fix: restore Forgejo workflow names #261

Merged
andres merged 4 commits from build/243-forgejo-workflow-name into main 2026-08-25 11:52:50 +00:00

Closes #243

Summary

Restore the Forgejo adapter contract by deriving workflowName from 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 inside context; lib/forge-github.sh already receives it on CheckRun nodes and needs no change.

Worklog

  • Claim #243 and create build/243-forgejo-workflow-name from origin/main
  • Record baseline counts: forge-backends 147, labels-reconcile 252; whole suite 31 files green
  • Add adapter and StatusContext-only reconciler regressions first
  • Record RED: forge-backends 147 passed / 2 failed; labels-reconcile 254 passed / 2 failed
  • Add minimal workflowName mapping to the Forgejo adapter
  • Run focused GREEN tests and record raised assertion counts
  • Add grouped changelog.d/243.md
  • Run whole suite, sanctioned shellcheck, git diff --check, and exact-scope guards

Acceptance criteria

  • forge_pr_view emits workflowName for every rollup entry, set to the substring of context before the first /, with RED-first output recorded for the assertion.
  • A context carrying no / emits workflowName: "" and is not excluded by the reconciler, with RED-first output recorded.
  • checks_state, driven by a rollup of StatusContext nodes whose only FAILURE belongs to SELF_WORKFLOW, returns PENDING—not FAILURE—with RED-first output recorded.
  • A rollup whose only entries belong to SELF_WORKFLOW returns NONE, not SUCCESS, asserted through the Forgejo shape.
  • A rollup carrying a real FAILURE from another workflow still returns FAILURE.
  • actions/labels-reconcile/labels-reconcile.sh has no diff.
  • lib/forge-github.sh has no diff.
  • No existing assertion is deleted or weakened; both touched test-file assertion counts rise, with before/after counts stated.
  • The full suite and sanctioned shellcheck are green at the PR head, with file and script counts stated.

Test evidence

Baseline at 6dc8bf6: forge-backends 147 passed; labels-reconcile 252 passed; 31 test files passed.

RED at 9f54eb9:

forge-backends: 147 passed, 2 failed
labels-reconcile: 254 passed, 2 failed

The failures are the absent adapter fields and the resulting self FAILURE classifications (FAILURE instead of PENDING / NONE).

Focused GREEN after the adapter change: forge-backends 149 passed / 0 failed; labels-reconcile 256 passed / 0 failed.

Final verification

At 54a933436361648e37707459ee88d9532887705e:

  • forge-backends: 149 passed, 0 failed (baseline 147).
  • labels-reconcile: 258 passed, 0 failed (baseline 252).
  • Whole suite: 31 test files passed, 0 failed.
  • Sanctioned shellcheck: 64 tracked scripts, clean.
  • Changelog validation: 103 passed, 0 failed.
  • git diff --check: clean.
  • Exact diff: the four intended files only; actions/labels-reconcile/labels-reconcile.sh and lib/forge-github.sh byte-identical to origin/main.
  • Worktree clean.

Pre-handoff review follow-up: adapter fixtures now cover labels, CI, and Refs guard with 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 54a93343

Round passed with no written reply.

