CodeIssuesPull RequestsActionsSecurityInsights
✨ AI
More
Settings

feat(api): list every workflow run in a repo, not one workflow at a time #5597

MergedXSccantynz wants to mergefeat/api-list-workflow-runsmainopened 1d ago
ccantynzcommented 1d ago

GET /api/v2/repos/:owner/:repo/actions/runs — the repo-wide list GitHub has had since 2018 and this API did not. Runs could be listed only per workflow, by filename.

That sounds like a small gap and isn't. Everything that watches CI from outside asks "what happened on this branch", not "what happened in ci.yml on this branch" — an agent polling a merge, a status badge, a deploy gate. Without it a client must list workflows, fan out one request per workflow, merge by hand, and still can't order results correctly across workflows.

This session hit it twice. A monitor was pointed at the missing endpoint and reported nothing, both times — the worse half of the bug, because a 404 that a polling loop reads as silence is indistinguishable from "still running". The run it was watching had finished twenty minutes earlier.

Filters

branch, head_sha, event, status, with per_page/page.

status deliberately keeps GitHub's quirk of accepting both lifecycle values (queued, in_progress) and conclusions (success, failure) against the two columns — that's what existing clients already send. Accepting half the vocabulary would be compatible in shape and useless in practice.

branch accepts a short name or a fully-qualified ref; prefixing an already-qualified ref would produce refs/heads/refs/heads/main and silently match nothing — an empty list that reads as "no runs on that branch" rather than as the bug it is.

Privacy

Same guard as the per-workflow list: this GET has soft auth only, so without it a private repo's entire CI history is world-readable. 404, not 403 — a 403 confirms the repo exists.

Testability

Query parsing is extracted as a pure function so its promises can be tested without a database. Two matter beyond tidiness:

  • per_page is clamped to 100. Unclamped it's a one-request timeout against a repo with a long CI history.
  • Malformed paging falls back to a usable page, never an empty one. An empty page is the dangerous failure — a client reads it as "no runs" and acts on that.

Also in this branch

The production verification of the sidecar runner merged in 859e3cb, recorded in docs/CI-ISOLATION-NEXT-INCREMENT.md — including one thing that document predicted wrongly. It said ls /data/repos in the runner would report No such file or directory. It doesn't: the directory exists in the image and is simply empty, because the git-repos volume isn't mounted over it. The property holds, but the stated test would have been read as a failure by whoever ran it. The mount list, not the directory listing, is the check.

Verified: runner PID 1 holds 11 variables (no DATABASE_URL, no ANTHROPIC_API_KEY, no GLUECRON_PAT, no WORKFLOW_SECRETS_KEY); the app's holds 30. Runner mounts ci-work only. mem=5 GiB, cpus=2, pids=512.

ccantynzAI Reviewcommented 1d ago

AI Triage

(no summary)

Priority: medium Risk area: mixed

Suggested labels: (no label suggestions) Suggested reviewers: (no reviewer suggestions)

Suggestions only — nothing has been applied. The PR author stays in control.

gluecron[bot]🤖 botAI Reviewcommented 1d ago

AI review unavailable

The platform's AI balance is exhausted, so AI generation is temporarily unavailable. Nothing was lost. You can queue this as a repair for the internal agent from the repository's Health page, or try again once the balance is restored. The PR is otherwise unchanged.

Cross-repo impact

See what breaks downstream if this PR merges.

Analyze →
⮌ Merged

This pull request was merged into main.

c comment · e edit title · m merge · a approve · r request changes · ? shortcuts