Code review (GitHub Actions)
subak init scaffolds an automated code-review workflow into your repo that runs
Claude on every pull request. A fleet of agents
reviews the diff in the context of your codebase and posts findings as inline
comments on the exact lines. It runs in your own GitHub Actions and bills per
token against your Anthropic API key — no Claude subscription or managed plan
required.
Two files are written (skip-if-exists, so re-running init never clobbers your
edits):
| File | Purpose |
|---|---|
.github/workflows/code-review.yml | The workflow: triggers, permissions, and the review prompt. |
REVIEW.md | Review-only instructions injected as the highest-priority guidance every run. Tune what gets flagged here. |
Setup
The workflow needs one secret. Until it's set, the workflow no-ops with a warning rather than failing, so it's safe to commit immediately.
- Create an API key at console.anthropic.com.
- In your repo, go to Settings → Secrets and variables → Actions → New repository secret.
- Name it
ANTHROPIC_API_KEYand paste the key.
Open a pull request. Within a minute or two a Claude code review check run appears; findings land as inline comments on the diff.
Reviews run only on branches in the same repository — GitHub does not expose Actions secrets to pull requests from forks, so fork PRs are skipped.
What it does
- Reviews the current diff. Each push re-runs the review against the changes the PR introduces, not the whole repo.
- Posts inline comments, tagged by severity: 🔴 Important (a bug to fix before merge) and 🟡 Nit (minor). Findings include a ```suggestion block when a concrete fix fits, so you can commit it from the GitHub UI.
- Converges across pushes. It reads its own prior comments and won't re-post a finding that's still valid. When you fix a finding, GitHub automatically marks that thread Outdated and collapses it on the next run.
- Never blocks merges. Findings are advisory comments; the check run always completes neutrally.
Reviews complete in a couple of minutes for a small PR and cost roughly a few
cents to a few dollars depending on PR size and codebase complexity. Because the
workflow re-runs on every push, a concurrency group cancels an in-flight review
when you push again, and timeout-minutes bounds worst-case cost.
Tuning with REVIEW.md
REVIEW.md is plain markdown injected verbatim as the top-priority instruction
for every review. Common tunings:
- Recalibrate severity — state exactly what 🔴 Important means for your repo.
- Cap nit volume — e.g. "report at most 5 nits; summarize the rest as a count."
- Skip paths — generated code, lockfiles, vendored dependencies, or anything CI already enforces (lint, formatting, type errors).
- Repo-specific checks — e.g. "new API routes must have an integration test."
- Verification bar — require a
file:linecitation before a finding is posted.
Your repo's CLAUDE.md files are also read as project context; newly introduced
violations are flagged as nits. Keep REVIEW.md short — length dilutes the rules
that matter most.
Reviewer identity and thread resolution
By default the workflow authenticates with the built-in GITHUB_TOKEN, so
findings post as github-actions[bot]. Fixed findings auto-collapse as
Outdated on the next push, which — combined with the reviewer not re-posting
still-valid findings — keeps a re-reviewed PR focused on what's current. This is
enough for most teams and needs no extra setup.
Two independent upgrades are possible:
Post under your own identity (GitHub App)
Run the review under a GitHub App token so comments post under your App's name
(e.g. your-app[bot]) instead of github-actions[bot]. Install a GitHub App
with pull-requests: write on the repo, add its APP_ID and private key
(APP_PRIVATE_KEY) as secrets, and mint a token per run:
- name: Mint app token
id: app-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Review
if: steps.guard.outputs.skip != 'true'
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ steps.app-token.outputs.token }}
# …track_progress, prompt, claude_args as scaffolded…
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
Mark threads Resolved (requires a user token)
The green Resolved badge needs a user-flavored token — a fine-grained or
classic Personal Access Token with pull-requests: write. Neither the built-in
GITHUB_TOKEN nor a GitHub App installation token can run the
resolveReviewThread GraphQL mutation: GitHub rejects it as "Resource not
accessible by integration" for any App identity, regardless of granted scopes.
If you want fixed findings marked Resolved (not just Outdated), store a PAT as a
secret, expose it to the agent's gh calls (GH_TOKEN), and add a line to the
prompt telling the reviewer to resolve threads whose finding is gone via
resolveReviewThread (gh api graphql). Most teams skip this and rely on the
automatic Outdated collapse instead.
Triggering and re-running
The workflow triggers on opened, synchronize (each push), reopened, and
ready_for_review. To re-run without pushing, use the Re-run jobs button on
the workflow run, or push an empty commit.
To review a diff locally before opening a PR, run /code-review in a
Claude Code session — no workflow required.
Related
- Integrations & Automation — git hooks, MCP, and CI reporting.
- Validation — the structural gate that runs before code review adds value.