Closes #243 ## Summary Restore the Forgejo adapter contract by deriving `workflowName` from 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 inside `context`; `lib/forge-github.sh` already receives it on `CheckRun` nodes and needs no change. ## Worklog - [x] Claim #243 and create `build/243-forgejo-workflow-name` from `origin/main` - [x] Record baseline counts: `forge-backends` 147, `labels-reconcile` 252; whole suite 31 files green - [x] Add adapter and StatusContext-only reconciler regressions first - [x] Record RED: `forge-backends` 147 passed / 2 failed; `labels-reconcile` 254 passed / 2 failed - [x] Add minimal `workflowName` mapping to the Forgejo adapter - [x] Run focused GREEN tests and record raised assertion counts - [x] Add grouped `changelog.d/243.md` - [x] Run whole suite, sanctioned shellcheck, `git diff --check`, and exact-scope guards ## Acceptance criteria - [x] `forge_pr_view` emits `workflowName` for every rollup entry, set to the substring of `context` before the first ` / `, with RED-first output recorded for the assertion. - [x] A `context` carrying no ` / ` emits `workflowName: ""` and is not excluded by the reconciler, with RED-first output recorded. - [x] `checks_state`, driven by a rollup of `StatusContext` nodes whose only FAILURE belongs to `SELF_WORKFLOW`, returns PENDING—not FAILURE—with RED-first output recorded. - [x] A rollup whose only entries belong to `SELF_WORKFLOW` returns NONE, not SUCCESS, asserted through the Forgejo shape. - [x] A rollup carrying a real FAILURE from another workflow still returns FAILURE. - [x] `actions/labels-reconcile/labels-reconcile.sh` has no diff. - [x] `lib/forge-github.sh` has no diff. - [x] No existing assertion is deleted or weakened; both touched test-file assertion counts rise, with before/after counts stated. - [x] The full suite and sanctioned shellcheck are green at the PR head, with file and script counts stated. ## Test evidence Baseline at `6dc8bf6`: `forge-backends` 147 passed; `labels-reconcile` 252 passed; 31 test files passed. RED at `9f54eb9`: ```text forge-backends: 147 passed, 2 failed labels-reconcile: 254 passed, 2 failed ``` The failures are the absent adapter fields and the resulting self FAILURE classifications (`FAILURE` instead of `PENDING` / `NONE`). Focused GREEN after the adapter change: `forge-backends` 149 passed / 0 failed; `labels-reconcile` 256 passed / 0 failed. ## Final verification At `54a933436361648e37707459ee88d9532887705e`: - `forge-backends`: 149 passed, 0 failed (baseline 147). - `labels-reconcile`: 258 passed, 0 failed (baseline 252). - Whole suite: 31 test files passed, 0 failed. - Sanctioned shellcheck: 64 tracked scripts, clean. - Changelog validation: 103 passed, 0 failed. - `git diff --check`: clean. - Exact diff: the four intended files only; `actions/labels-reconcile/labels-reconcile.sh` and `lib/forge-github.sh` byte-identical to `origin/main`. - Worktree clean. Pre-handoff review follow-up: adapter fixtures now cover `labels`, `CI`, and `Refs guard` with 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:54a933436361648e37707459ee88d9532887705e --> **Round at 54a93343** _Round passed with no written reply._
codex-bot-andresmgsl added 1 commit 2026-08-25 08:42:13 +00:00
test: expose missing Forgejo workflow names
Some checks failed
CI / test (pull_request) Failing after 3m48s
CI / release-exercise (pull_request) Successful in 25s
CI / self-guards (pull_request) Successful in 21s
CI / action-exercise (pull_request) Successful in 20s
CI / docs-sync-exercise (pull_request) Successful in 20s
labels / labels (pull_request) Successful in 22s
Refs guard / refs-not-closing (pull_request) Successful in 20s
9f54eb98bf
codex-bot-andresmgsl added 1 commit 2026-08-25 08:43:05 +00:00
fix: restore Forgejo workflow names
All checks were successful
CI / test (pull_request) Successful in 3m49s
CI / release-exercise (pull_request) Successful in 24s
CI / self-guards (pull_request) Successful in 20s
CI / action-exercise (pull_request) Successful in 20s
CI / docs-sync-exercise (pull_request) Successful in 20s
labels / labels (pull_request) Successful in 22s
Refs guard / refs-not-closing (pull_request) Successful in 20s
21871de5ee
codex-bot-andresmgsl added 1 commit 2026-08-25 08:43:26 +00:00
docs: record Forgejo workflow-name fix
All checks were successful
CI / test (pull_request) Successful in 3m55s
CI / release-exercise (pull_request) Successful in 25s
CI / self-guards (pull_request) Successful in 21s
CI / action-exercise (pull_request) Successful in 20s
CI / docs-sync-exercise (pull_request) Successful in 20s
labels / labels (pull_request) Successful in 22s
Refs guard / refs-not-closing (pull_request) Successful in 20s
4bdb80bf80
codex-bot-andresmgsl added 1 commit 2026-08-25 08:54:04 +00:00
test: complete Forgejo workflow-name matrix
All checks were successful
CI / test (pull_request) Successful in 3m48s
CI / release-exercise (pull_request) Successful in 26s
CI / self-guards (pull_request) Successful in 21s
CI / action-exercise (pull_request) Successful in 19s
CI / docs-sync-exercise (pull_request) Successful in 20s
labels / labels (pull_request) Successful in 22s
Refs guard / refs-not-closing (pull_request) Successful in 20s
54a9334363
Author
Member

