fix(tools/git): ci-queue-wait.sh treats 404 branch-absent as queue-clear #874
Reference in New Issue
Block a user
Delete Branch "fix/ci-queue-wait-404-branch-absent"
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?
What
ci-queue-wait.shis a mandatory pre-push CI queue guard. Its Gitea branch-head lookup(
gitea_get_branch_head_sha) calledcurl -fsSL .../branches/<branch>. For a branch that hasnever been pushed to the remote yet, Gitea's API returns 404 for that endpoint.
curl -ffailson the 404, produces empty stdout, and the downstream
python3 -c 'json.load(sys.stdin)'raisesJSONDecodeError-- crashing the guard. Since this guard runs before the first push, every newfeature branch's first push was blocked.
Fix
Capture the HTTP status via
curl -sS -w '\n%{http_code}'instead of relying oncurl -f:__BRANCH_ABSENT__, return 0. A branch that doesn't exist on the remote yet hasno in-flight pipeline, so the pre-push guard should treat this as "queue clear," not crash.
The caller checks for the
__BRANCH_ABSENT__sentinel and exits 0 with abranch not yet on remote -- queue clearmessage.ci-queue-wait.ps1had the identical bug (Invoke-RestMethodthrows on any non-2xx status,including 404, and the
catchblock unconditionally wrote an error and exited 1). Ported theequivalent fix there: the
catchblock now inspects the caught exception's HTTP status code andexits 0 with the same "queue clear" message on 404, while still failing closed on any other error.
Tests
Added
packages/mosaic/framework/tools/git/test-ci-queue-wait-branch-absent.sh, a self-containedregression harness (curl stubbed) covering:
logged as before).
Verified red-first: run against the unpatched script, case 1 crashes with an uncaught
json.decoder.JSONDecodeErrortraceback and exits 1. Restoring the fix turns all 3 cases green.Wired into
packages/mosaic/package.json'stest:framework-shellscript, alongside the existinggit-wrapper regression tests, so it runs as part of
pnpm test.Quality gates
shellcheckon both changed/added shell files: clean except a pre-existing informationalSC1091(not-following a sourced sibling script) that is also present on the unmodifiedoriginal file.
pwsh -NoProfileparser check on the.ps1file: no parse errors.pnpm --filter @mosaicstack/mosaic run test:framework-shell: all green, including the new test.pnpm --filter @mosaicstack/mosaic run lint: clean.pnpm typecheck(full monorepo via turbo): all 42 tasks green.pnpm format:check: clean for every file this PR touches.Incidental
Bundled as a separate commit: fixes pre-existing #868 README prettier drift
(
packages/mosaic/framework/tools/orchestrator/README.md) to satisfy the repo-wide mandatorypre-push format gate (
pnpm typecheck && pnpm lint && pnpm format:check), which currently failson
origin/mainas-is regardless of this PR. Whitespace/table-alignment only, viaprettier --write-- no content change. Kept as its own commit so it no-ops cleanly once #868'sown fix lands on
main.Upstreams Mos host-local tooling-patch kit (2026-07-23), Patch 3.
Closes #872
gitea_get_branch_head_sha() looked up a branch's head SHA via `curl -fsSL .../branches/<branch>`. For a branch not yet pushed to the remote, Gitea returns 404, curl -f fails, stdin is empty, and the downstream `json.load` raises JSONDecodeError -- crashing the guard. Since ci-queue-wait.sh is a mandatory pre-push check, every new feature branch's first push was blocked. Capture the HTTP status via `curl -sS -w '\n%{http_code}'`: - 404 -> echo __BRANCH_ABSENT__, return 0 (no in-flight pipeline on a branch that doesn't exist yet -- queue is clear). - non-200 -> return 1 (still fail-closed on a genuine API error). - 200 -> parse the JSON as before (existing-branch behavior unchanged). The caller checks for the __BRANCH_ABSENT__ sentinel and exits 0 with a "branch not yet on remote -- queue clear" message. ci-queue-wait.ps1 had the same bug (Invoke-RestMethod throws on any non-2xx, including 404, and the catch block exited 1) -- ported the equivalent fix there via the caught exception's HTTP status code. Adds a red-first regression harness (test-ci-queue-wait-branch-absent.sh) covering: 404 branch-absent -> queue clear; 200 existing branch with a terminal CI state -> unchanged behavior; 500 genuine API error -> still fail-closed. Verified failing against the unpatched script (crashes with JSONDecodeError) and passing after the fix. Wired into package.json's test:framework-shell alongside the existing git-wrapper regression tests. Upstreams Mos host-local tooling-patch kit (2026-07-23), Patch 3.Gate-16 APPROVE -- stamped by Mos (id-11)
Registered under the distinct Mos bot identity (id-11) for cryptographic author!=reviewer separation on PR #874: PR author jason.woltje (id2) != approver Mos (id11). Registers the finalized verdict of the independent reviewer (fresh checkout, diff re-derived, adversarial); MS-LEAD prepared/relayed the RoR, Mos stamps+merges (MS-LEAD never touches id-11).
VERDICT: APPROVE @
23cbdaf8df(Closes #872).Finding-0 (commit-author metadata): both PR commits carry local git author/committer ms-lead-reviewer reviewer@mosaic.local (shared-checkout config used by all fleet subagents). The independent reviewer confirmed via the Gitea commit API that this resolves to author:null / committer:null (NO linked account) and verification.verified:false (unsigned) -- inert, unauthenticated local metadata, NOT a credential and never the load-bearing signal. The load-bearing Gate-16 separations HOLD: authenticated PR-author jason.woltje (id2) != authenticated approver Mos (id11); process independence is real (distinct adversarial subagents; this chain surfaced real defects incl. the C1 exports bug, the destructive test, and Finding-0 itself). Durable hygiene fix (c) tracked.
Independent review -- all 8 criteria PASS: (1) fix correctness 404->BRANCH_ABSENT/exit0, non-200 fail-closed; (2) PowerShell .ps1 parity; (3) red-first test reproduced + wired into test:framework-shell; (4) README chore whitespace-only; (5) scope tight; (6) firewall clean; (7) open/mergeable/CI green wp1974; (8) gates green.
6-CHECK re-verified by Mos @23cbdaf8df28fc6bcb894347feeaaea2d48a410b: open/not-merged/mergeable/base main; CI combined=success @exact head; reviewed==CI==merge head (full-40); independent APPROVE author!=reviewer no REQUEST-CHANGES; body Closes #872; queue-guard clear.