Skip to content

monitor-ci.sh branch-fallback can report a stale, unrelated run instead of the pushed commit's #38

Description

@jnasbyupgrade

Bug

monitor-ci.sh's branch-fallback (.claude/skills/ci/scripts/monitor-ci.sh:66-70) can silently report a stale, unrelated run as the result for the current push.

if [[ -z "$run_id" && -n "$branch" && ( -z "$sha" || $sha_wait -ge $SHA_INDEX_WAIT ) ]]; then
  # Only fall back to branch once the SHA wait window has elapsed (or no SHA given).
  # NOTE: this can pick up a different run if two pushes happen rapidly.
  run_id=$(gh run list --repo "$repo" --branch "$branch" \
    --event pull_request --limit 1 \
    --json databaseId --jq '.[0].databaseId // empty' 2>/dev/null || true)
fi

Once SHA_INDEX_WAIT (30s) elapses without GitHub having indexed a run for the
given sha, this falls back to "most recent run on the branch" with no
check that its headSha actually matches sha
. If the new push's CI run
hasn't started yet — not just "not indexed yet," but genuinely not scheduled
yet — this returns the previous commit's already-completed run and reports
it as PASS/FAIL for the current push.

The existing comment ("this can pick up a different run if two pushes happen
rapidly") undersells the risk: this isn't limited to rapid pushes. In
practice, GitHub Actions can take several minutes to even queue a pull_request
workflow run (observed ~8-15 min delay on Postgres-Extensions/pgxntool PR #60,
unrelated to the push itself — the run eventually appeared and passed). The
30s window is nowhere near enough headroom for that.

Impact

The script reported OVERALL: ALL_PASS three separate times for three
different pushes to the same PR/branch, all while actually just re-reporting
one earlier commit's stale run — because no new run existed yet for any of
those specific commits. This was only caught by manually cross-checking
headSha via gh api .../actions/runs against the pushed commit.

Suggested fix

When a sha is provided, the branch-fallback lookup should filter/verify
that the returned run's headSha equals sha (e.g. gh run list --repo "$repo" --branch "$branch" --json databaseId,headSha --jq '.[] | select(.headSha == "'"$sha"'") | .databaseId' first, before ever
accepting a bare "most recent run on branch" result). If no matching run is
found, keep waiting (up to timeout) rather than falling back to an
unrelated run at all.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions