Tag every published per-arch image with an immutable per-release snapshot - #41
Conversation
|
Tested and confirmed end-to-end against the experimental fork: the publish flow and the backfill workflow both produced the immutable per-arch snapshot tags as expected. |
There was a problem hiding this comment.
Pull request overview
Adds immutable, per-release architecture tags to preserve SEP-58 image digests, plus tooling to backfill historical releases.
Changes:
- Introduces uniform release iteration tags beginning at
-0. - Publishes per-architecture snapshot tags and documents them.
- Adds a provenance-based backfill workflow and tests.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
.github/workflows/backfill.yml |
Adds manual backfill workflow. |
.github/workflows/publish.yml |
Propagates iteration into publishing. |
RELEASE.md |
Documents snapshots and backfilling. |
docker/README.md |
Documents mutable and immutable tags. |
scripts/backfill_iteration_tags.py |
Reconstructs historical snapshot tags. |
scripts/lib/gh_cli.py |
Adds branch, file, and asset helpers. |
scripts/publish_aliases.py |
Clarifies moving-alias behavior. |
scripts/publish_manifests.py |
Creates per-architecture snapshot tags. |
scripts/release_body.py |
Lists snapshots in release bodies. |
scripts/release_pr_body.py |
Handles iteration-zero releases. |
scripts/release_prepare.py |
Selects iteration tags using releases and branches. |
tests/integration/test_release_prepare.py |
Tests iteration selection. |
tests/unit/test_backfill_iteration_tags.py |
Tests backfill behavior. |
tests/unit/test_publish_aliases.py |
Verifies aliases exclude snapshots. |
tests/unit/test_publish_manifests.py |
Tests snapshot publication. |
tests/unit/test_release_body.py |
Tests snapshot release documentation. |
tests/unit/test_release_pr_body.py |
Tests iteration-zero PR content. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
694f928 to
e839478
Compare
e839478 to
31092ee
Compare
leighmcculloch
left a comment
There was a problem hiding this comment.
Couple comments, otherwise lgtm.
| def list_release_branch_tags(repo: str) -> list[str]: | ||
| """Release tags of the `release/<tag>` branches that exist on the repo. | ||
|
|
||
| A release branch is created at prepare time and persists across the |
There was a problem hiding this comment.
I believe we use 'delete branch on merge' on most repos, and so GitHub will auto delete the release branch, is that an issue?
| cli = args.stellar_cli_version | ||
| registry = args.registry | ||
|
|
||
| iteration = latest_iteration(gh_cli.list_release_tags(args.repo), cli) |
There was a problem hiding this comment.
If v25.2.0 and v25.2.0-1 both exist as GitHub Releases, but v25.2.0-1's publish run fails before the build/push step, will backfill work as expected? Or will a next run get stuck?
| Moving aliases (`:<cli>`, `:latest`) re-point each release. | ||
| Moving aliases (`:<cli>`, `:latest`) re-point each release. The immutable `:<cli>-rust<key>-<arch>-<N>` snapshots are the exception — they're keyed by the release's refresh index, so a re-run recreates the same tags at the same digests rather than moving them. | ||
|
|
||
| To recover from a failed run, use **Re-run failed jobs** from the GitHub Actions UI; re-runs simply rebuild and overwrite. Recovering from a corrupt push is the same — just re-run, no manual tag deletion needed. |
There was a problem hiding this comment.
I think some of the text here needs updating. Are the statements about rerunning still correct? Won't that result in new releases now? Could it get stuck trying to republish an existing?
| # auto-picked by the release workflow. Strip leading "v" and the | ||
| # trailing "-<N>" to derive the stellar-cli version; the refresh | ||
| # index N (0 when there's no suffix, i.e. the first release) names | ||
| # the immutable :<version>-<N> Docker tag published by the aliases |
There was a problem hiding this comment.
Is :<version>-<N> still exist, or the tag is :<cli>-rust<key>-<arch>-<N> now?
Fixes #38.
What
Adds an immutable per-release snapshot tag for every published per-arch image:
:‹cli›-rust‹key›-‹arch›-‹N›(e.g.27.0.0-rust1.95.0-slim-trixie-amd64-0), minted by the publish workflow for each(rust base, arch)a release builds. Also adds a manually-dispatchedbackfillworkflow to reconstruct these tags for already-published releases, recovering each per-arch digest from the release'sprov-*.intoto.jsonlattestation assets.Why
SEP-58 verifiable builds pin per-arch content digests (
bldimg) into deployed contracts permanently. Today those digests are only reachable through mutable tags (:‹cli›-rust‹key›-‹arch›,:‹cli›,:latest), which re-point on the next publish — orphaning the old digest and making it garbage-collectable. The immutable per-arch tags keep every published digest referenced by a tag that never moves, so none can be garbage-collected. Coverage is per-arch across every rust pair a release built, not just the default one (e.g. v27.0.0 shipped four rust pairs).