GitHub Actions CI and AI Code Review¶
Archived 2026-10-07. This page existed only in the GitHub wiki (written 2026-06-24) and was moved here before the wiki started being generated from
docs/. Workflow names, secrets (UQO_E2E_*) and theclaude-cr.ymlreview job describe the repo as it was then; for current CI see CI-CD Pipeline Setup.
This page documents the repository's own GitHub Actions workflows under .github/workflows/ — the CI (automated test gates) and the CR (AI code review). For the consumer-facing CI wrappers shipped as products (the uqo GitHub Action / GitLab template, ghost mode, runner images), see CI-CD Pipeline Setup.
Workflow overview¶
| Workflow | File | Trigger | Purpose | Gating |
|---|---|---|---|---|
| Claude AI Code Review | claude-cr.yml |
PR opened/synchronize/reopened/ready_for_review |
AI review posting inline comments | Non-blocking (advisory) |
| pr-fast | pr-fast.yml |
every PR | Fast required test suite | Required |
| pr-heavy | pr-heavy.yml |
e2e-heavy label or manual dispatch |
Heavy optional E2E suite | Optional |
| nightly-external | nightly-external.yml |
cron 0 2 * * * + manual |
External lifecycle E2E | Scheduled |
| release-gate | release-gate.yml |
manual dispatch | External release gate | Release |
CR — Claude AI Code Review (claude-cr.yml)¶
Automatically reviews every pull request and posts inline review comments using Anthropic's official anthropics/claude-code-action@v1. No @claude mention is required — the absence of a trigger_phrase makes it run on all matching PR events.
How it works¶
- PR is opened or updated → workflow triggers.
- The action authenticates with a Claude Pro/Max subscription (OAuth token), checks out the diff, and runs Claude Code in agent review mode (
track_progress: true). - Claude reads the diff and posts a tracking comment plus inline comments on specific lines.
Review focus (prompt)¶
In priority order, the reviewer is instructed to flag:
1. Correctness / logic errors and edge cases.
2. Security flaws (injection, unsafe subprocess/shell use, secrets in code, unsafe deserialization, path traversal, SSRF).
3. Performance bottlenecks and resource leaks.
4. Missing or weak test coverage, mapped to the repo's tier_fast / tier_heavy / tier_external markers.
Pure stylistic formatting is explicitly out of scope.
Required setup¶
Add the repository secret CLAUDE_CODE_OAUTH_TOKEN (Settings → Secrets and variables → Actions). Generate it on a machine logged into a paid Claude subscription:
claude setup-token
Copy the resulting sk-ant-oat... token into the secret. GITHUB_TOKEN is auto-provided by GitHub.
Billing note: the Anthropic API Console (pay-as-you-go
ANTHROPIC_API_KEY) and a Claude Pro/Max subscription are separate wallets. This workflow intentionally uses the subscription via OAuth, so it consumes no API credits. Using an API key against a $0 console balance fails instantly with a401and no posted review.
Key configuration¶
permissions:
contents: read
pull-requests: write
id-token: write # required by the action for progress tracking
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
github_token: ${{ secrets.GITHUB_TOKEN }}
track_progress: true
claude_args: |
--allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)"
--max-turns 25
Two settings are essential for comments to actually appear:
- --allowedTools must include mcp__github_inline_comment__create_inline_comment — without it Claude has no way to post and the run ends with No buffered inline comments.
- --max-turns must be high enough to finish (a budget of 8 was exhausted before completion; 25 is comfortable for typical PRs).
Cost / noise guards¶
- Skips draft PRs and
dependabot[bot]. concurrencycancels an in-progress review when the PR is pushed again.- Reviews are advisory — they post comments but do not block merges.
Troubleshooting¶
| Symptom | Cause | Fix |
|---|---|---|
| Job green, no comment posted | Missing comment tool in --allowedTools |
Add mcp__github_inline_comment__create_inline_comment |
error_max_turns in logs |
--max-turns too low |
Raise the budget |
401 Invalid bearer token |
Bad/partial OAuth token | Re-run claude setup-token, re-set the secret |
is_error: true, total_cost_usd: 0, ~instant |
API key with $0 console balance | Switch to claude_code_oauth_token (subscription) |
| Need the exact error | Output hidden for security | Temporarily add show_full_output: true, re-run, then remove |
CI — Test gates¶
Tier selection is marker-driven (pytest -m) and shared with local and GitLab runs. See CI-CD Pipeline Setup for the full tier command reference.
pr-fast (pr-fast.yml) — required¶
Runs on every PR (all target branches), 12-minute timeout, Python 3.11.
python -m pytest -q -m "tier_fast and not quarantined" --maxfail=1 --no-cov
pr-heavy (pr-heavy.yml) — optional¶
Runs only when a PR is labeled e2e-heavy or via manual workflow_dispatch. 30-minute timeout.
python -m pytest -q -m "tier_heavy and not tier_external" --maxfail=1 --durations=25
nightly-external (nightly-external.yml) — scheduled¶
Cron 0 2 * * * (daily 02:00 UTC) plus manual dispatch. Runs the external lifecycle suite against real GitHub/GitLab targets. Uses the external-e2e concurrency group (no cancel-in-progress) so external runs never overlap.
python -m pytest -q -m "tier_external and cleanup_required" --maxfail=1 --durations=50
UQO_E2E_* secrets (GitHub/GitLab tokens, owner/group, base URL).
release-gate (release-gate.yml) — release¶
Manual workflow_dispatch only, 45-minute timeout. Same external suite as nightly, run as a deliberate pre-release gate. Shares the external-e2e concurrency group.
Shared conventions¶
- All test jobs upload diagnostics artifacts on failure (or always, for external suites):
.artifacts/e2e/**,**/*.log, summary JSON, API responses, and screenshots when present. - External suites are isolated under the
external-e2econcurrency group.
Secrets reference¶
| Secret | Used by | Purpose |
|---|---|---|
CLAUDE_CODE_OAUTH_TOKEN |
claude-cr.yml |
Claude subscription auth for AI review |
GITHUB_TOKEN |
all | Auto-provided by GitHub Actions |
UQO_E2E_GITHUB_TOKEN / UQO_E2E_GITHUB_OWNER |
nightly-external, release-gate | External GitHub E2E target |
UQO_E2E_GITLAB_TOKEN / UQO_E2E_GITLAB_GROUP_ID / UQO_E2E_GITLAB_BASE_URL |
nightly-external, release-gate | External GitLab E2E target |
Context & Links: - CI-CD Pipeline Setup — consumer-facing CI wrappers, ghost mode, runner images - QA Strategies, E2E Harness Operations Guide, Command Reference - Troubleshooting and Error Codes