audit(ci): comprehensive gh-CLI → Gitea-REST sweep across workflows (post-#66) #75

Open
opened 2026-05-07 22:22:06 +00:00 by claude-ceo-assistant · 1 comment

Summary

Comprehensive sweep of gh CLI invocations across .github/workflows/ after the canonical SCM migration to Gitea (post-2026-05-06). PR #66 fixed the most-acute case (auto-sync main → staging) by replacing gh pr create with direct push. This issue tracks the rest.

Why

gh CLI is hardcoded against GitHub.com in two ways that both fail on Gitea:

  1. GraphQL paths (gh pr list/view/create/merge/diff, gh run list) → Gitea exposes no GraphQL endpoint, returns HTTP 405 Method Not Allowed (https://git.moleculesai.app/api/graphql).
  2. REST paths (gh api ...) → gh calls /api/v3/... (GitHub Enterprise REST shape), Gitea exposes /api/v1/. Setting GH_HOST=git.moleculesai.app does NOT help — the path mismatch is in gh source.

Confirmed empirically 2026-05-07:

GH_HOST=git.moleculesai.app gh pr list ...                       → HTTP 405 (graphql)
GH_HOST=git.moleculesai.app gh api repos/.../pulls               → HTTP 404 (api/v3)
curl -H token https://git.moleculesai.app/api/v1/repos/.../pulls → HTTP 200

Therefore: no gh subcommand currently works on this fleet. Workflows that call gh either fail noisily (the auto-sync case fixed in #66) or silently degrade (e.g. || echo "none/none" fallbacks treat every Gitea 405 as none/none → wrong gate decision).

Audit (excluding sister-agent work in flight)

EXCLUDED (sister agents): auto-sync-main-to-staging.yml (PR #66, done), auto-promote-staging.yml, retarget-main-to-staging.yml.

File Line gh shape Class
auto-promote-on-e2e.yml 172 gh run list --workflow=X --commit=SHA F
auto-promote-on-e2e.yml 338 gh api repos/.../compare/A...B D
auto-tag-runtime.yml 64 gh pr list --state merged --search SHA A
ci.yml 334 gh api -X POST repos/.../commits/SHA/comments D
check-merge-group-trigger.yml 54 gh api .../branches/X/protection/required_status_checks D
scripts/check-stale-promote-pr.sh 114, 177, 184 gh pr list/view/comment (called by auto-promote-stale-alarm.yml) A
scripts/ops/check_migration_collisions.py 103, 114 gh pr list/diff (called by check-migration-collisions.yml) A

Class plan (one PR per class)

  • PR-Agh pr ... calls in workflows + scripts. Replace with curl to /api/v1/repos/.../pulls.... Affected: auto-tag-runtime.yml, scripts/check-stale-promote-pr.sh, scripts/ops/check_migration_collisions.py.
  • PR-Dgh api REST passthroughs.
    • auto-promote-on-e2e.yml line 338: replace with curl /api/v1/repos/.../compare/A...B (endpoint exists in Gitea).
    • ci.yml line 334: Gitea has NO commit-comments API → drop the step, write the deploy-reminder body to GITHUB_STEP_SUMMARY instead. Operators read the run summary, not stale commit comments.
    • check-merge-group-trigger.yml: this workflow exists exclusively to lint that workflows producing required-status-checks declare merge_group: triggers. Gitea has no merge queue and no merge_group: event type. Convert to no-op stub (same pattern as PR #51 / CodeQL).
  • PR-Fgh run list → Gitea has NO workflow-runs API. Each workflow on Gitea Actions still emits a commit status. Replace with curl /api/v1/repos/.../commits/{SHA}/statuses + jq filter on context name. Affected: auto-promote-on-e2e.yml.

Acceptance criteria

  • All three PRs land independently (no cross-class dependency).
  • Each PR triggers a representative workflow ≥2 consecutive successful runs.
  • Hostile self-review weakest-3 documented per PR.
  • main stays 20/20 green throughout; PRs land via the same staging→main path.

Discussion-with-Hongming items

None blocking. The class designs are local to per-workflow edits + script edits; no org-wide config change (e.g. act_runner env, branch-protection whitelist) is needed.

## Summary Comprehensive sweep of `gh` CLI invocations across `.github/workflows/` after the canonical SCM migration to Gitea (post-2026-05-06). PR #66 fixed the most-acute case (auto-sync main → staging) by replacing `gh pr create` with direct push. This issue tracks the rest. ## Why `gh` CLI is hardcoded against GitHub.com in two ways that both fail on Gitea: 1. **GraphQL paths** (`gh pr list/view/create/merge/diff`, `gh run list`) → Gitea exposes no GraphQL endpoint, returns `HTTP 405 Method Not Allowed (https://git.moleculesai.app/api/graphql)`. 2. **REST paths** (`gh api ...`) → `gh` calls `/api/v3/...` (GitHub Enterprise REST shape), Gitea exposes `/api/v1/`. Setting `GH_HOST=git.moleculesai.app` does NOT help — the path mismatch is in `gh` source. Confirmed empirically 2026-05-07: ``` GH_HOST=git.moleculesai.app gh pr list ... → HTTP 405 (graphql) GH_HOST=git.moleculesai.app gh api repos/.../pulls → HTTP 404 (api/v3) curl -H token https://git.moleculesai.app/api/v1/repos/.../pulls → HTTP 200 ``` Therefore: **no `gh` subcommand currently works on this fleet**. Workflows that call `gh` either fail noisily (the auto-sync case fixed in #66) or silently degrade (e.g. `|| echo "none/none"` fallbacks treat every Gitea 405 as `none/none` → wrong gate decision). ## Audit (excluding sister-agent work in flight) EXCLUDED (sister agents): `auto-sync-main-to-staging.yml` (PR #66, done), `auto-promote-staging.yml`, `retarget-main-to-staging.yml`. | File | Line | gh shape | Class | |---|---|---|---| | `auto-promote-on-e2e.yml` | 172 | `gh run list --workflow=X --commit=SHA` | F | | `auto-promote-on-e2e.yml` | 338 | `gh api repos/.../compare/A...B` | D | | `auto-tag-runtime.yml` | 64 | `gh pr list --state merged --search SHA` | A | | `ci.yml` | 334 | `gh api -X POST repos/.../commits/SHA/comments` | D | | `check-merge-group-trigger.yml` | 54 | `gh api .../branches/X/protection/required_status_checks` | D | | `scripts/check-stale-promote-pr.sh` | 114, 177, 184 | `gh pr list/view/comment` (called by `auto-promote-stale-alarm.yml`) | A | | `scripts/ops/check_migration_collisions.py` | 103, 114 | `gh pr list/diff` (called by `check-migration-collisions.yml`) | A | ## Class plan (one PR per class) - **PR-A** — `gh pr ...` calls in workflows + scripts. Replace with `curl` to `/api/v1/repos/.../pulls...`. Affected: `auto-tag-runtime.yml`, `scripts/check-stale-promote-pr.sh`, `scripts/ops/check_migration_collisions.py`. - **PR-D** — `gh api` REST passthroughs. - `auto-promote-on-e2e.yml` line 338: replace with `curl /api/v1/repos/.../compare/A...B` (endpoint exists in Gitea). - `ci.yml` line 334: Gitea has NO commit-comments API → drop the step, write the deploy-reminder body to `GITHUB_STEP_SUMMARY` instead. Operators read the run summary, not stale commit comments. - `check-merge-group-trigger.yml`: this workflow exists exclusively to lint that workflows producing required-status-checks declare `merge_group:` triggers. Gitea has no merge queue and no `merge_group:` event type. Convert to no-op stub (same pattern as PR #51 / CodeQL). - **PR-F** — `gh run list` → Gitea has NO workflow-runs API. Each workflow on Gitea Actions still emits a commit status. Replace with `curl /api/v1/repos/.../commits/{SHA}/statuses` + jq filter on context name. Affected: `auto-promote-on-e2e.yml`. ## Acceptance criteria - All three PRs land independently (no cross-class dependency). - Each PR triggers a representative workflow ≥2 consecutive successful runs. - Hostile self-review weakest-3 documented per PR. - main stays 20/20 green throughout; PRs land via the same staging→main path. ## Discussion-with-Hongming items None blocking. The class designs are local to per-workflow edits + script edits; no org-wide config change (e.g. act_runner env, branch-protection whitelist) is needed.
Author
Owner

Status update — all 3 class PRs filed

  • Class Agh pr list / view / diff / comment → Gitea v1 REST

    • PR: #80#80
    • Files: auto-tag-runtime.yml, scripts/check-stale-promote-pr.sh, scripts/ops/check_migration_collisions.py
    • First CI run: 24/24 SUCCESS. Second consecutive run armed via empty trigger commit (chore: 2nd verification trigger).
  • Class Dgh api REST passthroughs (3 different fix shapes per file)

    • PR: #81#81
    • Files: auto-promote-on-e2e.yml (compare → local git), ci.yml (commit-comment → step summary), check-merge-group-trigger.yml (no-op stub — Gitea has no merge queue)
    • First CI run: in progress
  • Class Fgh run list → Gitea commit-status query

    • PR: #83#83
    • Files: auto-promote-on-e2e.yml (E2E gate)
    • First CI run: in progress

Empirical confirmations (2026-05-07)

  • GH_HOST=git.moleculesai.app gh pr list ... → HTTP 405 (graphql)
  • gh api repos/.../pulls → HTTP 404 (gh CLI hits /api/v3, Gitea is /api/v1)
  • Direct curl /api/v1/repos/.../pulls → HTTP 200
  • Gitea swagger: 0 endpoints under /repos/.../actions/runs — no workflow-runs API
  • Gitea /api/v1/repos/.../compare/A...B accepts branch/tag refs but returns BaseNotExist for full commit SHAs
  • Gitea has no /repos/.../commits/{sha}/comments endpoint at all
  • Gitea Actions DOES emit per-job commit statuses with context "<Workflow Name> / <Job Name> (<event>)" — usable as substitute for workflow-run state queries

No follow-up needed before merging

No discuss-with-Hongming items surfaced. None of the fixes required org-wide config changes (e.g. act_runner env, branch-protection whitelist) — all changes are local to per-workflow edits + script edits.

## Status update — all 3 class PRs filed - **Class A** — `gh pr list / view / diff / comment` → Gitea v1 REST - PR: #80 → https://git.moleculesai.app/molecule-ai/molecule-core/pulls/80 - Files: `auto-tag-runtime.yml`, `scripts/check-stale-promote-pr.sh`, `scripts/ops/check_migration_collisions.py` - First CI run: 24/24 SUCCESS. Second consecutive run armed via empty trigger commit (chore: 2nd verification trigger). - **Class D** — `gh api` REST passthroughs (3 different fix shapes per file) - PR: #81 → https://git.moleculesai.app/molecule-ai/molecule-core/pulls/81 - Files: `auto-promote-on-e2e.yml` (compare → local git), `ci.yml` (commit-comment → step summary), `check-merge-group-trigger.yml` (no-op stub — Gitea has no merge queue) - First CI run: in progress - **Class F** — `gh run list` → Gitea commit-status query - PR: #83 → https://git.moleculesai.app/molecule-ai/molecule-core/pulls/83 - Files: `auto-promote-on-e2e.yml` (E2E gate) - First CI run: in progress ## Empirical confirmations (2026-05-07) - `GH_HOST=git.moleculesai.app gh pr list ...` → HTTP 405 (graphql) - `gh api repos/.../pulls` → HTTP 404 (gh CLI hits /api/v3, Gitea is /api/v1) - Direct `curl /api/v1/repos/.../pulls` → HTTP 200 - Gitea swagger: 0 endpoints under `/repos/.../actions/runs` — no workflow-runs API - Gitea `/api/v1/repos/.../compare/A...B` accepts branch/tag refs but returns `BaseNotExist` for full commit SHAs - Gitea has no `/repos/.../commits/{sha}/comments` endpoint at all - Gitea Actions DOES emit per-job commit statuses with context `"<Workflow Name> / <Job Name> (<event>)"` — usable as substitute for workflow-run state queries ## No follow-up needed before merging No discuss-with-Hongming items surfaced. None of the fixes required org-wide config changes (e.g. act_runner env, branch-protection whitelist) — all changes are local to per-workflow edits + script edits.
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: molecule-ai/molecule-core#75
No description provided.