Skip to content

Promote recorded Linux candidates with resumable asset uploads - #423

Merged
zeth merged 1 commit into
mainfrom
feat/promote-recorded-linux
Nov 9, 2026
Merged

zeth merged 1 commit into
mainfrom
feat/promote-recorded-linux

Conversation

@zeth

@zeth zeth commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

Linux promotion currently downloads signed artifacts by name/run and uses --clobber, so retrying can replace existing assets and a draft can be created without first verifying the candidate tag. Add release.py promote-linux --record ... --wait to deliver the recorded signed bytes to the exact release and retain independently verified destination evidence.

The coordinated path requires the existing holder-v<version> tag at the accepted candidate SHA and dispatches the existing promotion workflow on main with signed artifact ID/ZIP checksum, signing run and source SHA. Both jobs verify the pinned bundle. Existing signature verification, signed-image smoke checks, attestation verification and non-executing payload reverification remain in place. No build or signing is repeated.

Replace unconditional asset replacement with a tested promotion helper: create/reuse the draft at an existing tag, inspect all existing Linux assets before writing, retain matching names/sizes/hashes, and upload only missing files without --clobber. Paginate release/asset lists and verify legacy assets without API digests by downloading their bytes. Check current tag/release state before each write. Preserve existing notes, titles and other-platform assets. A complete published stable release is verifiable without mutation; incomplete/conflicting published stable assets cannot be modified. The existing published-prerelease opt-in permits missing uploads but never replacement.

Intentional mutable drafts retain a separate explicit manual route: replace_draft_assets=true permits replacing conflicts only while the release is still a draft and cannot be combined with pinned workflow inputs. The coordinator always disables both replacement and published-prerelease modification. All paths now require the release tag to exist, avoiding implicit tag creation and its Launchpad side effects.

The workflow retains a promotion receipt. Independently, the coordinator checks destination release/asset IDs and hashes, records the signed source relationship and refreshes draft/prerelease state. It reconciles interrupted dispatches, supports failed-job retries for partial uploads, and recognizes complete matching manual/published delivery without another run, even after source artifacts expire. A later cleanup failure remains visible while the completed destination can still be accepted. Accepted asset-ID/hash drift stops re-observation. The runbook and new Linux promotion guide document inputs, receipts, explicit replacement and recovery limits.

Validation: 122 release tests and 41 staging tests pass. New coverage includes draft creation/repeat, partial upload/lost response, conflicts and explicit draft replacement, published stable/prerelease policy, release publication races, annotated/missing/wrong tags, pagination/duplicates, legacy digest fallback, coordinator restart/retry/expiry, independent completion after workflow failure, accepted destination drift, and exact signed-source downloads. Boundary, root version, workflow YAML and diff checks pass. A live read-only check inspected published 0.2.5's tag/release and four Linux asset identities through the new reader. No real promotion/signing/build dispatches, draft/tag creation, asset uploads or replacement were performed.

Continues #120 and #122. Core SDK publication and the remaining platform/PPA/website completion handoffs remain subsequent work; exercise the full remote promotion path through the next actual release.

@zeth
zeth merged commit 7c763cf into main Nov 9, 2026
59 checks passed
@zeth
zeth deleted the feat/promote-recorded-linux branch November 9, 2026 14:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant