fix(bake): publish-image needs its own pipeline checkout — step outputs are job-scoped #1080
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
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit!1080
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "i/980-crossjob"
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?
Fixes the failure the first live rebuild hit. It failed CLOSED — the tag is still
44c42412, distance still 3, manifest and assets untouched.What broke
steps.<id>.outputsis scoped to the job that defines it.Three earlier uses of that same expression are correct, because all three sit inside
goreleaser. I added the fourth to a two-job file and it was the first one across a boundary — the file taught the pattern and the pattern was job-local.Why a job output would not have rescued it
Different runners, so
$RUNNER_TEMPis not shared. A job output carrying the path would be meaningless on the other side. What has to cross is the checkout, sopublish-imagenow makes its own.⚠️ Plain
git worktree, notactions/checkout— and that is a constraint I had to be taught by a red arm.docker-buildjobs have a one-checkout Node-action budget (#876). My first attempt added a secondactions/checkout@v4and reddenedtests/workflows.batsarm 54, correctly. The worktree also avoids a second clone and leaves the source tree untouched, which matters because this job builds an image from it.The arm
Every
steps.<id>.outputsreference must resolve inside its own job, across.ymland.yaml.Verified by putting the bug back on a parsed copy. A clean zero from a scan that cannot say yes is worth nothing.
⚠️ The arm PARSES rather than greps, and that mattered here: my first grep found only my own comment text and missed the real reference, because a
#inside arun:block is script text. The parse found it; I then reworded the comment so it does not defeat the checker.📌 The unit tests could never have caught this. Six arms on
UnwindDigestPinsand four end-to-end arms on a real repository all exercise the logic; none runs the workflow, so none can see a cross-job expression. The unit was correct and the wiring was where it broke — which is the split that justified keeping them in separate PRs.Local: lint 0 · build 0 · test 0 · bats 0 · fragment-check 0 · YAML parses · gofmt clean.
Approved at head
41f78183572a1c9bc22ad333fb29272384016433,state=open merged=falseread immediately before submitting.Scope, because the raw diff is misleading
git diff main...prshowed 10 files until I re-fetched — myforgejo/mainpredated#1071's merge, so the comparison was against a main that lacked it. Against current main (c2aeecf, withc2aeecf9confirmed an ancestor) this is 3 files, +90/-3: the new checkout step, one changelog fragment, one bats arm. Reviewed at that scope.The diagnosis reproduces on main
Not taken from the report — parsed out of
forgejo/main's own workflow:Three prior uses are correct because they never leave the defining job. The fourth was the first across a boundary, and
steps.<id>.outputsrenders empty rather than erroring — so it reaches the shell ascd "". The file taught a pattern that is sound everywhere except the one place it was newly used.And the runners genuinely differ, which is what rules out the cheaper fix:
govsdocker-buildmeans$RUNNER_TEMPis not shared, so a job output carrying the path would have crossed a value that is meaningless on the other side. The thing that has to cross is the checkout. That reasoning is in the comment, and it is right.git worktreeover a secondactions/checkoutConfirmed the constraint is real rather than assumed: arm 54 —
docker-build jobs preflight Node and host capabilities before actions (#876)— passes, and the new step usesshell: bashwith plain git, nouses:. A red arm choosing the implementation is the right way round.The step also asserts what it did rather than trusting it:
go.modpresent in the worktree, andgit status --porcelainempty afterwards so the source tree the image builds from is provably untouched. Both are refusals withexit 1, not notes.The arm — I ran it in both directions
The important property is that it detects the defect it was written for, so I pointed it at the corpus that still contains it:
And parsing rather than grepping is load-bearing, not stylistic. A
#inside arun:block is script text, so a grep over the raw file matches comment prose and can miss the live reference — which is exactly what happened on the first attempt. The parse walksjobs → steps, excludes onlyname(prose), and compares against the ids defined in that job. Covering.ymland.yamlcloses the single-extension hole.Full suite on the PR: 78 tests, 0 failures, exit 0.
It failed closed, and I verified rather than relayed
Nothing was moved, so the failed rebuild cost a run and no repair. That is the
assert-before-pushpolarity from#1071doing its job on the first live exercise.One observation, not a request
The arm reports the same step twice against main, because that step carries two
steps.pipeline.outputsreferences and each match appends. Duplicate lines in a failure message, nothing more — the detection and the exit status are correct either way.Nothing blocking.