Fix release validation and packaging with latest sources
Some checks failed
action.yml / Fix release validation and packaging with latest sources (push) Failing after 0s
Canary release / release (push) Failing after 21s

This commit is contained in:
Alois 2026-10-04 22:02:56 +02:00
commit 4ad0faf307
Signed by: alois
SSH key fingerprint: SHA256:GBzT2DXvAuGV9XIV5W3WrzVpjU54FThmxHXdbz95J24
5 changed files with 67 additions and 46 deletions

38
flake.lock generated
View file

@ -3,11 +3,11 @@
"client": { "client": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1791114583, "lastModified": 1791134823,
"narHash": "sha256-J4j6LI+erWFp+maryBRN08Ra90BKLjv0NOhVC7subEY=", "narHash": "sha256-KlEYoTKdP0yIHODuXGIaAPKlYV+7Z1Prd0r3r7R6wGI=",
"ref": "dev", "ref": "dev",
"rev": "d08a00a94acda0d1622de5960fa74750bf7d64db", "rev": "b5a7246ec7b92d21de22fc53339fd7f7db99edb7",
"revCount": 646, "revCount": 647,
"type": "git", "type": "git",
"url": "ssh://git@methanium.net/tensamin/client" "url": "ssh://git@methanium.net/tensamin/client"
}, },
@ -20,11 +20,11 @@
"iota": { "iota": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1791114268, "lastModified": 1791141275,
"narHash": "sha256-iKNN+La/hAKXxJL6wYti2jlZ4uS2C5dRkQyuVnciPwU=", "narHash": "sha256-jtoeOgev70umEJD2RhPJGpJD0A8X8sG/sWbdpwO5/kU=",
"ref": "main", "ref": "main",
"rev": "3d824fde58f1a9ff3c2df45311f7dc658e9700dd", "rev": "976ffde7a86b2f3f9884035b2a3a9ffb9aefe501",
"revCount": 327, "revCount": 329,
"type": "git", "type": "git",
"url": "ssh://git@methanium.net/tensamin/iota" "url": "ssh://git@methanium.net/tensamin/iota"
}, },
@ -70,11 +70,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1790981744, "lastModified": 1791011291,
"narHash": "sha256-sm6DclXJudZfP/pcDBQQsRqyMxBcQsuw+7yQr4rBBLE=", "narHash": "sha256-V6OBJccNKBo/ktknxlJXZChPoI0NE2lembArBO3CE9k=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "55ba7f49ef2962b42cbd126522b7df5f95037679", "rev": "73e728ddb6b7a12d18808f510813a13ee1fe4cce",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -87,11 +87,11 @@
"omega": { "omega": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1791114269, "lastModified": 1791141275,
"narHash": "sha256-56Nh5XnH7SK1P0kdtai/ZKcuQr8YlgDo5ndBf67YnFo=", "narHash": "sha256-Bo65XMYfSb/KFsp3fRVU+wVXrj4WrQGhyBRh51X24Uw=",
"ref": "main", "ref": "main",
"rev": "993fa5ead0cfe5f5f0ab1ecd12ffe0f343380489", "rev": "58bedd6a051ba281832c0d94e1de9a2313646341",
"revCount": 157, "revCount": 159,
"type": "git", "type": "git",
"url": "ssh://git@methanium.net/tensamin/omega" "url": "ssh://git@methanium.net/tensamin/omega"
}, },
@ -104,11 +104,11 @@
"omikron": { "omikron": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1791114268, "lastModified": 1791141275,
"narHash": "sha256-x6jc6l3LC3jTG/5YOuch32spGXfUzhO20M3g/Qmq2FY=", "narHash": "sha256-TKQebKvVTlHLEfAmoM+MtY5A2md5tUhx7lFXz2L5H8M=",
"ref": "main", "ref": "main",
"rev": "39371ad398d13aa1792c1ff58d2fb72f7be15787", "rev": "9d96c5a9b9052ba6f83082555af749aac1f6aeab",
"revCount": 211, "revCount": 213,
"type": "git", "type": "git",
"url": "ssh://git@methanium.net/tensamin/omikron" "url": "ssh://git@methanium.net/tensamin/omikron"
}, },

View file

