Label images with the build.gradle version and stop older patches moving :latest - #692
Merged
Merged
Conversation
coopernetes
marked this pull request as draft
September 24, 2026 04:25
…ing :latest Every stable tag moved :X.Y, :X and :latest to its image, so a 1.4.x patch cut after 1.5.0 would have pointed :latest and :1 back at 1.4.x. Images also carried org.opencontainers.image.version=build-<sha>, so a released image never reported its own version. docker-publish now sets org.opencontainers.image.version from the build.gradle version (X.Y.Z on a release commit, X.Y.Z-SNAPSHOT otherwise). Tag-triggered promotion moves to release-publish.yml, where scripts/release_image_tags.py refuses an image whose label is not the tag's version, and moves each convenience tag only when the release is at least as new as the version labelled on the image it points at now. A tag rolled back by hand stays put until something newer ships; tags on images without a semver label move. Pre-releases still get their exact version only. Promotions are serialised so two releases cannot interleave their read-then-write, and cleanup-interim-images now shares that group (its old group matched no running workflow). The scripts' unit tests move from the workflows that run them into CI's Build & Test job, a required check for merges and release tags, so a broken script fails before a tag is pushed rather than after. README and CONTRIBUTING describe the current tags and release flow. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
coopernetes
force-pushed
the
ci/release-tag-publish
branch
from
October 3, 2026 04:22
57fb413 to
89f60ea
Compare
coopernetes
marked this pull request as ready for review
October 3, 2026 04:39
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every stable release tag moved
:X.Y,:Xand:latest, so a 1.4.x patch cut after 1.5.0 would have pointed:latestand:1back at 1.4.x. Images were also labelledorg.opencontainers.image.version=build-<sha>, so a released image never reported its own version.docker-publishsetsorg.opencontainers.image.versionfrombuild.gradle(X.Y.Zon a release commit,X.Y.Z-SNAPSHOTotherwise).release-publish.yml.scripts/release_image_tags.pyrefuses an image whose label is not the tag's version, and moves each convenience tag only when the release is at least as new as the version on the image it points at now. A hand rollback stays put until something newer ships; tags on unlabelled (pre-change) images move.cleanup-interim-imagesshares that concurrency group (its old group matched no running workflow).Build & Test(required for merges and tags) instead of inside the workflows that use them.Worth a look: this PR's image build should carry
org.opencontainers.image.version=1.5.0-SNAPSHOT, confirmingmetadata-action'slabels:input overrides its generated value. Re-running the release workflow for v1.4.3 or earlier now fails the label check by design;retag.ymlremains the manual path.release/1.4.xneeds this cherry-picked before its next release commit, since tag runs use the workflows at the tagged commit.Test plan (personal fork)
Run in
coopernetes/fogwallwith exact copies of theRelease gatetag ruleset (same 12 required checks, no bypass) and theProtect release branchesruleset. Forkmain=upstream/main+ this commit; forkrelease/9.1.x=upstream/release/1.4.x+ this commit cherry-picked. Dummy9.xversions; every step checked on both images by version label and digest.ghcr.io/rbc/fogwall{,-server}:1.4.3copied in as:9.1.0,:9.1,:9,:latest(legacybuild-9244818label, same digests as upstream).org.opencontainers.image.versionfrombuild.gradle(9.1.0-SNAPSHOT,9.2.0,9.1.2-SNAPSHOT, …), sometadata-action'slabels:override works.v9.1.0pushed while checks were running → rejected, "12 of 12 required status checks have not succeeded".v9.2.0frommain→ moves9.2.0 9.2 9 latest, replacing the legacy-labelled9andlatest;9.1untouched.v9.1.1fromrelease/9.1.xafter 9.2.0 → moves9.1.1 9.1only;9andlatestkeep the 9.2.0 digest.v9.1.9on the 9.1.1 commit → refused on both images (labelled '9.1.1', not '9.1.9'); nothing written.v9.1.2on a9.1.2-SNAPSHOTcommit → refused (labelled '9.1.2-SNAPSHOT', not '9.1.2'); nothing written.v9.3.0-rc.1→ moves9.3.0-rc.1only; no9.3;9andlatestunchanged.v9.2.0publish → same tags, same digests.retag.ymlpoints9andlatestat 9.1.1, thenv9.1.2→ moves9.1.2 9.1 9 latest.v9.1.3andv9.3.0in onegit push→v9.3.0published first andv9.1.3waited for it;v9.1.3then moved9.1.3 9.1only.latestand9end at 9.3.0,9.3created,9.1at 9.1.3.release/9.*branches,v9.*tags and fork packages; reset forkmain.Backporting to
release/1.4.x:cleanup-interim-images.yml(that branch still has the bash cleanup script). Keep the branch's version; scheduled workflows only run from the default branch.🤖 Generated with Claude Code