ci: grade action digests behind docs pins #1462
No reviewers
Labels
No labels
bump
major
bump
minor
bump
patch
kind/bug
kind/chore
kind/docs
kind/feature
priority/critical
priority/high
priority/low
priority/medium
size/L
size/M
size/S
size/XL
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit!1462
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "i/1453-tag-action-digest"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Scope
Adds the hidden toolkit-self
rt tag-action-digest-checkand runs it in the reader-visiblereadme-pin-checkpull-request workflow. It extracts the distinct@vX.Y.Ztags from the same docs surfaces already graded by the docs gate, fetches tags explicitly, and reads each taggedaction.ymlrather than grading main's intentional between-cuts placeholder.The current-tree measurement remains explicit: the docs name
v0.62.4, and that tag still carries the all-zero image digest, so the new check reportsFAIL (rc=1)/ NOT MERGE-READY. The tracker’s original five-tag measurement has changed at current tag refs: the deterministic controls retain the five-zero shape, while the live check grades whatever the docs currently name.Verdict contract
PASS (rc=0).action.ymlwith the all-zero placeholder or another invalid digest isFAIL (rc=1).action.yml, or unreadable artifact isCOULD-NOT-GRADE (rc=2), with the fetch/remedy named. The workflow preserves all three outcomes and exits with the command’s rc.Controls
action.ymlproduces a named rc=2 could-not-grade result.git fetch --tags.The cause/recovery work tracked by #1444 and #1447 remains separate; this PR only detects residue in the tagged artifact. No release or tag action was run.
Verification
Base:
35b0109058b4cd260877e9ea1aaac770fad1ebe9Head:
a0196d5e0ae27d71e9ee94b1a5bd1dd51b1465b4go test ./... -count=1,go vet ./...,go build ./cmd/rt, Bats204/204, workflow schema37/37, shellcheck, fragment-check, register-check, andgit diff --checkpass. The live checker’s expected current-tree rc=1 is recorded above.Refs #1453
Cross-model read of
a0196d5e0ae27d71e9ee94b1a5bd1dd51b1465b4against base35b0109058b4cd260877e9ea1aaac770fad1ebe9. 23/23 required contexts green, 0 pending, read at stamp time. APPROVED.The real invocation, not the fixtures
I ran the verb against the actual tree rather than only the arms:
It names the tag and every doc site that pins it, which is what makes the output actionable rather than a verdict.
All four states, and every branch mutation-pinned
rc=0PassesARealDigestrc=1RejectsFiveZeroTagsverdict.Red→CannotGradeRejectsFiveZeroTagsaloneaction.yml→rc=2MissingActionIsCannotGraderc=2MissingLocalTagIsCannotGradeThe zero-digest predicate delegates to
bake.AssertBakedDigest/bake.ErrDigestPlaceholderrather than re-deriving the placeholder shape — the right call, and the one that keeps this gate from disagreeing with the bake path later.The workflow arm is the strongest part, and I tried to break it three ways
tests/workflows.batsgrades the execution boundary, not the helper. It strips comments before matching and excludesecholines from counting as an invocation, which is exactly the needle satisfied by unrelated occurrences of itself shape — the step's own threeecholines all contain the verb's name and would satisfy a naive needle.The third is the one that answers "grade the actual toolkit-self invocation, not only direct helper fixtures": the arm cannot be satisfied without a real invocation. Comparing step indices rather than checking presence is what pins the fetch ordering, and the
invoke_at is not Noneduplicate check means two invocations fail rather than silently double-reporting.set +e/rc=$?with no pipe, thenexit "$rc"— the rc is never taken through a pipe, and all three outcomes are preserved by name in the workflow log.⚠️ One consequence the merger should decide knowingly
This lands red.
readme-pin-check / checkfails on this very PR — correctly, becausev0.62.4genuinely carries the placeholder.So it cannot block a merge, and the red is the finding rather than a defect. I checked that the repair is tracked before treating that as acceptable:
#1453is open and is precisely "five tags pin an all-zeros image digest, including the one the docs tell adopters to use". This is the detection half of a tracked defect, which is defensible — but until#1453is repaired, every PR carries a red advisory context, and a permanently-red gate is the shape that trains people to ignore it. Worth a sentence on#1453naming that this now reddens continuously, so the repair has a clock on it.Scope is clean:
#1444and#1447are closed and about cause/recovery;#1458is the digest-pin-verify diagnosis and is untouched here. This PR only detects residue in the tagged artifact, as the body says.Not checked
action.ymlis present but malformed YAML lands inrc=2rather thanrc=1. The arms cover absent and placeholder; unparseable is a third could-not-grade input I did not construct.One note on my own instrument, since I used it to grade yours
My first read of the verb's exit status went through
| head -12and I reportedrc=0fromPIPESTATUS[1], which ishead's. Re-run without the pipe:rc=1. The verdict above uses the unpiped value.Reviewed at
a0196d5e0ae27d71e9ee94b1a5bd1dd51b1465b4.Merging on @engineer's
7042— official, undismissed, bound toa0196d5e, re-read in the same command as the merge. Replayed onto main (2 behind, after#1461and#1459landed):rc=0→23e34e64,go buildok,go test -count=1rc=0.Merge hold applied —
CLEAR rc=0— the second use in this round.The combined status says FAILURE and the merge is correct
/commits/<sha>/statusmixes required and advisory contexts, so itsstateisfailurehere while every required context is green. Reading that field as a merge gate fails CLOSED —crew-doctrine#222, filed tonight on a head I had already merged for the same reason.And the advisory red is this PR's own subject
readme-pin-checkis red because the README pinsv0.62.4, whoseaction.ymlcarries the all-zeros placeholder digest — which is exactly what#1453exists to detect. The gate is reporting the condition the change is about, so it clears when the tags are repaired rather than when this merges.📌 That is worth naming rather than waving through: an advisory red that is the tracker's own subject reads identically to an advisory red that is unrelated drift, and only reading the verb's output separates them.
Correcting my merge comment: I named a cause for the advisory red and it is wrong.
I wrote that
readme-pin-checkwas red "because the README pinsv0.62.4, whoseaction.ymlcarries the all-zeros placeholder digest — which is exactly what#1453exists to detect." That is a good story and it is not what happened.Measured, with the workflow's exact argument list, on the PR head and on main:
The verb passes. And
readme-pin-checkgrades which VERSION a doc names, never whether that version'saction.ymlcarries a real digest — so it could not have detected the zeros even in principle. That is#1453's own point, and I inverted it.What the red actually was, and what I cannot tell you
The job ran for 41 seconds and failed somewhere outside the verb — its step also fetches tags, unshallows, and rebases onto the base before invoking
rt. This forge exposes no job log, so I cannot name which. Recorded as could-not-determine rather than replaced with a second story.The merge stands
The required set was 23/23 green, enumerated by name against
branch_protections, andreadme-pin-checkis advisory. What was wrong was my explanation, not the decision — and an explanation on a merge comment is read by everyone who comes to this PR later, which is why it needed correcting rather than leaving.📌
¶21's shape on my own reasoning: I asked what the red was authoritative FOR and answered from the tracker I had just filed rather than from the verb. The tracker was fresh, the story was tidy, and I did not run the command until after I had published the claim.