iota/scripts/releases.md
Alois e71d9c3118
Some checks failed
Validate authentication / Validate authentication (push) Failing after 1s
Move builds to prod-pins and add explicit update channels
2026-10-04 19:27:02 +02:00

84 lines
4.1 KiB
Markdown

# Unmanaged signed releases
Publishing belongs to prod-pins. Iota only builds and verifies release inputs.
## Operator commands
Run as root for the unmanaged system installation:
```sh
iota update channel stable
iota update channel canary
iota update check
iota update apply
```
`iota update channel` shows the selected channel. Selection atomically persists
`/etc/iota/update.env` without fetching or applying a release. The standalone
`iota-updater` supports the same commands. Check and apply read this file directly,
including the pinned public key and key ID. Process environment cannot replace
the trust configuration. Channel selection preserves both trust values and all
per-channel anti-replay state.
The manifest URL is
`https://git.methanium.net/tensamin/prod-pins/releases/download/CHANNEL/iota-update-linux-ARCH.json`.
The signature URL appends `.sig`. CHANNEL is `stable` or `canary`, ARCH is
`x86_64` or `aarch64`. Apply can select a previously accepted target when the
active release belongs to the other channel. It still rejects older sequences,
sequence/version reuse and failed activation sequences. Same-channel explicit
rollback remains respected.
The initial ZIP installer remains supported. It preserves existing update.env
and removes a previously provisioned unattended update timer. The update service
is an explicit oneshot apply operation with no timer.
## Release script contracts
```sh
bash scripts/build-update-manifest.sh BINARY_DIRECTORY BASE_VERSION CHANNEL RELEASE_SEQUENCE PUBLISHED_AT EXPIRES_AT linux ARCH BASE_URL OUTPUT.json
iota-release sign OUTPUT.json OUTPUT.json.sig
bash scripts/build-release-bundle.sh BINARY_DIRECTORY PRODUCT_VERSION OUTPUT.json MANIFEST_URL PUBLIC_KEY SIGNATURE_URL CHANNEL SIGNING_KEY_ID OUTPUT.zip
iota-bundle OUTPUT.zip
```
The binary directory contains `iota`, `iota-daemon` and `iota-updater`.
The manifest script emits PRODUCT_VERSION as `BASE_VERSION-CHANNEL-FULL_SOURCE_SHA`.
Read `.product_version` from the generated manifest for the bundle command.
Use an immutable release BASE_URL in prod-pins. Upload the binaries there as
`iota-linux-ARCH`, `iota-daemon-linux-ARCH` and `iota-updater-linux-ARCH`.
The signed artifact paths remain `bin/iota`, `bin/iota-daemon` and
`bin/iota-updater`, with SHA-256 hashes and byte lengths.
Publish the manifest and signature under each mutable `stable` or `canary`
release as `iota-update-linux-ARCH.json` and `iota-update-linux-ARCH.json.sig`.
Sequences must increase per channel. Serialize publication per channel and
reject a lower sequence or reuse with a different product version. Keep
immutable binary assets available for already published manifests.
## Signature and workflow inputs
`IOTA_RELEASE_SIGNING_KEY` is a secret containing a 32-byte Ed25519 seed as
64 hexadecimal characters. `iota-release sign` prints the derived 32-byte
public key as hex. Compare it with the expected pinned public key before
publishing or building installer trust configuration.
The detached signature is 64 Ed25519 bytes encoded as 128 hexadecimal
characters. It signs `serde_json::to_vec` of the typed `ReleaseManifest`, in
the Rust declaration field order, with nested artifacts in their declaration
field order. It does not sign the pretty-printed JSON file bytes. Use the Rust
signer rather than a generic JSON canonicalizer.
The prod-pins workflow needs:
- `IOTA_RELEASE_SIGNING_KEY`, secret signing seed.
- `IOTA_RELEASE_SOURCE_SHA`, full 40-character Iota source commit SHA. Defaults
to the local repository HEAD, so set it explicitly when building elsewhere.
- `IOTA_RELEASE_SIGNING_KEY_ID`, defaults to `primary`.
- Expected pinned public key, supplied as the bundle PUBLIC_KEY argument.
- Base product version, channel, positive release sequence, RFC 3339 publication
and expiry timestamps, architecture and immutable artifact BASE_URL.
- A Forgejo API token with release upload access to `tensamin/prod-pins`.
Build the Rust release binaries plus `iota-release` and `iota-bundle`. Shell
scripts require bash, git, coreutils, jq and zip. No Iota publishing workflow
remains; verification runs in `.forgejo/workflows/validate.yml`.