Claude Code GitHub Actions Setup Guide (2026): PR Reviews Without Surprise API Bills
Claude Code inside GitHub Actions is one of those ideas that sounds obvious once you see it working. A reviewer asks a question on a pull request, tags @claude, and the bot reads the diff, checks the repo, and answers with context. For small teams, that's faster than building a custom review bot. For bigger teams, it's a nice way to automate the boring first pass.
But setup matters. A sloppy install gives you two kinds of pain: repo permissions that are wider than they need to be, and billing that does not work the way people assume it does. This guide covers the safe path: install the GitHub app, pick the right auth method, wire a minimal workflow, then tighten it before you let the bot loose on production repos.
When the official Claude Code action is the right tool
The official anthropics/claude-code-action is best when you want Claude to live inside GitHub's event model instead of building your own webhook service. It can respond to issue comments, PR review comments, labels, and assignments. That makes it good for:
- Interactive PR help with
@claude - First-pass code review on every new diff
- Issue triage and labeling
- Scheduled maintenance prompts for docs, tests, or repo hygiene
If your team needs a pure OpenAI-compatible pipeline or multi-model routing across GPT, Claude, and Gemini, a normal GitHub Action that calls an API directly is still cleaner. More on that in a minute.
Pick your auth method before you write YAML
This is the decision most people skip, and it's the one that causes the mess later.
| Auth mode | Best for | Secret name | Main gotcha |
|---|---|---|---|
| Claude Code OAuth | Teams already using Claude Code, Pro, or Max | CLAUDE_CODE_OAUTH_TOKEN | Needs token setup from a local Claude install |
| Anthropic API key | Budgeted automation and server-side billing | ANTHROPIC_API_KEY | Every run is pay-per-token |
| Bedrock / Vertex | Enterprise cloud governance | Cloud credentials | More setup, but better policy control |
My opinion: if you're experimenting and you already use Claude Code day to day, start with OAuth. If you're building a predictable CI budget for a team, use an API key on purpose and treat it like any other metered service.
For OAuth, generate the token locally first:
claude setup-token
Then store it in GitHub Actions secrets. If you prefer CLI setup, GitHub's own secret tooling is faster than clicking through the UI:
gh secret set CLAUDE_CODE_OAUTH_TOKEN < token.txt
Minimal setup: interactive @claude replies on PRs
First install the Claude GitHub app on the repository. Then drop in a small workflow. This is the easiest useful setup because it stays dormant until somebody explicitly asks Claude for help.
name: Claude Assistant
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned, labeled]
jobs:
claude-response:
runs-on: ubuntu-latest
permissions:
contents: write
issues: write
pull-requests: write
steps:
- uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
trigger_phrase: "@claude"
claude_args: |
--max-turns 6
That one detail, --max-turns 6, matters more than people think. Unlimited agent loops are not a badge of seriousness. They're how you wake up to a bloated invoice or a PR full of over-eager edits.
Automatic PR review without asking in comments
If you want Claude to review every PR automatically, use the prompt input. Keep the prompt narrow. Generic prompts create generic review noise.
name: Claude PR Review
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: |
Review this PR for:
- security regressions
- missing tests
- breaking API changes
- obviously dead code
Be concise. Quote the exact file and line context when possible.
use_sticky_comment: true
claude_args: |
--max-turns 4
This pattern is better than telling Claude to "review everything thoroughly." You're not hiring a philosopher. You're asking for a useful reviewer who points at real risk.
Permissions worth tightening before you forget
The action can work with the official Claude GitHub app, or with a custom GitHub app if your org has stricter rules. For public repos, stricter is better.
- Give write access only where Claude truly needs it. Review-only jobs often don't need
contents: write. - Do not allow broad bot triggering unless you trust every bot in the repo. The
allowed_botssetting exists for a reason. - Only grant
additional_permissionsif Claude needs workflow results or other extra context. - If your org blocks third-party apps, generate a token with your own GitHub app and pass it as
github_token.
The official docs are pretty good here, but the practical rule is simple: start with the smallest permission set that lets the workflow do its job, then expand only after a failure tells you what is missing.
The 2026 billing trap: OAuth is not the same as API key usage
This part deserves blunt wording. People are mixing up Claude subscriptions, Claude Code OAuth, and raw Anthropic API billing. They are not the same thing.
In March 2026, one developer publicly reported more than $1,800 in charges after following a claude -p workflow that inherited ANTHROPIC_API_KEY from the shell. The key point was not the exact number. The point was the confusion: they thought they were operating inside a Claude subscription workflow, but the run was billing an API account.
Rule of thumb: if you set ANTHROPIC_API_KEY, assume the meter is running. If you want subscription-style Claude Code usage, stay on the OAuth path and keep your automation design consistent.
Three simple ways to avoid pain:
- Use separate secrets for experimentation and production. Never reuse a personal key in CI.
- Cap turns. Agentic review is useful; agentic wandering is expensive.
- Start with interactive triggers like
@claudebefore enabling every-PR automation.
When the official action is not enough
Sometimes you don't actually want the official action. Sometimes you want a normal GitHub workflow that calls a model, returns structured JSON, and moves on. That's especially true when you want multi-model routing or you already standardised on an OpenAI-compatible stack.
For example, you might keep Claude Code for interactive PR help, but run a nightly multi-model regression summary through KissAPI because the rest of your CI already speaks the OpenAI format. In that case, a tiny Node.js script is often simpler than bending the official action into a shape it wasn't built for:
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.KISSAPI_API_KEY,
baseURL: "https://api.kissapi.ai/v1"
});
const result = await client.chat.completions.create({
model: "gpt-5",
messages: [
{ role: "system", content: "Summarize the risk in this diff for a release manager." },
{ role: "user", content: process.env.PR_DIFF }
]
});
console.log(result.choices[0].message.content);
That's not a replacement for Claude Code inside GitHub. It's the clean fallback when you want one API key for several models and don't need Claude's native GitHub interaction layer.
Need a simpler API layer for the rest of your CI?
Use KissAPI for the jobs that don't need the official Claude action. One OpenAI-compatible endpoint gives you access to Claude, GPT, and other models for custom GitHub workflows.
Start FreeThe setup I'd actually recommend
If I were setting this up for a real team today, I'd do it in this order:
- Install the GitHub app on one non-critical repo.
- Use OAuth first for interactive
@claudereplies. - Add
--max-turnsbefore adding any fancy automation. - Move to API-key-backed automation only after you've seen typical token usage.
- Keep custom multi-model jobs separate instead of forcing every use case through one action.
That's the sane path. It gives you the upside of Claude in PRs without turning your CI into a mysterious, expensive side project.