@ -10,14 +10,15 @@ export TENSAMIN_CHANNEL=$channel ELECTRON_SKIP_BINARY_DOWNLOAD=1
export TENSAMIN_ANDROID_VERSION_CODE=${RELEASE_SEQUENCE:?Release sequence required} export TENSAMIN_ANDROID_VERSION_CODE=${RELEASE_SEQUENCE:?Release sequence required}
system=${3:-$(nix eval --impure --raw --expr 'builtins.currentSystem')} system=${3:-$(nix eval --impure --raw --expr 'builtins.currentSystem')}
expr="import $root/scripts/release-env.nix { root = builtins.toPath \"$root\"; kind = \"packages\"; channel = \"$channel\"; system = \"$system\"; }" expr="import $root/scripts/release-env.nix { root = builtins.toPath \"$root\"; kind = \"packages\"; channel = \"$channel\"; system = \"$system\"; }"
packages=$(nix build --impure --no-link --print-out-paths --expr "$expr")
nix build --impure --no-link --expr "import $root/scripts/release-env.nix { root = builtins.toPath \"$root\"; kind = \"checks\"; system = \"$system\"; }" nix build --impure --no-link --expr "import $root/scripts/release-env.nix { root = builtins.toPath \"$root\"; kind = \"checks\"; system = \"$system\"; }"
packages=$(nix build --impure --no-link --print-out-paths --expr "$expr")
arch=$system arch=$system
arch=${arch%-linux} arch=${arch%-linux}
printf '%s\n' "$packages" > "$out/packages-$arch.txt" printf '%s\n' "$packages" > "$out/packages-$arch.txt"
for name in iota iota-daemon iota-ui omikron omega client client-web mtp-sdk; do for name in iota iota-daemon iota-ui omikron omega client client-web mtp-sdk; do
# Nix closures, unlike a plain copy of a Nix binary, retain runtime libraries. # Nix closures, unlike a plain copy of a Nix binary, retain runtime libraries.
mapfile -t closure < <(nix-store --query --requisites "$packages/$name") package=$(realpath "$packages/$name")
mapfile -t closure < <(nix-store --query --requisites "$package")
nix-store --export "${closure[@]}" | gzip -n > "$out/$name-linux-$arch.nar.gz" nix-store --export "${closure[@]}" | gzip -n > "$out/$name-linux-$arch.nar.gz"
done done
for binary in iota iota-daemon iota-updater; do for binary in iota iota-daemon iota-updater; do
@ -30,6 +31,7 @@ cp -L "$packages/omega-container" "$out/omega-image-linux-$arch.tar.gz"
cp "$packages/iota-portable/bin/iota-release" "$out/iota-release-linux-$arch" cp "$packages/iota-portable/bin/iota-release" "$out/iota-release-linux-$arch"
cp "$packages/iota-portable/bin/iota-bundle" "$out/iota-bundle-linux-$arch" cp "$packages/iota-portable/bin/iota-bundle" "$out/iota-bundle-linux-$arch"
cp -rL "$packages/iota-bundle/share/iota" "$out/iota-contract" cp -rL "$packages/iota-bundle/share/iota" "$out/iota-contract"
chmod -R u+w "$out/iota-contract"
# The helpers' relative script paths are part of the Iota contract. # The helpers' relative script paths are part of the Iota contract.
mkdir -p "$out/iota-contract/iota-updater" "$out/iota-contract/iota-installer" mkdir -p "$out/iota-contract/iota-updater" "$out/iota-contract/iota-installer"
mv "$out/iota-contract/artifacts.tsv" "$out/iota-contract/iota-updater/" mv "$out/iota-contract/artifacts.tsv" "$out/iota-contract/iota-updater/"
@ -37,8 +39,13 @@ mv "$out/iota-contract/bundle-files.txt" "$out/iota-contract/iota-installer/"
mkdir -p "$out/iota-contract/static" mkdir -p "$out/iota-contract/static"
mv "$out/iota-contract/static-web" "$out/iota-contract/static/web" mv "$out/iota-contract/static-web" "$out/iota-contract/static/web"
work=$(mktemp -d) work_root=$(mktemp -d)
trap 'rm -rf "$work"' EXIT trap 'rm -rf "$work_root"' EXIT
work=$work_root/tensamin/client
mkdir -p "$work"
mtp_source=$(nix build --no-link --print-out-paths ".#packages.$system.mtp-source")
cp -r "$mtp_source" "$work_root/mtp"
chmod -R u+w "$work_root/mtp"
source=$(nix build --no-link --print-out-paths ".#packages.$system.client-source") source=$(nix build --no-link --print-out-paths ".#packages.$system.client-source")
cp -r "$source/." "$work/" cp -r "$source/." "$work/"
chmod -R u+w "$work" chmod -R u+w "$work"

