Iterion Desktop — Distribution
Release flow
Pushing a v* tag triggers two GitHub Actions workflows in parallel:
release.yml(existing) — builds the CLI binaries for 6 platforms and attaches them to the GitHub Release.desktop-release.yml(new) — builds the desktop binaries for the same 6 platforms, signs each artefact, generates the manifest, and attaches everything to the same GitHub Release.
The two workflows do not collide because every desktop artefact is prefixed iterion-desktop-*.
Artefacts produced per release
iterion-desktop-darwin-universal.zip # Iterion.app/, universal amd64+arm64, ditto-compressed
iterion-desktop-darwin-universal.zip.sig
iterion-desktop-windows-amd64.exe # portable
iterion-desktop-windows-amd64.exe.sig
iterion-desktop-windows-amd64-installer.exe
iterion-desktop-windows-amd64-installer.exe.sig
iterion-desktop-windows-arm64.exe
iterion-desktop-windows-arm64.exe.sig
iterion-desktop-windows-arm64-installer.exe
iterion-desktop-windows-arm64-installer.exe.sig
iterion-desktop-linux-amd64.AppImage
iterion-desktop-linux-amd64.AppImage.sig
iterion-desktop-linux-amd64.tar.gz # raw binary + desktop file/icon
iterion-desktop-linux-amd64.tar.gz.sig
iterion-desktop-linux-amd64.deb # Debian/Ubuntu package with desktop + CLI
iterion-desktop-linux-amd64.deb.sig
iterion-desktop-linux-arm64.AppImage
iterion-desktop-linux-arm64.AppImage.sig
iterion-desktop-linux-arm64.tar.gz # raw binary + desktop file/icon
iterion-desktop-linux-arm64.tar.gz.sig
iterion-desktop-linux-arm64.deb # Debian/Ubuntu package with desktop + CLI
iterion-desktop-linux-arm64.deb.sig
iterion-desktop-manifest.json
iterion-desktop-manifest.json.sigAuto-update flow
- Running desktop polls
releases/latest/download/iterion-desktop-manifest.jsonon startup (and every 4h thereafter, while the user has auto-check on). - Downloads
iterion-desktop-manifest.json.sigand verifies it against the embeddedupdaterPublicKeyHex. - Selects the artefact for
GOOS/GOARCH, downloads it. - Verifies the artefact's
sha256anded25519against the manifest. - Atomic-swaps the binary on disk (per-OS strategies in
updater_apply_*.go). - Emits a
update:appliedevent so the SPA can prompt for restart.
The user can also trigger updates manually via Settings → Updates → "Check now".
Signing setup
One-time: generate keypair
bash
./scripts/desktop/ed25519-keygen.shOutputs hex to stdout, stores PEM in ~/.iterion-keys/updater_ed25519.pem.
One-time: configure CI
- Paste the contents of
~/.iterion-keys/updater_ed25519.peminto a GitHub repository secret namedUPDATER_ED25519_PRIVATE. - Paste the public-key hex (the script's stdout) into
cmd/iterion-desktop/updater.go'supdaterPublicKeyHexconstant and commit. - Verify: build a binary, run
./scripts/desktop/verify-release.shon its.sigagainst the same hex. Should printSignature Verified Successfully.
Rollback
If a desktop release contains a critical bug:
- Download the previous
iterion-desktop-manifest.jsonfrom the prior tag and re-upload it as the latest tag's manifest. This stops auto-update from offering the bad version. - Optionally, untag the bad release on GitHub (or mark it as draft) so the static
releases/latest/...URL falls through to the previous one. - The CLI release remains independent —
release.ymlartefacts are not affected.
Future: code-signing
V1 ships unsigned. When code-signing is added:
- macOS: developer certificate + notarisation via
xcrun notarytool. Hook point indesktop-release.ymlis gated onsecrets.MACOS_DEVELOPER_ID_CERT_BASE64. - Windows: code-signing certificate via
signtool. Hook point gated onsecrets.WINDOWS_CERT_BASE64.
Adding either does NOT replace the Ed25519 manifest signature — both exist independently. The Ed25519 layer is the trust anchor for our update channel; OS signing is only a UX improvement (Gatekeeper / SmartScreen).
