CI/CD Integration with Claude Code
Learning Objectives
- Use Claude Code in GitHub Actions workflows
- Build auto-lint-fix and PR review bots
- Configure headless mode safely for CI
- Use /install-github-app for native integration
Claude in Your Pipeline
Claude Code's headless mode makes it a natural fit for CI/CD pipelines. It can review PRs, fix lint errors, generate documentation, and run quality checks — all automatically, triggered by events in your repository.
The key principles for CI integration:
1. API key auth — browser auth doesn't work in headless environments
2. Restricted tools — limit what Claude can do in CI
3. Max turns — prevent runaway loops
4. Focused tasks — one specific job per Claude invocation
GitHub Actions: Basic Setup
Step 1: Store Your API Key
Go to your repository's Settings > Secrets and variables > Actions. Add a secret:
- Name:
ANTHROPIC_API_KEY - Value: Your Anthropic API key
Step 2: Create a Workflow
Create .github/workflows/claude-review.yml:
name: Claude Code Review
on:
pull_request:
branches: [main, develop]
jobs:
review:
runs-on: ubuntu-latest
steps:
- name: Checkout
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: Review PR
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude -p "Review the changes in this PR. Check for:
1. Security vulnerabilities
2. Missing error handling
3. Performance issues
4. Test coverage gaps
Output a markdown report with findings." \
--output-format text \
--max-turns 15 \
--allowedTools "Read" "Bash(git diff )" "Bash(git log )" \
> review-report.md
- name: Post Review Comment
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const review = fs.readFileSync('review-report.md', 'utf8');
if (review.trim()) {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: ## Claude Code Review\n\n${review}
});
}
This workflow:
1. Triggers on every PR to main/develop
2. Installs Claude Code
3. Runs a headless review with restricted tools
4. Posts the review as a PR comment
Auto-Lint-Fix Workflow
Automatically fix lint errors when a PR is opened:
name: Claude Auto-Fix
on:
pull_request:
branches: [main]
jobs:
auto-fix:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
- name: Setup
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Dependencies
run: npm ci && npm install -g @anthropic-ai/claude-code
- name: Run Lint Check
id: lint
run: |
npx eslint src/ --format json > lint-results.json 2>/dev/null || true
if [ -s lint-results.json ]; then
echo "has_errors=true" >> $GITHUB_OUTPUT
fi
- name: Fix Lint Errors with Claude
if: steps.lint.outputs.has_errors == 'true'
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude -p "Fix all lint errors found in lint-results.json.
Read each file with errors and fix them.
Only fix lint errors, don't refactor or change behavior." \
--max-turns 20 \
--allowedTools "Read" "Write(src/*)" "Bash(npx eslint )"
- name: Commit Fixes
run: |
git config user.name "Claude Code Bot"
git config user.email "claude@bot.noreply.github.com"
git add -A
git diff --cached --quiet || git commit -m "fix: auto-fix lint errors (Claude Code)"
git push
Auto-Generate Changelog
Generate a changelog entry when a release tag is pushed:
name: Generate Changelog
on:
push:
tags:
- 'v*'
jobs:
changelog:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: Generate Changelog
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^)
git log $PREV_TAG..HEAD --oneline | claude -p \
"Create a changelog entry for ${GITHUB_REF_NAME}.
Group by: Features, Bug Fixes, Performance, Other.
Format as markdown. Be concise." \
--max-turns 1 > changelog-entry.md
- name: Create GitHub Release
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const body = fs.readFileSync('changelog-entry.md', 'utf8');
await github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: process.env.GITHUB_REF_NAME,
name: Release ${process.env.GITHUB_REF_NAME},
body: body
});
Native GitHub App Integration
For the most seamless experience, use the official Claude GitHub App:
# In a Claude Code session
/install-github-app
This installs the app on your repository and enables:
- Automatic PR reviews when PRs are opened
- Inline code comments on specific lines
- Check runs integrated with GitHub's status checks
- Review requests and approvals
The GitHub App is more deeply integrated than a custom workflow and handles authentication automatically.
Security Best Practices for CI
Restrict Tools
Always use --allowedTools in CI:
# Read-only analysis
--allowedTools "Read" "Bash(git diff )" "Bash(git log )"
# Lint fix (needs write access to src/ only)
--allowedTools "Read" "Write(src/*)" "Bash(npx eslint )"
# Never allow in CI:
# Bash(rm ), Bash(curl ), Bash(sudo ), Write(.github/*)
Limit Turns
Always set --max-turns:
--max-turns 15 # For most tasks
--max-turns 5 # For simple analysis
--max-turns 30 # For complex refactoring (use sparingly)
Protect Secrets
- Store API keys in GitHub Secrets, never in workflow YAML
- Don't log Claude's output if it might contain sensitive information
- Use
--allowedToolsto prevent Claude from reading .env files
Cost Management
CI runs can be expensive if unchecked:
- Set
--max-turnsto prevent runaway usage - Use Sonnet (not Opus) for CI tasks — it's cheaper and fast enough
- Run Claude only on meaningful events (PR opened, not every push)
- Monitor API usage to catch unexpected spikes
Key Takeaway
Claude Code integrates with CI/CD through headless mode (-p) and API key authentication. Use GitHub Actions to automate PR reviews, lint fixes, and changelog generation. Always apply three safety measures in CI: --allowedTools (restrict capabilities), --max-turns (prevent loops), and GitHub Secrets (protect keys). For the deepest integration, use /install-github-app for native GitHub review features. CI with Claude is powerful but requires careful guardrails.