View file

@ -7,7 +7,10 @@ case ${1:?} in
pnpm run ci pnpm run ci
electron_arch=x64 electron_arch=x64
[[ $RELEASE_ARCH != aarch64 ]] || electron_arch=arm64 [[ $RELEASE_ARCH != aarch64 ]] || electron_arch=arm64
package_name=tensamin
[[ $TENSAMIN_CHANNEL == stable ]] || package_name="tensamin-$TENSAMIN_CHANNEL"
pnpm --dir apps/electron exec electron-builder --config electron-builder.config.cjs \ pnpm --dir apps/electron exec electron-builder --config electron-builder.config.cjs \
--config.deb.packageName="$package_name" --config.rpm.packageName="$package_name" \
--linux --"$electron_arch" --publish never --linux --"$electron_arch" --publish never
pnpm run copy-releases pnpm run copy-releases
for asset in releases/*; do for asset in releases/*; do

View file

@ -1,17 +1,19 @@
{ root, kind ? "tools", channel ? "canary", system ? builtins.currentSystem }: { root, kind ? "tools", channel ? "canary", system ? builtins.currentSystem, sources ? {} }:
let let
central = builtins.getFlake (toString root); central = builtins.getFlake (toString root);
pkgs = import central.inputs.nixpkgs { pkgs = import central.inputs.nixpkgs {
inherit system; inherit system;
overlays = [ central.inputs.rust-overlay.overlays.default ]; overlays = [ central.inputs.rust-overlay.overlays.default ];
}; };
project = central.lib.mkPackages { inherit system; }; project = central.lib.mkPackages { inherit system sources; };
# Reuse only the client's tool shells, with central nixpkgs and Rust inputs. # Reuse only the client's tool shells, with central nixpkgs and Rust inputs.
# Client builds below always consume client-source and mtp-sdk from prod-pins. # Client builds below always consume client-source and mtp-sdk from prod-pins.
clientTools = (import (central.inputs.client + "/flake.nix")).outputs { clientTools = (import (central.inputs.client + "/flake.nix")).outputs {
self = central.inputs.client; self = central.inputs.client;
prod-pins = central // {
inputs = central.inputs // {
nixpkgs = central.inputs.nixpkgs // { nixpkgs = central.inputs.nixpkgs // {
# The client's old SDK platform-tools pin is absent in central nixpkgs. # Use the platform-tools version available in central nixpkgs.
outPath = pkgs.runCommand "release-client-nixpkgs" {} '' outPath = pkgs.runCommand "release-client-nixpkgs" {} ''
mkdir -p "$out" mkdir -p "$out"
cat > "$out/default.nix" <<'EOF' cat > "$out/default.nix" <<'EOF'
@ -24,13 +26,15 @@ let
EOF EOF
''; '';
}; };
rust-overlay = central.inputs.rust-overlay; };
};
}; };
branded = name: project.packages.${name}.overrideAttrs { branded = name: project.packages.${name}.overrideAttrs {
TENSAMIN_CHANNEL = channel; TENSAMIN_CHANNEL = channel;
}; };
checked = name: project.packages.${name}.overrideAttrs (old: { checked = name: project.packages.${name}.overrideAttrs (old: {
doCheck = true; doCheck = true;
SSL_CERT_FILE = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
installPhase = ''mkdir -p "$out"''; installPhase = ''mkdir -p "$out"'';
nativeBuildInputs = old.nativeBuildInputs ++ project.devShells.${name}.nativeBuildInputs; nativeBuildInputs = old.nativeBuildInputs ++ project.devShells.${name}.nativeBuildInputs;
preBuild = (old.preBuild or "") + '' preBuild = (old.preBuild or "") + ''
@ -43,20 +47,27 @@ let
pname = "mtp-checks"; pname = "mtp-checks";
src = project.packages.mtp-sdk.src; src = project.packages.mtp-sdk.src;
cargoDeps = project.packages.mtp-vendor; cargoDeps = project.packages.mtp-vendor;
cargoBuildFlags = [ "--workspace" ]; cargoBuildFlags = [ "--workspace" "--exclude" "mtp-wasm" ];
cargoTestFlags = [ "--workspace" ]; cargoTestFlags = [ "--workspace" "--exclude" "mtp-wasm" ];
doCheck = true; doCheck = true;
MTP_TYPE_MAPS = "${project.packages.mtp-sdk.src}/tests/fixtures/example/type-maps.yaml";
installPhase = ''mkdir -p "$out"''; installPhase = ''mkdir -p "$out"'';
nativeBuildInputs = old.nativeBuildInputs ++ project.devShells.mtp.nativeBuildInputs; nativeBuildInputs = old.nativeBuildInputs ++ project.devShells.mtp.nativeBuildInputs;
preBuild = '' preBuild = ''
cargo fmt --all --check cargo fmt --all --check
cargo clippy --locked --offline --workspace --all-targets -- -D warnings cargo clippy --locked --offline --workspace --exclude mtp-wasm --all-targets -- -D warnings
''; '';
}); });
in in
if kind == "tools" then pkgs.mkShell { if kind == "tools" then pkgs.mkShell {
packages = with pkgs; [ nix git (python3.withPackages (p: [ p.pyyaml ])) bash coreutils jq zip gnutar gzip openssh skopeo shellcheck ruff ]; packages = with pkgs; [ nix git (python3.withPackages (p: [ p.pyyaml ])) bash coreutils jq zip gnutar gzip openssh skopeo shellcheck ruff ];
} else if kind == "electron" || kind == "tauri" then clientTools.devShells.${system}.${kind} } else if kind == "electron" || kind == "tauri" then
clientTools.devShells.${system}.${kind}.overrideAttrs (old: {
shellHook = builtins.replaceStrings
[ ''cd "$workRoot/tensamin/client"'' ]
[ ''cd "''${RELEASE_WORK:-$workRoot/tensamin/client}"'' ]
old.shellHook;
})
else if kind == "checks" then pkgs.linkFarm "release-checks" (map (name: { else if kind == "checks" then pkgs.linkFarm "release-checks" (map (name: {
inherit name; inherit name;
path = checked name; path = checked name;

View file

@ -1,15 +1,15 @@
"""Refresh the shared sources, transformed locks, and fixed-output hashes.""" """Refresh the shared sources, transformed locks, and fixed-output hashes."""
import argparse import argparse
from pathlib import Path
import re import re
import shutil import shutil
import subprocess import subprocess
import tempfile import tempfile
from pathlib import Path
def run(*args, **kwargs): def run(*args, **kwargs):
result = subprocess.run(args, text=True, **kwargs) result = subprocess.run(args, text=True, check=False, **kwargs)
if result.returncode: if result.returncode:
raise SystemExit(result.stderr if kwargs.get("capture_output") else result.returncode) raise SystemExit(result.stderr if kwargs.get("capture_output") else result.returncode)
return result return result
@ -60,7 +60,7 @@ for key, output in [(n, f"{n}-vendor") for n in ["mtp", "iota", "omikron", "omeg
text = re.sub(rf'({key} = ")[^"]+', rf'\g<1>sha256-{"A" * 43}=', text) text = re.sub(rf'({key} = ")[^"]+', rf'\g<1>sha256-{"A" * 43}=', text)
hash_file.write_text(text) hash_file.write_text(text)
result = subprocess.run(["nix", "build", f"path:{root}#packages.{system}.{output}", result = subprocess.run(["nix", "build", f"path:{root}#packages.{system}.{output}",
"--no-link", "--print-out-paths", *overrides], text=True, capture_output=True) "--no-link", "--print-out-paths", *overrides], text=True, capture_output=True, check=False)
match = re.search(r"got:\s+(sha256-[A-Za-z0-9+/=]+)", result.stderr) match = re.search(r"got:\s+(sha256-[A-Za-z0-9+/=]+)", result.stderr)
if not match: if not match:
hash_file.write_text(original) hash_file.write_text(original)