📣 round answered at head 54a9334363

📣 round answered at head 54a933436361648e37707459ee88d9532887705e
codex-bot-andresmgsl changed title from WIP: fix: restore Forgejo workflow names to fix: restore Forgejo workflow names 2026-08-25 08:57:08 +00:00
forgejo-actions added the
scope:labels
scope:release-flow
labels 2026-08-25 09:29:57 +00:00
codex-bot-andresmgsl requested review from glm-bot-andresmgsl 2026-08-25 09:55:52 +00:00
codex-bot-andresmgsl requested review from claude-bot-andresmgsl 2026-08-25 09:55:52 +00:00
codex-bot-andresmgsl requested review from kimi-bot-andresmgsl 2026-08-25 09:55:53 +00:00
codex-bot-andresmgsl added the
state:bots-reviewing
label 2026-08-25 09:55:54 +00:00

🔎 reviewing head 54a9334363

Verification complete at this head; verdict next.

  • Acceptance criteria: all nine met (adapter workflowName, bare-context "", StatusContext PENDING / NONE / foreign FAILURE, both no-diff files, assertion counts up, suite + shellcheck green).
  • Reproduced RED by reverting the adapter hunk at this head: forge-backends 147/2, labels-reconcile 256/2.
  • Reproduced GREEN: forge-backends 149/0, labels-reconcile 258/0; whole suite 31 files / 0 failed; .github/scripts/shellcheck-all.sh clean over 64 tracked scripts.
  • Baseline at 6dc8bf6: 147 and 252 — the stated rises check out.
  • Mutation probes on the parser: last-separator-instead-of-first reds 1 reconciler case; dropping the contains guard reds the adapter's bare-context case; stripping the prefix out of context reds the adapter too.
🔎 reviewing head 54a933436361648e37707459ee88d9532887705e Verification complete at this head; verdict next. - Acceptance criteria: all nine met (adapter `workflowName`, bare-context `""`, StatusContext PENDING / NONE / foreign FAILURE, both no-diff files, assertion counts up, suite + shellcheck green). - Reproduced RED by reverting the adapter hunk at this head: `forge-backends` 147/2, `labels-reconcile` 256/2. - Reproduced GREEN: `forge-backends` 149/0, `labels-reconcile` 258/0; whole suite 31 files / 0 failed; `.github/scripts/shellcheck-all.sh` clean over 64 tracked scripts. - Baseline at `6dc8bf6`: 147 and 252 — the stated rises check out. - Mutation probes on the parser: last-separator-instead-of-first reds 1 reconciler case; dropping the `contains` guard reds the adapter's bare-context case; stripping the prefix out of `context` reds the adapter too.

🔎 reviewing head 54a9334363

  • Reviewed against #243 acceptance criteria.
  • Diff scope (triple-dot): changelog.d/243.md, lib/forge-forgejo.sh, test/forge-backends.test.sh, test/labels-reconcile.test.sh.
  • actions/labels-reconcile/labels-reconcile.sh and lib/forge-github.sh unchanged.
  • forge-backends: 149 passed / 0 failed (was 147).
  • labels-reconcile: 258 passed / 0 failed (was 252).
  • shellcheck-all: 64 tracked scripts clean.
  • git diff --check: clean.
  • Full suite: 27 files passed, 4 failed only on node/npm-dependent cases (this box has no node); actionlint not installed. I relied on the PR's recorded CI evidence for those.
  • Verdict: approve.
🔎 reviewing head 54a933436361648e37707459ee88d9532887705e - Reviewed against #243 acceptance criteria. - Diff scope (triple-dot): changelog.d/243.md, lib/forge-forgejo.sh, test/forge-backends.test.sh, test/labels-reconcile.test.sh. - actions/labels-reconcile/labels-reconcile.sh and lib/forge-github.sh unchanged. - forge-backends: 149 passed / 0 failed (was 147). - labels-reconcile: 258 passed / 0 failed (was 252). - shellcheck-all: 64 tracked scripts clean. - git diff --check: clean. - Full suite: 27 files passed, 4 failed only on node/npm-dependent cases (this box has no node); actionlint not installed. I relied on the PR's recorded CI evidence for those. - Verdict: approve.

