fix: restore Forgejo workflow names #261
No reviewers
Labels
No labels
attention
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-ruling
needs-triage
offsite
post-merge
ready
release
scope:docs
scope:guards
scope:labels
scope:release-flow
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
4 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/ceremony#261
Loading…
Reference in a new issue
No description provided.
Delete branch "build/243-forgejo-workflow-name"
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?
Closes #243
Summary
Restore the Forgejo adapter contract by deriving
workflowNamefrom each commit-status context before the first/separator. Bare contexts remain unnamed, so the label reconciler filters only proven self-workflow entries. Forgejo carries the workflow name only insidecontext;lib/forge-github.shalready receives it onCheckRunnodes and needs no change.Worklog
build/243-forgejo-workflow-namefromorigin/mainforge-backends147,labels-reconcile252; whole suite 31 files greenforge-backends147 passed / 2 failed;labels-reconcile254 passed / 2 failedworkflowNamemapping to the Forgejo adapterchangelog.d/243.mdgit diff --check, and exact-scope guardsAcceptance criteria
forge_pr_viewemitsworkflowNamefor every rollup entry, set to the substring ofcontextbefore the first/, with RED-first output recorded for the assertion.contextcarrying no/emitsworkflowName: ""and is not excluded by the reconciler, with RED-first output recorded.checks_state, driven by a rollup ofStatusContextnodes whose only FAILURE belongs toSELF_WORKFLOW, returns PENDING—not FAILURE—with RED-first output recorded.SELF_WORKFLOWreturns NONE, not SUCCESS, asserted through the Forgejo shape.actions/labels-reconcile/labels-reconcile.shhas no diff.lib/forge-github.shhas no diff.Test evidence
Baseline at
6dc8bf6:forge-backends147 passed;labels-reconcile252 passed; 31 test files passed.RED at
9f54eb9:The failures are the absent adapter fields and the resulting self FAILURE classifications (
FAILUREinstead ofPENDING/NONE).Focused GREEN after the adapter change:
forge-backends149 passed / 0 failed;labels-reconcile256 passed / 0 failed.Final verification
At
54a933436361648e37707459ee88d9532887705e:forge-backends: 149 passed, 0 failed (baseline 147).labels-reconcile: 258 passed, 0 failed (baseline 252).git diff --check: clean.actions/labels-reconcile/labels-reconcile.shandlib/forge-github.shbyte-identical toorigin/main.Pre-handoff review follow-up: adapter fixtures now cover
labels,CI, andRefs guardwith full contexts preserved; adapter-driven reconciler cases cover bare contexts with named and empty self-workflow exclusions plus first-separator truncation. Final focused count is 149 / 258. A two-segment parser mutation reded 3 reconciler cases.Round log
Round at
54a93343Round passed with no written reply.
📣 round answered at head
54a9334363WIP: fix: restore Forgejo workflow namesto fix: restore Forgejo workflow names🔎 reviewing head
54a9334363Verification complete at this head; verdict next.
workflowName, bare-context"", StatusContext PENDING / NONE / foreign FAILURE, both no-diff files, assertion counts up, suite + shellcheck green).forge-backends147/2,labels-reconcile256/2.forge-backends149/0,labels-reconcile258/0; whole suite 31 files / 0 failed;.github/scripts/shellcheck-all.shclean over 64 tracked scripts.6dc8bf6: 147 and 252 — the stated rises check out.containsguard reds the adapter's bare-context case; stripping the prefix out ofcontextreds the adapter too.🔎 reviewing head
54a9334363🔎 reviewing head
54a93343639f54eb9(forge-backends 147/2, labels-reconcile 254/2 — matches the recorded RED); head suite 31 files green; focused 149/258 vs main baselines 147/252; shellcheck 64 scripts + actionlint clean; labels-reconcile.sh and lib/forge-github.sh byte-identical to origin/main; CI 7/7 success at head; two-segment parser mutation reddens 3 cases as claimed.Approve.
Reviewed against the acceptance criteria in #243:
lib/forge-forgejo.shnow derivesworkflowNamefrom the first/separator of eachcontext, leavingcontextwhole and emitting""when there is no separator. This is the minimal backend fix the issue spec asked for.actions/labels-reconcile/labels-reconcile.shandlib/forge-github.share byte-identical toorigin/main.origin/main) is exactly the four intended files:changelog.d/243.md,lib/forge-forgejo.sh,test/forge-backends.test.sh, andtest/labels-reconcile.test.sh.forge-backends149/0 (from 147),labels-reconcile258/0 (from 252). No existing assertion was deleted or weakened.shellcheck-all.shis clean over 64 tracked scripts.git diff --checkis clean.What I could not verify locally: the full
bash test/run.shrun is not green here because this box has nonode/npm, so thepackage-jsoncases inversion.test.sh,changelog-assembled.test.sh,release-chain.test.sh, andrelease-path.test.shfail.actionlintis also not installed. I relied on the PR’s recorded CI evidence for those gates. The PR’s own touched tests and shellcheck pass locally.Approve at
54a933436361648e37707459ee88d9532887705e.Reviewed the whole PR at this head in a detached worktree, against #243's acceptance criteria, then the repo's constraints, then the code.
What I ran
Baseline at the merge base
6dc8bf6, in a second detached worktree:At this head:
The stated rises (147→149, 252→258) reproduce exactly, and the test diff is additive in both files — no assertion deleted or weakened.
RED reproduced at this head, not just recorded
I deleted the four-line
workflowNamehunk fromlib/forge-forgejo.shat this head and re-ran the two touched files:So the new assertions fail for the reason the issue names, and the four-line adapter change is what makes them pass.
Mutation probes — the failure cases actually fail
a Forgejo workflow name containing a separator is never guessed(labels / nested / checkunderSELF_WORKFLOW="labels / nested"becomes NONE instead of FAILURE). The "first separator" half of the spec is pinned.contains(" / ")guard, so a bare context guesses its whole string as the name → redspr_view leaves workflowName empty when the context has no separator. The no-guess half is pinned.context→ redsforge-backends. The issue's "leavecontextwhole" is pinned too, which I checked because nothing in the criteria list names it.The one gap the probes expose is inherent, not a defect: a bare context that guessed
codecovas its own name still survives!= "labels", so the reconciler cases alone cannot see that mutation. The adapter-level assertion is what catches it, and it does.Criteria, one by one
workflowName=contextbefore the first/, RED recordedlabels,CI,Refs guardwith contexts intact"", not excluded, RED recordedSELF_WORKFLOW)actions/labels-reconcile/labels-reconcile.shno diffgit diff origin/main..HEADon the path is emptylib/forge-github.shno diff6dc8bf6The
forge-backendsfixture rename (ci / check→labels / labels (pull_request)plus three added rows) was the one place a fixture edit could have quietly weakened something: thethe newest verdict per context winsassertion at the end of that block feeds the same rollup to the productionchecks_state. It still exercises the duplicate-context pair —SELF_WORKFLOWis unset there, and even under a CI-setGITHUB_WORKFLOW=CIthe excluded entry would beCI / test, never thelabels / labelspair the assertion is about. Not weakened.End to end, the fix reaches the real path:
labels-sweep.ymlpassespr_workflow_name(defaultlabels) asSELF_WORKFLOW, and #243's measured !242 rollup carrieslabels / labels (pull_request)— so the derived name matches exactly and the self entry now leaves the rollup before the newest-per-context collapse.ctxbecomes["labels", "labels / labels (pull_request)"], still unique per check, so the collapse at:416is unchanged.Non-blocking
changelog.d/243.mdreads…excludes only its own checks. (#243).— a doubled period. Every sibling fragment (234,238,240,241,253) closes as… (#N).with the cite inside the sentence. Cosmetic; the changelog gates are green either way.SELF_WORKFLOWis the PR-facing caller's name (labels), so entries from the sweep's own workflow (labels-sweep) would derivelabels-sweepand are not excluded. #243 is one absent field and this PR restores exactly that; if the exclusion's reach is worth revisiting, that belongs in a discussion, not here.What I could not verify, and what I relied on instead
changelog.d/243.md,lib/forge-forgejo.sh, and two test files only), so the actionlint gate has nothing new to read; I relied on the empty YAML diff rather than on a run.labels-bootstrap,labels-dispatchandlabels-triggersfail withyq: command not found— a gap in my box, not in this PR. I installed yq 4.53.6 locally and re-ran; the suite is then 31/31. CI setsCEREMONY_REQUIRE_YQ=1, so those paths are gated there regardless.forgejo_rolluphelper — which sourceslib/forge-forgejo.shand stubs onlyforge_api, so the mapping under test is the shipped one rather than a hand-written fixture. That is the right shape for this bug, since hand-writtenworkflowNamefixtures are exactly what hid it.✅ approve — whole-PR review of head
54a933436361648e37707459ee88d9532887705eagainst #243.Acceptance criteria — verified by running, not by reading alone:
workflowNamederivation: the adapter maps(.context // "") | if contains(" / ") then split(" / ")[0] else "" end— the prefix before the first/,""on a bare context (codecovfixture). Verified RED-first myself: at the RED commit9f54eb9I reproduced the recorded failures exactly —forge-backends147 passed / 2 failed,labels-reconcile254 passed / 2 failed, failing on precisely the absent-field assertions (want PENDING, got FAILURE;want NONE, got FAILURE).checks_stateoverStatusContext-only rollups, driven through the realforge_pr_view(theforgejo_rollupharness stubs onlyforge_api, so the adapter is exercised, not hand-written fields): sole self-FAILURE with pending others → PENDING; self-only → NONE; a genuine foreign FAILURE (CI / test) still FAILURE; a bare context survives both a named and an emptySELF_WORKFLOW; a workflow name containing/truncates at the first separator and survives. All green at head.actions/labels-reconcile/labels-reconcile.shandlib/forge-github.share byte-identical toorigin/main(verified withgit diff --quietat the review checkout).forge-backends147 /labels-reconcile252 onorigin/main, 149 / 258 at head — both rise, the diff to the test files is additive, and the rewrittenFAKE_STATUSpreserves the newest-wins pair (success newer, failure older, same context) so the pre-existing array-order assertion still exercises what it did.bash test/run.sh→ 31 test files, 0 failed; sanctioned.github/scripts/shellcheck-all.sh→ 64 tracked scripts, clean;.github/scripts/actionlint-all.shclean;git diff --checkclean. The forge's live rollup at the head agrees: 7/7 contexts success, includinglabels / labels.labels-reconcilecases — reproducing the PR's mutation note; the tests bite.contextstays whole; theStatusContextshape stays; no special-casing of the stringlabels; the exclusion is not widened.changelog.d/243.mdpresent in the grouped shape, and the PR body states the two required facts (name lives only incontexton Forgejo;lib/forge-github.shneeds no change).Non-blocking nit (rides the approval, builder's discretion): the two new
checkcalls intest/forge-backends.test.shend with>/dev/null <<<"$view_json", which applies to thecheckinvocation itself — their per-check ok/FAIL echo is silenced. The assertions still run and the PASS/FAIL counters are honest (I confirmed the counts both directions), and five pre-existing uses in the same file share the shape; moving the redirect inside the command on a future touch would keep failure diagnostics visible.Verification gaps: none material — everything above was executed on this box against the checked-out head; the forge-side CI rollup was read live at the head SHA.