Claude Code in GitHub Actions: Automate Code Review, Tests, and More
Install Claude Code in a GitHub Actions runner with 'npm install -g @anthropic-ai/claude-code', set ANTHROPIC_API_KEY from secrets, then run 'claude --headless --print "task"'. Use it for PR reviews, changelog generation, test fixes, and documentation updates.
GitHub Actions is the most common place to run Claude Code outside of local development. The combination is powerful: every PR can automatically get an AI review, every merge can generate a changelog entry, and every failing CI run can get a first-pass fix attempt — all without human intervention.
The setup is minimal. Any ubuntu-latest runner has Node.js pre-installed. Install Claude Code with npm, set your API key from repository secrets, and you are ready. The headless flag makes it non-interactive, and --print streams the output so you can capture it and use it in subsequent steps.
For PR review workflows, fetch the diff with git diff, pipe it to Claude with a focused prompt (review for security issues, check for missing tests, verify error handling), and post the result as a PR comment via the GitHub API or the github-script action. Keep the diff under 8,000 tokens to stay within context limits.
For more complex tasks like fixing failing tests, give Claude the test output and the relevant source files. Claude can read files, edit them, and run tests in the Actions runner just as it would locally — the tools work the same. Commit the fixes with 'git commit' and push to the PR branch.
Examples
name: Claude Code PR Review
on:
pull_request:
types: [opened, synchronize]
paths: ['src/**', 'lib/**']
jobs:
review:
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: read
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: Generate review
id: claude
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
DIFF=$(git diff origin/${{ github.base_ref }}...HEAD -- 'src/**' 'lib/**' 2>/dev/null | head -c 12000)
if [ -z "$DIFF" ]; then
echo "body=No relevant changes to review." >> $GITHUB_OUTPUT
exit 0
fi
PROMPT="You are a senior engineer reviewing a pull request. Review the following diff for: (1) bugs and logic errors, (2) security vulnerabilities, (3) missing error handling, (4) performance issues. Be specific and concise. Format as a markdown list.\n\n\`\`\`diff\n${DIFF}\n\`\`\`"
REVIEW=$(echo "$PROMPT" | claude --headless --print --max-turns 3 2>/dev/null)
{
echo 'body<<GHEOF'
echo "## Claude Code Review"
echo ""
echo "$REVIEW"
echo 'GHEOF'
} >> $GITHUB_OUTPUT
- name: Comment on PR
uses: actions/github-script@v7
if: steps.claude.outputs.body != ''
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `${{ steps.claude.outputs.body }}`
})name: Claude Auto-Fix Tests
on:
workflow_dispatch:
inputs:
branch:
description: 'Branch to fix'
required: true
jobs:
fix-tests:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.branch }}
token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/setup-node@v4
with: { node-version: '20' }
- run: npm ci
- name: Capture test failures
id: tests
run: |
npm test 2>&1 | tail -100 > /tmp/test-output.txt || true
echo "output=$(cat /tmp/test-output.txt | head -c 3000)" >> $GITHUB_OUTPUT
- name: Claude fixes tests
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude --headless --print --max-turns 20 \
"The test suite is failing. Here is the output:\n$(cat /tmp/test-output.txt)\nFix the failing tests. Read the relevant source files, understand the failures, and edit the test or source files to fix them. Run the tests after each fix to confirm."
- name: Commit fixes
run: |
git config user.name "Claude Code"
git config user.email "claude@anthropic.com"
git add -A
git diff --staged --quiet || git commit -m "fix: auto-fix failing tests via Claude Code"
git pushTips
- →Limit the diff passed to Claude to under 12,000 tokens (~9,000 words) to stay within context and keep costs low.
- →Use 'paths' filters in the workflow trigger to only run on changes to relevant files.
- →Set --max-turns to a low number (3-5) for review tasks and higher (20-30) for fix tasks that need iteration.
- →Cache node_modules in Actions runners to speed up Claude Code installation on repeated runs.
- →Add a 'concurrency' group to the workflow to cancel in-progress reviews when new commits are pushed.
FAQ
How much does running Claude Code in GitHub Actions cost?+
A typical PR review task (3-5 turns, ~5,000 tokens total) costs about $0.02-0.05 with Claude Sonnet. A test-fix task with 20 turns might cost $0.20-0.50. Set up spending limits in the Anthropic console and monitor with the usage dashboard.
Can Claude Code push commits back to the PR branch from Actions?+
Yes, with the right permissions. Set 'permissions: contents: write' in the job, checkout with a token that has write access, configure git user.name/email, and use 'git commit && git push'. Claude's file edits will be staged and committed like any other changes.
Is there an official Claude Code GitHub Action?+
Anthropic has published the claude-code-action on the GitHub Marketplace. It wraps the headless mode with common patterns (PR review, issue triage) and handles auth. Check the Anthropic GitHub organization for the latest version.