🔎 reviewing head 54a9334363

  • Criteria settled (all run, not read): RED reproduced at 9f54eb9 (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.
  • Non-blocking nit noted: the two new check calls swallow their own ok/FAIL echo via >/dev/null on the check invocation (pre-existing pattern, counters honest).
  • Composing verdict.
🔎 reviewing head 54a933436361648e37707459ee88d9532887705e - Criteria settled (all run, not read): RED reproduced at 9f54eb9 (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. - Non-blocking nit noted: the two new check calls swallow their own ok/FAIL echo via >/dev/null on the check invocation (pre-existing pattern, counters honest). - Composing verdict.
kimi-bot-andresmgsl approved these changes 2026-08-25 10:11:37 +00:00
kimi-bot-andresmgsl left a comment
Member

Approve.

Reviewed against the acceptance criteria in #243:

  • lib/forge-forgejo.sh now derives workflowName from the first / separator of each context, leaving context whole and emitting "" when there is no separator. This is the minimal backend fix the issue spec asked for.
  • actions/labels-reconcile/labels-reconcile.sh and lib/forge-github.sh are byte-identical to origin/main.
  • The diff (triple-dot vs origin/main) is exactly the four intended files: changelog.d/243.md, lib/forge-forgejo.sh, test/forge-backends.test.sh, and test/labels-reconcile.test.sh.
  • Test counts rose as required: forge-backends 149/0 (from 147), labels-reconcile 258/0 (from 252). No existing assertion was deleted or weakened.
  • shellcheck-all.sh is clean over 64 tracked scripts.
  • git diff --check is clean.

What I could not verify locally: the full bash test/run.sh run is not green here because this box has no node/npm, so the package-json cases in version.test.sh, changelog-assembled.test.sh, release-chain.test.sh, and release-path.test.sh fail. actionlint is 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. Reviewed against the acceptance criteria in #243: - `lib/forge-forgejo.sh` now derives `workflowName` from the first ` / ` separator of each `context`, leaving `context` whole and emitting `""` when there is no separator. This is the minimal backend fix the issue spec asked for. - `actions/labels-reconcile/labels-reconcile.sh` and `lib/forge-github.sh` are byte-identical to `origin/main`. - The diff (triple-dot vs `origin/main`) is exactly the four intended files: `changelog.d/243.md`, `lib/forge-forgejo.sh`, `test/forge-backends.test.sh`, and `test/labels-reconcile.test.sh`. - Test counts rose as required: `forge-backends` 149/0 (from 147), `labels-reconcile` 258/0 (from 252). No existing assertion was deleted or weakened. - `shellcheck-all.sh` is clean over 64 tracked scripts. - `git diff --check` is clean. What I could not verify locally: the full `bash test/run.sh` run is not green here because this box has no `node`/`npm`, so the `package-json` cases in `version.test.sh`, `changelog-assembled.test.sh`, `release-chain.test.sh`, and `release-path.test.sh` fail. `actionlint` is 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.
claude-bot-andresmgsl approved these changes 2026-08-25 10:12:35 +00:00
claude-bot-andresmgsl left a comment
Member

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:

forge-backends:    147 passed, 0 failed
labels-reconcile:  252 passed, 0 failed

At this head:

forge-backends:    149 passed, 0 failed
labels-reconcile:  258 passed, 0 failed
test/run.sh:       31 test files passed, 0 failed
.github/scripts/shellcheck-all.sh: 64 tracked scripts, clean
.github/scripts/marker-check.sh:   agrees with the tree
.github/scripts/vendored-check.sh: green
git diff --check (merge-base..head):  clean

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 workflowName hunk from lib/forge-forgejo.sh at this head and re-ran the two touched files:

forge-backends:    147 passed, 2 failed
labels-reconcile:  256 passed, 2 failed
  FAIL: Forgejo StatusContexts exclude a self FAILURE and retain pending work — want PENDING, got FAILURE
  FAIL: Forgejo StatusContexts containing only the self workflow are NONE — want NONE, got FAILURE

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

  • Truncate at the last separator instead of the first → reds a Forgejo workflow name containing a separator is never guessed (labels / nested / check under SELF_WORKFLOW="labels / nested" becomes NONE instead of FAILURE). The "first separator" half of the spec is pinned.
  • Drop the contains(" / ") guard, so a bare context guesses its whole string as the name → reds pr_view leaves workflowName empty when the context has no separator. The no-guess half is pinned.
  • Strip the derived prefix out of context → reds forge-backends. The issue's "leave context whole" 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 codecov as 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

criterion verdict
workflowName = context before the first /, RED recorded met — adapter assertion covers labels, CI, Refs guard with contexts intact
bare context → "", not excluded, RED recorded met — adapter assertion plus two reconciler cases (named and empty SELF_WORKFLOW)
StatusContext rollup, only FAILURE is self → PENDING met, RED reproduced above
self-only rollup → NONE, not SUCCESS met, RED reproduced above
foreign FAILURE still FAILURE met
actions/labels-reconcile/labels-reconcile.sh no diff met — git diff origin/main..HEAD on the path is empty
lib/forge-github.sh no diff met — same check, empty
no assertion deleted/weakened, counts rise, stated met — measured independently against 6dc8bf6
suite + shellcheck green, counts stated met — 31 files, 64 scripts

The forge-backends fixture rename (ci / checklabels / labels (pull_request) plus three added rows) was the one place a fixture edit could have quietly weakened something: the the newest verdict per context wins assertion at the end of that block feeds the same rollup to the production checks_state. It still exercises the duplicate-context pair — SELF_WORKFLOW is unset there, and even under a CI-set GITHUB_WORKFLOW=CI the excluded entry would be CI / test, never the labels / labels pair the assertion is about. Not weakened.

End to end, the fix reaches the real path: labels-sweep.yml passes pr_workflow_name (default labels) as SELF_WORKFLOW, and #243's measured !242 rollup carries labels / labels (pull_request) — so the derived name matches exactly and the self entry now leaves the rollup before the newest-per-context collapse. ctx becomes ["labels", "labels / labels (pull_request)"], still unique per check, so the collapse at :416 is unchanged.

Non-blocking

  • changelog.d/243.md reads …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.
  • Observation, explicitly out of scope for #243 and not a change I'm asking for: SELF_WORKFLOW is the PR-facing caller's name (labels), so entries from the sweep's own workflow (labels-sweep) would derive labels-sweep and 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

  • actionlint is not installed on this box and I did not install it. The PR touches no YAML (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.
  • yq was absent here too. Without it, labels-bootstrap, labels-dispatch and labels-triggers fail with yq: 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 sets CEREMONY_REQUIRE_YQ=1, so those paths are gated there regardless.
  • I did not exercise the fix against a live Forgejo rollup. The evidence I relied on is #243's measured !242 status list, replayed through the real adapter by the new forgejo_rollup helper — which sources lib/forge-forgejo.sh and stubs only forge_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-written workflowName fixtures are exactly what hid it.
**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: ```text forge-backends: 147 passed, 0 failed labels-reconcile: 252 passed, 0 failed ``` At this head: ```text forge-backends: 149 passed, 0 failed labels-reconcile: 258 passed, 0 failed test/run.sh: 31 test files passed, 0 failed .github/scripts/shellcheck-all.sh: 64 tracked scripts, clean .github/scripts/marker-check.sh: agrees with the tree .github/scripts/vendored-check.sh: green git diff --check (merge-base..head): clean ``` 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 `workflowName` hunk from `lib/forge-forgejo.sh` at this head and re-ran the two touched files: ```text forge-backends: 147 passed, 2 failed labels-reconcile: 256 passed, 2 failed FAIL: Forgejo StatusContexts exclude a self FAILURE and retain pending work — want PENDING, got FAILURE FAIL: Forgejo StatusContexts containing only the self workflow are NONE — want NONE, got FAILURE ``` 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 - **Truncate at the last separator instead of the first** → reds `a Forgejo workflow name containing a separator is never guessed` (`labels / nested / check` under `SELF_WORKFLOW="labels / nested"` becomes NONE instead of FAILURE). The "first separator" half of the spec is pinned. - **Drop the `contains(" / ")` guard**, so a bare context guesses its whole string as the name → reds `pr_view leaves workflowName empty when the context has no separator`. The no-guess half is pinned. - **Strip the derived prefix out of `context`** → reds `forge-backends`. The issue's "leave `context` whole" 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 `codecov` as 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 | criterion | verdict | |---|---| | `workflowName` = `context` before the first ` / `, RED recorded | met — adapter assertion covers `labels`, `CI`, `Refs guard` with contexts intact | | bare context → `""`, not excluded, RED recorded | met — adapter assertion plus two reconciler cases (named and empty `SELF_WORKFLOW`) | | StatusContext rollup, only FAILURE is self → PENDING | met, RED reproduced above | | self-only rollup → NONE, not SUCCESS | met, RED reproduced above | | foreign FAILURE still FAILURE | met | | `actions/labels-reconcile/labels-reconcile.sh` no diff | met — `git diff origin/main..HEAD` on the path is empty | | `lib/forge-github.sh` no diff | met — same check, empty | | no assertion deleted/weakened, counts rise, stated | met — measured independently against `6dc8bf6` | | suite + shellcheck green, counts stated | met — 31 files, 64 scripts | The `forge-backends` fixture rename (`ci / check` → `labels / labels (pull_request)` plus three added rows) was the one place a fixture edit could have quietly weakened something: the `the newest verdict per context wins` assertion at the end of that block feeds the same rollup to the production `checks_state`. It still exercises the duplicate-context pair — `SELF_WORKFLOW` is unset there, and even under a CI-set `GITHUB_WORKFLOW=CI` the excluded entry would be `CI / test`, never the `labels / labels` pair the assertion is about. Not weakened. End to end, the fix reaches the real path: `labels-sweep.yml` passes `pr_workflow_name` (default `labels`) as `SELF_WORKFLOW`, and #243's measured !242 rollup carries `labels / labels (pull_request)` — so the derived name matches exactly and the self entry now leaves the rollup before the newest-per-context collapse. `ctx` becomes `["labels", "labels / labels (pull_request)"]`, still unique per check, so the collapse at `:416` is unchanged. ## Non-blocking - `changelog.d/243.md` reads `…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. - Observation, explicitly out of scope for #243 and not a change I'm asking for: `SELF_WORKFLOW` is the PR-facing caller's name (`labels`), so entries from the sweep's own workflow (`labels-sweep`) would derive `labels-sweep` and 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 - **actionlint** is not installed on this box and I did not install it. The PR touches no YAML (`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. - **yq** was absent here too. Without it, `labels-bootstrap`, `labels-dispatch` and `labels-triggers` fail with `yq: 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 sets `CEREMONY_REQUIRE_YQ=1`, so those paths are gated there regardless. - I did not exercise the fix against a live Forgejo rollup. The evidence I relied on is #243's measured !242 status list, replayed through the real adapter by the new `forgejo_rollup` helper — which sources `lib/forge-forgejo.sh` and stubs only `forge_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-written `workflowName` fixtures are exactly what hid it.
glm-bot-andresmgsl approved these changes 2026-08-25 10:18:37 +00:00
glm-bot-andresmgsl left a comment
Member

approve — whole-PR review of head 54a933436361648e37707459ee88d9532887705e against #243.

Acceptance criteria — verified by running, not by reading alone:

  • workflowName derivation: the adapter maps (.context // "") | if contains(" / ") then split(" / ")[0] else "" end — the prefix before the first /, "" on a bare context (codecov fixture). Verified RED-first myself: at the RED commit 9f54eb9 I reproduced the recorded failures exactly — forge-backends 147 passed / 2 failed, labels-reconcile 254 passed / 2 failed, failing on precisely the absent-field assertions (want PENDING, got FAILURE; want NONE, got FAILURE).
  • checks_state over StatusContext-only rollups, driven through the real forge_pr_view (the forgejo_rollup harness stubs only forge_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 empty SELF_WORKFLOW; a workflow name containing / truncates at the first separator and survives. All green at head.
  • No-diff constraints: actions/labels-reconcile/labels-reconcile.sh and lib/forge-github.sh are byte-identical to origin/main (verified with git diff --quiet at the review checkout).
  • Assertion floor: measured forge-backends 147 / labels-reconcile 252 on origin/main, 149 / 258 at head — both rise, the diff to the test files is additive, and the rewritten FAKE_STATUS preserves the newest-wins pair (success newer, failure older, same context) so the pre-existing array-order assertion still exercises what it did.
  • Suite and lint at head, run on this box: bash test/run.sh → 31 test files, 0 failed; sanctioned .github/scripts/shellcheck-all.sh → 64 tracked scripts, clean; .github/scripts/actionlint-all.sh clean; git diff --check clean. The forge's live rollup at the head agrees: 7/7 contexts success, including labels / labels.
  • Mutation probe: reparsing two segments instead of truncating at the first separator reddens exactly the 3 nested/self labels-reconcile cases — reproducing the PR's mutation note; the tests bite.
  • Spec decisions honored: the backend is fixed, not the reconciler; context stays whole; the StatusContext shape stays; no special-casing of the string labels; the exclusion is not widened. changelog.d/243.md present in the grouped shape, and the PR body states the two required facts (name lives only in context on Forgejo; lib/forge-github.sh needs no change).

Non-blocking nit (rides the approval, builder's discretion): the two new check calls in test/forge-backends.test.sh end with >/dev/null <<<"$view_json", which applies to the check invocation 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.

✅ **approve** — whole-PR review of head `54a933436361648e37707459ee88d9532887705e` against #243. **Acceptance criteria — verified by running, not by reading alone:** - `workflowName` derivation: the adapter maps `(.context // "") | if contains(" / ") then split(" / ")[0] else "" end` — the prefix before the first ` / `, `""` on a bare context (`codecov` fixture). Verified RED-first myself: at the RED commit `9f54eb9` I reproduced the recorded failures exactly — `forge-backends` 147 passed / 2 failed, `labels-reconcile` 254 passed / 2 failed, failing on precisely the absent-field assertions (`want PENDING, got FAILURE`; `want NONE, got FAILURE`). - `checks_state` over `StatusContext`-only rollups, driven through the real `forge_pr_view` (the `forgejo_rollup` harness stubs only `forge_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 empty `SELF_WORKFLOW`; a workflow name containing ` / ` truncates at the first separator and survives. All green at head. - No-diff constraints: `actions/labels-reconcile/labels-reconcile.sh` and `lib/forge-github.sh` are byte-identical to `origin/main` (verified with `git diff --quiet` at the review checkout). - Assertion floor: measured `forge-backends` 147 / `labels-reconcile` 252 on `origin/main`, 149 / 258 at head — both rise, the diff to the test files is additive, and the rewritten `FAKE_STATUS` preserves the newest-wins pair (success newer, failure older, same context) so the pre-existing array-order assertion still exercises what it did. - Suite and lint at head, run on this box: `bash test/run.sh` → 31 test files, 0 failed; sanctioned `.github/scripts/shellcheck-all.sh` → 64 tracked scripts, clean; `.github/scripts/actionlint-all.sh` clean; `git diff --check` clean. The forge's live rollup at the head agrees: 7/7 contexts success, including `labels / labels`. - Mutation probe: reparsing two segments instead of truncating at the first separator reddens exactly the 3 nested/self `labels-reconcile` cases — reproducing the PR's mutation note; the tests bite. - Spec decisions honored: the backend is fixed, not the reconciler; `context` stays whole; the `StatusContext` shape stays; no special-casing of the string `labels`; the exclusion is not widened. `changelog.d/243.md` present in the grouped shape, and the PR body states the two required facts (name lives only in `context` on Forgejo; `lib/forge-github.sh` needs no change). **Non-blocking nit** (rides the approval, builder's discretion): the two new `check` calls in `test/forge-backends.test.sh` end with `>/dev/null <<<"$view_json"`, which applies to the `check` invocation 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.
forgejo-actions added
state:needs-human
and removed
state:bots-reviewing
labels 2026-08-25 10:22:39 +00:00
codex-bot-andresmgsl requested review from andres 2026-08-25 10:40:57 +00:00
andres merged commit 484eb79623 into main 2026-08-25 11:52:50 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
4 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: heavy-duty/ceremony#261
No description provided.