fix(ci): distinguish cancelled from failed lanes, add mass-cancellation detector metric (BLO-21078) - #977
Conversation
…w cancellation (BLO-21078) verify's summary used to report a cancelled upstream lane identically to a real test failure, so a GitHub-side runner kill presented to every PR author as their own diff breaking CI. Now it names cancelled lanes separately in the step summary and error output. Also adds paperclip_github_workflow_run_conclusion_total, a bounded counter on completed workflow_run webhook deliveries, as the numerator for a fleet-wide mass-cancellation detector (alert rule lands in a companion onprem-k8s PR).
|
🔗 Paperclip issue: BLO-21078 |
1 similar comment
|
🔗 Paperclip issue: BLO-21078 |
|
Hey @allyblockcast[bot]! Before this PR can be reviewed, a few things need attention: Missing or incomplete:
Once updated, push a new commit and these checks will re-run automatically. — commitperclip |
…lit (BLO-21078) The npmrc-devdeps-guard test asserted a literal `test "$WORKTREE_INSTALL_RESULT" = "success"` string in the verify job's bash, pinning the exact implementation this PR replaced with a cancelled/failed lane split. Update the assertions to check the guard's actual intent (worktree_install's result still gates verify) against the new case-statement shape instead of the old literal. Co-Authored-By: Paperclip <noreply@paperclip.ing>
|
Hey @allyblockcast[bot]! Before this PR can be reviewed, a few things need attention: Missing or incomplete:
Once updated, push a new commit and these checks will re-run automatically. — commitperclip |
Ally — Consolidated PR ReviewLenses: pr-review-toolkit (code, tests, comments, errors, types) + gstack/review + native-codex. Important Issues (1)
Strengths
Recommended Action
This PR is authored by |
…nter (BLO-21078) Bounded counter (labeled only by conclusion) incremented once per completed workflow_run webhook delivery. Numerator for the mass-cancellation detector alert mirrored in Blockcast/onprem-k8s. Split out of PR #977, which also carried a pr.yml verify-summary rewrite that duplicated and would have regressed the skipped-lane handling already merged via #964 (BLO-20867) -- dropped that hunk here, kept only the metric. Co-Authored-By: Paperclip <noreply@paperclip.ing>
|
Superseded by #989. Split into a clean cut against current |
…nter (BLO-21078) Bounded counter (labeled only by conclusion) incremented once per completed workflow_run webhook delivery. Numerator for the mass-cancellation detector alert mirrored in Blockcast/onprem-k8s. Split out of PR #977, which also carried a pr.yml verify-summary rewrite that duplicated and would have regressed the skipped-lane handling already merged via #964 (BLO-20867) -- dropped that hunk here, kept only the metric. Co-Authored-By: Paperclip <noreply@paperclip.ing>
What
Two of BLO-21078's acceptance criteria, addressed independently:
1.
verify's summary now distinguishes cancelled from failed lanes (.github/workflows/pr.yml)Previously
verifywas a baretest "$X" = "success"chain — the first non-success result aborted the step with a generic exit code, sogh pr checksrendered a GitHub-side runner kill identically to a real test failure. Every affected PR author spent a cycle disproving a break they didn't cause (this literally happened during the 2026-08-02 19:34-19:57Z mass-cancellation incident this issue tracks).Now the step names each lane and its result, splits them into
cancelledvsfailedin both the step summary and the::error::annotations, and still fails the check either way (a cancelled lane still needs a re-run) -- but the reason is now visible without opening job logs.2.
paperclip_github_workflow_run_conclusion_total(server/src/services/metrics.ts,server/src/routes/github-webhook.ts)A new bounded Counter, incremented once per completed
workflow_runwebhook delivery, labeled only byconclusion(success/failure/cancelled/skipped/timed_out/action_required/neutral/stale/startup_failure/other). This is the numerator for the mass-cancellation detector alert rule (companion PR inBlockcast/onprem-k8s, since that's where this cluster's actually-firing Prometheus rules live -- see that repo'smonitoring/prometheus-configmap.yamlheader).Deliberately excludes repo/workflow-name/PR labels to keep cardinality fixed -- this counter's whole job is "how many terminal runs of each kind arrived recently," which
increase(...{conclusion="cancelled"}[window])answers without them.Why
Investigation on BLO-21078 found the reported "19:13-19:31Z window" framing was wrong -- the actual kill instants cluster in three separate waves (19:34:01-23Z, 19:36:12-18Z, 19:56:36-19:57:02Z) regardless of when each job had started, and post-cleanup steps completing after the cancelled step ruled out an ARC/k8s runner death (GitHub-side graceful cancellation instead). Full writeup on the issue. The incident had zero metric surface -- this PR is the fix for that gap, plus the verify-summary fix so the next occurrence doesn't cost every affected author a debugging cycle.
Test plan
npx tsc --noEmitonserver/-- 0 new errors (confirmed against baseline viagit stash, 39 pre-existing unrelated errors before and after)npx vitest run server/src/__tests__/metrics-service.test.ts-- 50/50 pass, including 4 new tests for the counter (registration, bounded-label normalization, accumulation, unknown-conclusion collapse)node deploy/helm/paperclip/tests/prometheus-rule.test.mjs-- 5/5 pass (chart still renders valid YAML with the mirrored alert added)verifyagainst all-success / all-cancelled / mixed-failure-and-cancelled / skipped-dependency scenariosgithub-webhook.test.tsintegration suite (embedded-postgres-backed) -- did not complete in the sandbox within a reasonable timeout; relying on CI for that pass🤖 Generated with Claude Code