Skip to content

Publish an immutable build tag alongside the mutable one - #21

Open
dionmcm wants to merge 1 commit into
groups-api-fixfrom
publish-build-tag
Open

Publish an immutable build tag alongside the mutable one#21
dionmcm wants to merge 1 commit into
groups-api-fixfrom
publish-build-tag

Conversation

@dionmcm

@dionmcm dionmcm commented Aug 18, 2026

Copy link
Copy Markdown
Member

Problem

The image build publishes exactly one tag — latest on groups-api-fix, the branch name elsewhere — and both are mutable. The digest we actually deploy therefore has no durable name of its own.

That caused two distinct problems on 2026-08-18:

  • Build 15968 was the image deployed to production. Its digest carried no tag at all until one was imported by hand, leaving the manifest production is pinned to eligible for garbage collection.
  • Build 15969 rebuilt the same commit (a19843d9), produced a different digest, and took ownership of latest. From that point the registry could not answer which image production was running.

Change

One script step after the Maven build. The image is already on the agent and Docker is already logged in, so it is just a tag-and-push, plus a read-back.

  • Named after the build, not the commit: 15968 and 15969 both built a19843d9 and produced different digests, so a commit-SHA tag would be silently overwritten by a rebuild.
  • Not named after $(Build.BuildNumber) either: tags beginning rvf- (the build-number prefix) were observed failing to be created in this registry while the command reported success.
  • The read-back exists because a publish reporting success without creating anything is the precise failure this step engineers around. RepoDigests is populated only once the registry has accepted the manifest.

What this does not change

values.yaml still pins by digest. A tag is a mutable pointer someone can move; the digest is the guarantee. The build tag exists so the manifest is permanent and findable, not so it can be pinned.

Testing

YAML parses; the build job goes from 4 steps to 5. The first real exercise is the merge itself, which triggers an image build — a red build there is the correct failure mode, and better found now than on the day a rollback target is needed.

Builds 15968 and 15969 keep their hand-applied tags (production-20260818, latest); everything from this merge forward is automatic.

🤖 Generated with Claude Code

https://claude.ai/code/session_018aYBXcyiozxQQGhzzhS7KG

The image build publishes exactly one tag - `latest` on groups-api-fix,
the branch name elsewhere - and both are mutable. So the digest we deploy
has no durable name of its own, which caused two distinct problems on
2026-08-18:

  * Build 15968 was the image deployed to production. Its digest carried
    no tag at all until one was imported by hand, leaving the manifest
    production is pinned to eligible for garbage collection.

  * Build 15969 rebuilt the same commit (a19843d), produced a different
    digest, and took ownership of `latest`. From that point the registry
    could not answer which image production was running.

Add a `build-<BuildId>` tag that is never reused, and verify it landed
rather than trusting the exit status - the manual repair used for 15968
returned success without creating the tag.

This does not change what the chart pins. `values.yaml` still carries the
digest, because a tag is a mutable pointer someone can move. The build
tag exists so the manifest is permanent and findable, not so it can be
pinned.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018aYBXcyiozxQQGhzzhS7KG
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