koala73 / koala73/worldmonitor
ci(deploy-gate): gate run exits 1 while required jobs are still pending — transient red on rapid merge trains
- Dominant language
- TypeScript
- Stars
- 86.6k
- Forks
- 13.1k
- Avg merge
- 8h 4m
- Merged PRs (30d)
- 825
Description
## Symptom
During the 7-PR merge train on 2026-07-05 (~15:37–15:38 UTC, head `6c48a33c`), one Deploy Gate run went red while 37 sibling gate runs at the **same SHA** succeeded:
- Failing run: https://github.com/koala73/worldmonitor/actions/runs/28745990841 (workflow_run trigger, 15:40:06 UTC)
- Failed step: `Check required PR gates passed for this SHA`
## Evidence from the run log
```
changes=success docs-stats=success unit=pending sidecar=pending convex-tests=pending variant-smoke-full=pending resilience-validation-smoke=pending digest-image=pending typecheck=pending biome=success security-audit=pending
pending=unit,sidecar,convex-tests,variant-smoke-full,resilience-validation-smoke,digest-image,typecheck,security-audit
##[error]Process completed with exit code 1.
```
8 of the 11 required jobs were still `pending` — nothing had failed — yet the step exited 1.
## Why this looks like a bug
The gate script's visible pending-branch sets a `pending` commit status and then `exit 0`:
```
if [ -n "$pending" ]; then
--field state="pending" \
--field description="Waiting for required PR gates: $pending"
exit 0
```
But the observed run printed the `pending=` line and then exited **1**, turning a normal in-progress state into a red workflow run. Note the python status block also computes `failed=` as "not in (success, skipped)", which classifies pending jobs as failed — the failure path may be evaluating before/instead of the pending short-circuit, or the `gh api` status-post in the pending branch may itself be failing and taking the step down with it.
## Impact
Low — later gate evaluations at the same SHA go green, so the final verdict is correct. But every rapid merge train leaves a red ✗ run in the Actions history that has to be manually distinguished from a real gate failure.
## Suggested fix
Reproduce by inspecting the failing run's full log to identify which branch actually exited 1, add a test/guard so the pending path always exits 0 (and posts the pending status best-effort), and confirm the `failed=` computation excludes `pending` jobs.
Found during the 2026-07-05 backlog triage session.
Contributor guide
Research direction
Start with the failing workflow_run at Actions run 28745990841 and inspect the full log around the `pending=` output and failed step. Trace the gate script's pending branch and its Python status block, then add a guard or test so pending jobs are not classified as failed and the pending path exits successfully while posting status best-effort.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github-actions, python, shell
- Domain
- ci-cd
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100