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:

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 modeBest forSecret nameMain gotcha
Claude Code OAuthTeams already using Claude Code, Pro, or MaxCLAUDE_CODE_OAUTH_TOKENNeeds token setup from a local Claude install
Anthropic API keyBudgeted automation and server-side billingANTHROPIC_API_KEYEvery run is pay-per-token
Bedrock / VertexEnterprise cloud governanceCloud credentialsMore 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.

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:

  1. Use separate secrets for experimentation and production. Never reuse a personal key in CI.
  2. Cap turns. Agentic review is useful; agentic wandering is expensive.
  3. Start with interactive triggers like @claude before 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 Free

The setup I'd actually recommend

If I were setting this up for a real team today, I'd do it in this order:

  1. Install the GitHub app on one non-critical repo.
  2. Use OAuth first for interactive @claude replies.
  3. Add --max-turns before adding any fancy automation.
  4. Move to API-key-backed automation only after you've seen typical token usage.
  5. 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.