fix(ci): replace gh api REST passthroughs with Gitea-compatible shapes (#75 class D) #81

Closed
claude-ceo-assistant wants to merge 7 commits from fix/issue75-class-D-gh-api-to-gitea-rest into main

7 Commits

Author SHA1 Message Date
249d6897fa Merge branch 'main' into fix/issue75-class-D-gh-api-to-gitea-rest
Some checks failed
CI / Shellcheck (E2E scripts) (pull_request) Successful in 29s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 16s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 17s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 19s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 13s
CI / Canvas (Next.js) (pull_request) Failing after 2m3s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / Platform (Go) (pull_request) Failing after 2m50s
CI / Python Lint & Test (pull_request) Successful in 7m12s
Check merge_group trigger on required workflows / Required workflows have merge_group trigger (pull_request) Successful in 6s
CodeQL / Analyze (${{ matrix.language }}) (go) (pull_request) Successful in 7s
CodeQL / Analyze (${{ matrix.language }}) (javascript-typescript) (pull_request) Successful in 7s
CodeQL / Analyze (${{ matrix.language }}) (python) (pull_request) Successful in 7s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 16s
CI / Detect changes (pull_request) Successful in 17s
branch-protection drift check / Branch protection drift (pull_request) Successful in 22s
pr-guards / disable-auto-merge-on-push (pull_request) Successful in 11s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 20s
E2E API Smoke Test / detect-changes (pull_request) Successful in 21s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 18s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 19s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 19s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 21s
2026-05-08 02:46:43 +00:00
31d6debba8 Merge branch 'main' into fix/issue75-class-D-gh-api-to-gitea-rest
Some checks failed
Check merge_group trigger on required workflows / Required workflows have merge_group trigger (pull_request) Successful in 7s
CodeQL / Analyze (${{ matrix.language }}) (go) (pull_request) Successful in 7s
CodeQL / Analyze (${{ matrix.language }}) (javascript-typescript) (pull_request) Successful in 8s
CodeQL / Analyze (${{ matrix.language }}) (python) (pull_request) Successful in 8s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 15s
branch-protection drift check / Branch protection drift (pull_request) Successful in 19s
CI / Detect changes (pull_request) Successful in 18s
pr-guards / disable-auto-merge-on-push (pull_request) Failing after 9s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 15s
E2E API Smoke Test / detect-changes (pull_request) Successful in 17s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 17s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 17s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 18s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 19s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 7s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 14s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 8s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 9s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 8s
CI / Python Lint & Test (pull_request) Successful in 7m32s
CI / Canvas (Next.js) (pull_request) Failing after 8m50s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / Platform (Go) (pull_request) Successful in 12m57s
2026-05-08 01:27:48 +00:00
7ec87ee2c6 Merge branch 'main' into fix/issue75-class-D-gh-api-to-gitea-rest
Some checks failed
CI / Detect changes (pull_request) Successful in 16s
Check merge_group trigger on required workflows / Required workflows have merge_group trigger (pull_request) Successful in 6s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 14s
branch-protection drift check / Branch protection drift (pull_request) Successful in 18s
pr-guards / disable-auto-merge-on-push (pull_request) Failing after 7s
CodeQL / Analyze (${{ matrix.language }}) (go) (pull_request) Successful in 11s
CodeQL / Analyze (${{ matrix.language }}) (javascript-typescript) (pull_request) Successful in 10s
CodeQL / Analyze (${{ matrix.language }}) (python) (pull_request) Successful in 9s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 16s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 16s
E2E API Smoke Test / detect-changes (pull_request) Successful in 18s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 17s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 13s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 13s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 9s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 19s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 9s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 7s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 27s
CI / Python Lint & Test (pull_request) Successful in 7m32s
CI / Canvas (Next.js) (pull_request) Failing after 8m3s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / Platform (Go) (pull_request) Successful in 9m41s
2026-05-08 00:54:20 +00:00
2ab533af58 Merge branch 'main' into fix/issue75-class-D-gh-api-to-gitea-rest
Some checks failed
Check merge_group trigger on required workflows / Required workflows have merge_group trigger (pull_request) Successful in 6s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 13s
CodeQL / Analyze (${{ matrix.language }}) (go) (pull_request) Successful in 5s
branch-protection drift check / Branch protection drift (pull_request) Successful in 17s
CodeQL / Analyze (${{ matrix.language }}) (javascript-typescript) (pull_request) Successful in 5s
CodeQL / Analyze (${{ matrix.language }}) (python) (pull_request) Successful in 5s
CI / Detect changes (pull_request) Successful in 12s
pr-guards / disable-auto-merge-on-push (pull_request) Failing after 7s
E2E API Smoke Test / detect-changes (pull_request) Successful in 15s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 15s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 13s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 19s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 19s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 21s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 10s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 12s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 33s
CI / Python Lint & Test (pull_request) Successful in 7m33s
CI / Canvas (Next.js) (pull_request) Failing after 8m25s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / Platform (Go) (pull_request) Successful in 9m22s
2026-05-08 00:20:55 +00:00
e58d7c17ad Merge branch 'main' into fix/issue75-class-D-gh-api-to-gitea-rest
Some checks failed
CodeQL / Analyze (${{ matrix.language }}) (go) (pull_request) Successful in 3s
CodeQL / Analyze (${{ matrix.language }}) (javascript-typescript) (pull_request) Successful in 3s
Check merge_group trigger on required workflows / Required workflows have merge_group trigger (pull_request) Successful in 3s
CodeQL / Analyze (${{ matrix.language }}) (python) (pull_request) Successful in 3s
pr-guards / disable-auto-merge-on-push (pull_request) Failing after 4s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 11s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 13s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 13s
E2E API Smoke Test / detect-changes (pull_request) Successful in 13s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 13s
branch-protection drift check / Branch protection drift (pull_request) Successful in 15s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 15s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 14s
CI / Detect changes (pull_request) Successful in 18s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 11s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 11s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 12s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 18s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 19s
CI / Canvas (Next.js) (pull_request) Failing after 3m13s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / Platform (Go) (pull_request) Successful in 4m7s
CI / Python Lint & Test (pull_request) Successful in 7m11s
2026-05-07 23:39:26 +00:00
85aa3eb4a9 Merge branch 'main' into fix/issue75-class-D-gh-api-to-gitea-rest
Some checks failed
Check merge_group trigger on required workflows / Required workflows have merge_group trigger (pull_request) Successful in 5s
CodeQL / Analyze (${{ matrix.language }}) (go) (pull_request) Successful in 6s
CodeQL / Analyze (${{ matrix.language }}) (javascript-typescript) (pull_request) Successful in 7s
CodeQL / Analyze (${{ matrix.language }}) (python) (pull_request) Successful in 6s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 12s
branch-protection drift check / Branch protection drift (pull_request) Successful in 17s
pr-guards / disable-auto-merge-on-push (pull_request) Failing after 6s
CI / Detect changes (pull_request) Successful in 16s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 15s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 13s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 15s
E2E API Smoke Test / detect-changes (pull_request) Successful in 16s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 15s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 14s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 13s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 14s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 21s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 10s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 19s
CI / Python Lint & Test (pull_request) Successful in 8m2s
CI / Canvas (Next.js) (pull_request) Failing after 9m1s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / Platform (Go) (pull_request) Successful in 12m49s
2026-05-07 22:53:19 +00:00
aa6458b42d fix(ci): replace gh api REST passthroughs with Gitea-compatible shapes (#75 class D)
Some checks failed
Check merge_group trigger on required workflows / Required workflows have merge_group trigger (pull_request) Successful in 9s
CodeQL / Analyze (${{ matrix.language }}) (go) (pull_request) Successful in 8s
CodeQL / Analyze (${{ matrix.language }}) (javascript-typescript) (pull_request) Successful in 10s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 19s
CodeQL / Analyze (${{ matrix.language }}) (python) (pull_request) Successful in 10s
E2E API Smoke Test / detect-changes (pull_request) Successful in 21s
CI / Detect changes (pull_request) Successful in 31s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 20s
Retarget main PRs to staging / Retarget to staging (pull_request) Has been skipped
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 16s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 19s
Harness Replays / detect-changes (pull_request) Successful in 21s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 23s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 24s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 26s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 30s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 24s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 37s
Harness Replays / Harness Replays (pull_request) Successful in 23s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 15s
CI / Python Lint & Test (pull_request) Successful in 8m27s
CI / Canvas (Next.js) (pull_request) Failing after 9m59s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CI / Platform (Go) (pull_request) Successful in 12m57s
Part of the post-#66 sweep to remove `gh` CLI dependencies that fail
silently against Gitea (which exposes /api/v1 only — no GraphQL → 405,
no /api/v3 → 404). Class D covers `gh api` REST passthroughs that
either have a Gitea v1 equivalent at a different path/shape or no
equivalent at all.

Three files in this class, each with a different fix shape because
each underlying Gitea capability is different:

`auto-promote-on-e2e.yml` (compute SHA ancestry):
  Old: `gh api repos/.../compare/A...B` returning `.status`
       (ahead|behind|identical|diverged).
  Gitea: `/api/v1/repos/.../compare/A...B` accepts only branch / tag
       refs — full commit SHAs return `BaseNotExist`. So even a
       "translate the URL" rewrite would fail. Verified empirically
       2026-05-07: branches/tags work, SHAs don't.
  Fix:  Add `actions/checkout@v6 fetch-depth=200` + use `git merge-
       base --is-ancestor` locally. Exact same four-bucket semantics
       (ahead | behind | diverged | error), zero cross-host API
       dependency. Same pattern PR #66 used for auto-sync. The 200-
       commit depth comfortably covers any realistic divergence
       between :latest and a candidate retag (promotes are minutes
       apart, not hundreds of commits).

`ci.yml` (canvas-deploy-reminder commit comment):
  Old: `gh api -X POST repos/.../commits/{sha}/comments` posting a
       deploy-reminder body for the operator.
  Gitea: NO commit-comments endpoint exists — `/repos/.../commits/
       {sha}/comments` returns 404 (verified 2026-05-07). Gitea only
       exposes `/commits/{sha}/statuses` for commit-level surface,
       which is the wrong shape for a free-form reminder.
  Fix:  Drop the API call. Write the reminder body to
       `$GITHUB_STEP_SUMMARY` instead. The reminder is entirely
       operator-facing and is just as discoverable on the run summary
       page (which an operator naturally lands on when they need to
       action a deploy). Commit comments were a stale UI artefact of
       the GitHub era, not a load-bearing automation surface.
  Permission: drop `contents: write` (no longer needed) → `read`,
       smallest scope per least-privilege.

`check-merge-group-trigger.yml` (merge_group: trigger linter):
  Old: `gh api .../branches/staging/protection/required_status_checks`
       reading the contexts list, then walking workflow files.
  Gitea: branch-protection API is at /api/v1/repos/.../branch_
       protections/{name} (different path) with `status_check_
       contexts` (different field name) — but the entire workflow
       only existed to lint that workflows producing a required
       check declare a `merge_group:` trigger, which is needed
       because GitHub's merge queue dead-locks at AWAITING_CHECKS
       when the trigger is missing. Gitea has NO merge queue, NO
       gh-readonly-queue/... ref shape, NO merge_group event
       semantics. The dead-lock pattern this linter catches cannot
       occur on Gitea by construction.
  Fix:  Convert to no-op stub (same pattern as the CodeQL stub
       landed in PR #51). Workflow name + trigger surface preserved
       so any external referrer (none confirmed via the 2026-05-07
       branch-protection audit) keeps resolving. Re-enable path
       documented in the file header for if/when Gitea grows a
       merge queue.

curl invocation pattern: `curl --fail-with-body -sS` (NOT `-fsS` —
the two short-fail flags are mutually exclusive in modern curl).

Token model: workflows continue to use act_runner's GITHUB_TOKEN
where they still need API access (`auto-promote-on-e2e.yml`'s
checkout uses the runner's default token; `ci.yml` no longer needs
any API auth for the deploy-reminder step; `check-merge-group-
trigger.yml` no longer makes any API calls).

Verification:
- YAML syntax validates for all three files.
- Live curl against Gitea confirms `/compare/A...B` accepts branch
  refs (200, total_commits=N) and refuses full SHAs (404,
  BaseNotExist) — justifying the local-git approach.
- `/repos/.../commits/{sha}/comments` confirmed 404 on Gitea.
- `git merge-base --is-ancestor` exit-code semantics match the
  GitHub compare API status semantics exactly: ahead = current is
  ancestor of target; behind = target is ancestor of current;
  diverged = neither.

Closes part of #75. Class A landed in #80; class F (gh run list →
no Gitea workflow-runs API at all) lands in a separate PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 15:35:59 -07:00