fix(ci): replace gh run list with Gitea commit-status query (#75 class F) #83
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "fix/issue75-class-F-gh-run-list-to-statuses"
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?
Summary
Class F of the post-#66 sweep tracked in #75: replace
gh run list --workflow=X --commit=SHAwith a Gitea commit-status query. One call site, one PR — Gitea has NO workflow-runs API at all.Why
gh run listhits/repos/.../actions/runs(GitHub Actions REST endpoint). Gitea exposes ZERO endpoints under/repos/.../actions/runs(verified 2026-05-07 via swagger inspection — only secrets / variables / runner-registration tokens live under/actions/). There is no way to query workflow run state via the Gitea v1 API directly.However, every Gitea Actions job emits a commit status with context =
"<Workflow Name> / <Job Name> (<event>)"(verified 2026-05-07 —/repos/.../commits/{sha}/statusesreturned 24 rows on a recent main SHA, all properly contextualised). That surface gives us exactly what we need: each workflow run leg is one status row, the aggregate state encodes the run outcome, and Gitea exposes it under/api/v1/repos/.../commits/{sha}/statuseswhich IS available.Files
auto-promote-on-e2e.ymllines 172-180gh run list --workflow e2e-staging-saas.yml --commit $SHAcurl /api/v1/repos/.../commits/$SHA/statuses+ jq filter on contexts whose name starts with"E2E Staging SaaS (full lifecycle) /"Mapping (preserves the 4 reachable buckets the original case statement handles)
none/nonein_progress/nonecompleted/failurecompleted/successThe
completed/cancelledarm of the case statement becomes unreachable: Gitea status API doesn't expose acancelledstate (it has success/failure/error/pending/warning). Per-SHA concurrency cancellations now surface asfailureand are handled by the failure branch. Documented in-place; arm kept as defense-in-depth.Test plan
none/none(E2E was paths-filtered for that change set — expected)none/nonein_progress/nonecompleted/successcompleted/failureHostile self-review — three weakest spots
name:field ine2e-staging-saas.yml, the jq prefix"E2E Staging SaaS (full lifecycle) /"silently stops matching → degenerates tonone/none→ auto-promote proceeds without the gate. Mitigation: comment in the workflow points at the prefix; rename PR will fail check-name-parity gate (#56) anyway because the same name is the gate context name in branch protection.cancelledsemantic: a legitimate per-SHA-concurrency cancel now reads asfailureand aborts. Acceptable on this fleet because cancels are rare (concurrency.cancel-in-progress isfalseon the relevant workflows) and operator can manually re-dispatch. If we measure cancel frequency > 1/week, revisit by parsing run-step-summary text via a follow-up.?limit=200or paginate explicitly when count approaches 100.Security + version impact
/commits/{sha}/statusesendpoint is repo-scoped; no extra permissions neededCloses part of #75
Companion PRs: #80 (class A —
gh pr ...), #81 (class D —gh api ...).🤖 Generated with Claude Code
Part of the post-#66 sweep to remove `gh` CLI dependencies that fail silently against Gitea. Class F covers `gh run list --workflow=X --commit=SHA` shapes — querying whether a specific workflow ran (and how it finished) for a specific SHA. Why this is the only call site in class F: `gh run list` hits GitHub's `/repos/.../actions/runs` REST endpoint. Gitea exposes ZERO endpoints under `/repos/.../actions/runs` — verified 2026-05-07 via swagger inspection: only secrets, variables, and runner-registration tokens live under /actions/. There's no way to query workflow run state via the Gitea v1 API directly. However, every Gitea Actions job DOES emit a commit status with `context = "<Workflow Name> / <Job Name> (<event>)"` (verified 2026-05-07 by reading /repos/.../commits/{sha}/statuses on a recent main SHA). That surface is exactly what we need: each workflow run leg is one status row, the aggregate state encodes the run outcome, and Gitea exposes it under `/api/v1/repos/.../commits/{sha}/statuses` which IS available. Affected: `auto-promote-on-e2e.yml` (lines 172-180): Old: `gh run list --workflow e2e-staging-saas.yml --commit $SHA --json status,conclusion --jq ...` returning a 5-bucket string like `completed/success` | `in_progress/none` | `none/none` | `completed/failure` | `completed/cancelled`. New: `curl /api/v1/repos/.../commits/$SHA/statuses` + jq filter on contexts whose name starts with `"E2E Staging SaaS (full lifecycle) /"`. Mapping: 0 matched contexts → "none/none" (E2E paths- filtered out — same as before) any context = pending → "in_progress/none" (defer) any context = error|failure → "completed/failure" (abort) all contexts = success → "completed/success" (proceed) The `completed/cancelled` arm of the case statement becomes unreachable: Gitea status API doesn't expose a `cancelled` state (it has success/failure/error/pending/warning), so per-SHA concurrency cancellations now surface as `failure` and are handled by the failure branch. Documented in-place; the cancelled arm is kept as defense-in-depth for any future dual-host operation. Verification: - Live curl against the current main SHA returns `none/none` (E2E was paths-filtered for that change set — expected). - Synthetic-input jq tests verify all four mapping buckets: no contexts → "none/none" one context = pending → "in_progress/none" success + success → "completed/success" success + failure → "completed/failure" - YAML syntax validates. Token: continues to use act_runner's GITHUB_TOKEN (per-run, repo read scope). The `/commits/{sha}/statuses` endpoint is repo-scoped, no extra perms needed. Closes part of #75. Master tracking issue at #75; companion PRs: #80 (class A — `gh pr ...`), #81 (class D — `gh api ...`). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>gh-CLI sweep class F (gh run list → /commits/{sha}/statuses query). auto-promote-on-e2e.yml E2E gate. 4 mapping buckets verified against synthetic+real Gitea data. 23/24 green, 0 failures. Mitigation for workflow-rename brittleness: PR #56's check-name parity gate already protects. Ready.