fix(build-and-sign-image): only tag releases on a release event - #29
Draft
kdaula wants to merge 2 commits into
Draft
fix(build-and-sign-image): only tag releases on a release event#29kdaula wants to merge 2 commits into
kdaula wants to merge 2 commits into
Conversation
The version tag block runs `git describe --exact-match --tags` against whatever commit is checked out, with no reference to how the run was triggered. Any non-release run that lands on an already-tagged commit - a push or nightly on a release branch sitting at its tag, or a manual rebuild of a released commit - therefore republishes vX.Y.Z, stable and latest onto a freshly built digest. Docker builds are not bit-for-bit reproducible, so the released tag silently moves off the artifact that was actually released, and anyone pulling the version tag gets the rebuild. The `event` input already existed for this and was passed by callers, but was never read anywhere in the action. Read it: version tags are applied only when the event is `release`, and every other event publishes the short-sha tag alone. This drops the workflow_dispatch "rebuild from a tag" behaviour added in edera-dev/protect#1248 - that path is the drift. If it is wanted back it should be an explicit opt-in input rather than implicit by describe. Refs edera-dev/protect#3692
kdaula
requested review from
alexandermerritt,
azenla,
bleggett,
kaniini and
tycho
as code owners
September 6, 2026 15:37
kdaula
marked this pull request as draft
September 6, 2026 15:46
The gate added in the first commit only covered the `git describe` block. The `type=semver` lines feeding docker/metadata-action were still live: procSemver gates on github.ref matching refs/tags/, not on event name (src/meta.ts:156 at the pinned dc80280), and `latest` rides along via the default flavor.latest=auto. A run dispatched from a tag ref - `gh workflow run release-artifacts.yml --ref v1.12.0` - therefore still moved vX.Y.Z, X.Y, X, stable and latest onto the rebuild. Gate them per-tag with the `enable` attribute. Nothing exercised the step being changed: selftest.yml loads three actions and build-and-sign-image is not one of them, so a template error here would ship straight to protect's release workflow. Move the tag computation into capture-version-tags.sh and cover it from selftest with a fabricated event, the same move protect made in edera-dev/protect#3692. The test fails if the gate is removed. The script is invoked as `bash <path>` rather than executed directly, so it does not depend on the file mode surviving. Refs edera-dev/protect#3692
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.
Problem
Two independent paths republish release tags onto a rebuild. Docker builds aren't bit-for-bit reproducible, so either one leaves
vX.Y.Zpointing at an artifact that was never released.git describe --exact-match --tagsruns against whatever commit is checked out, with no reference to what triggered the run. Any non-release run landing on an already-tagged commit re-emitsvX.Y.Z,X.Y,X,stable,latest.type=semverlines feedingdocker/metadata-action.procSemvergates ongithub.refmatchingrefs/tags/, not on event name (src/meta.ts:156at the pinneddc80280), andlatestrides along via the defaultflavor.latest=auto. Sogh workflow run release-artifacts.yml --ref v1.12.0moves all six tags — same drift, one trigger over.This is what drifted
v1.12.0:release/1.12sat at its tag and the workflow was re-run on that commit.Fix
eventinput — declared required, passed by callers, read by nothing. Now it's read.capture-version-tags.sh.enableattribute (enable=placed afterpattern=so the handlebars}}doesn't terminate the GitHub expression early).Testability
selftest.ymlloads three actions and this isn't one of them — it needs registry credentials and a real build — so nothing here caught a template error before it reached protect's release workflow.build-and-sign-image/capture-version-tags.sh..github/tests/capture-version-tags.test.shruns it against a fabricated repo forrelease,push,schedule,workflow_dispatchand empty. Verified it goes red if the gate is removed.bash <path>, so it doesn't depend on the file mode surviving.Heads up: behavior change
Removes the
workflow_dispatch"rebuild from a tag" path (edera-dev/protect#1248). That path is the drift — a rebuild can't reproduce the original digest, so re-tagging it as the release was never safe. If we want it back it should be an explicit opt-in input.Test plan
bash .github/tests/capture-version-tags.test.sh— 19 checks passshellcheckclean, YAML parsesSeparate issue, spotted in passing
Cosign sign all imagesis gatedif: '${{ inputs.push == true }}'—inputs.pushis the string'true', and GitHub casts across types to a number, so'true'→ NaN and the condition is always false. Every other push-gated step in this file uses== 'true'. Came in with0d91715(#5).If that reading holds, released images carry SBOM attestations but no signature, and
cosign verifyfails on all of them. I could not confirm against the registry — noread:packageson my token, no cosign/crane here. Not touching it in this PR since it's unrelated to tag drift; worth a two-minute check by someone who can pull.Refs edera-dev/protect#3692, PRT-553