The Complete Guide to Claude Code CI/CD Integration: From Local Dev to Automated Pipelines
Introduction
Throughout this series, CI/CD has kept popping up — the testing guide touched on test automation, and the Git guide covered CI as part of the PR workflow. But no post has systematically addressed: how to embed Claude Code into your CI/CD pipeline so it works even when you're not around.
During local development, Claude Code is your pair programming partner. But its capabilities go far beyond that — through Headless mode and GitHub Actions integration, it becomes your team's 24/7 automated collaborator: auto-reviewing PRs, auto-fixing lint errors, even generating PRs directly from issues.
This post covers Claude Code's CI/CD capabilities thoroughly.
Why Use Claude Code in CI/CD
Manual Code Review vs Claude Code Automated Review
| Dimension | Manual Code Review | Claude Code Auto Review |
|---|---|---|
| Response time | Waiting for reviewer availability (hours to days) | Minutes after PR creation |
| Coverage | Limited by reviewer energy and expertise | Systematically checks all changed files |
| Consistency | Varies by person, inconsistent standards | Follows unified rules in CLAUDE.md |
| Availability | Working hours, timezone constraints | 24/7 around the clock |
| Cost | Senior engineer time | API call fees (usually lower) |
| Depth | Understands business context | Excels at finding pattern issues and potential bugs |
Note: Claude Code isn't meant to replace human code review — it's the first line of defense. It quickly catches obvious issues, letting human reviewers focus on architecture decisions and business logic.
Where Claude Code Fits in the Pipeline
Code push
↓
CI triggers (lint, tests, build)
↓
Claude Code auto review ← First line of defense
↓
Human code review ← Focus on architecture and business
↓
Merge
↓
CD deploy
Claude Code works best after CI checks but before human review. This way it reviews code that's already passed basic checks, resulting in higher quality reviews.
Headless Mode Basics
To use Claude Code in CI/CD, the core is Headless mode — no interactive terminal needed, everything runs through CLI arguments and pipes.
Core Parameters
| Parameter | Description | Example |
|---|---|---|
-p, --print | Non-interactive mode, outputs result directly | claude -p "analyze this code" |
--output-format | Output format: text, json, stream-json | claude -p --output-format json "..." |
--max-turns | Limit agent loop iterations, prevent runaway | claude -p --max-turns 10 "..." |
--model | Specify model | claude -p --model claude-sonnet-4-6 "..." |
--allowedTools | Whitelist: only allow specified tools | claude -p --allowedTools "Read,Grep,Glob" "..." |
--disallowedTools | Blacklist: block specified tools | claude -p --disallowedTools "Bash,Write" "..." |
--permission-mode | Permission mode | claude -p --permission-mode plan "..." |
Basic Usage
Simple analysis:
# Analyze a file
claude -p "Analyze src/utils.ts for code quality issues"
# Pipe input
cat src/utils.ts | claude -p "Review this code"
# Analyze git diff
git diff main | claude -p "Review these changes, point out potential issues"JSON output (for downstream processing):
claude -p --output-format json "Analyze src/utils.ts for code quality"Response structure:
{
"result": "Analysis result text...",
"is_error": false,
"total_cost_usd": 0.023,
"session_id": "abc123"
}Restricted tools (security review scenario):
# Read-only mode: only allow reading and searching, no file modifications
claude -p --allowedTools "Read,Grep,Glob" "Review all API endpoint security in src/"Environment Variables
| Variable | Description |
|---|---|
ANTHROPIC_API_KEY | API key (required in CI) |
CLAUDE_MODEL | Default model (overridden by --model) |
CLAUDE_MAX_TURNS | Default max turns |
In CI environments, ANTHROPIC_API_KEY must be injected via Secrets — never hardcode it in config files or source code.
GitHub Actions Integration
GitHub Actions is the most mature CI/CD integration for Claude Code. Anthropic provides an official Action that works out of the box.
The Official GitHub Action
# .github/workflows/claude-review.yml
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: |
Review this PR's code changes. Focus on:
1. Potential bugs and logic errors
2. Security vulnerabilities
3. Performance issues
4. Code style consistencyThis basic setup gets Claude Code to automatically review code on every PR creation or update, posting review results as PR comments.
Configuration Options
Key parameters for anthropics/claude-code-action@v1:
| Parameter | Description | Default |
|---|---|---|
anthropic_api_key | API key | Required |
prompt | Custom prompt | Built-in review prompt |
model | Model selection | claude-sonnet-4-6 |
max_turns | Max turns | 10 |
allowed_tools | Allowed tools list | All |
disallowed_tools | Blocked tools list | None |
timeout_minutes | Timeout | 10 |
Automated Code Review
A more complete code review workflow:
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize]
paths:
- 'src/**'
- 'lib/**'
- 'app/**'
jobs:
review:
runs-on: ubuntu-latest
# Skip draft PRs and bot-created PRs
if: |
github.event.pull_request.draft == false &&
github.event.pull_request.user.login != 'dependabot[bot]'
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
model: claude-sonnet-4-6
max_turns: 10
prompt: |
You are a strict but friendly code reviewer. Review all changes in this PR.
Review focus:
1. **Correctness**: Logic errors, edge cases, null handling
2. **Security**: Injection vulnerabilities, sensitive data leaks, permission issues
3. **Performance**: Unnecessary loops, memory leaks, N+1 queries
4. **Maintainability**: Naming clarity, function complexity, code duplication
Output format:
- 🔴 Must fix: Blocking issues
- 🟡 Suggestion: Improvement recommendations
- 🟢 Well done: Things worth praising
If no issues found, just say "LGTM" — don't manufacture problems.Auto-Fix PRs
Claude Code can not only review but also fix issues directly:
name: Claude Auto Fix
on:
issue_comment:
types: [created]
jobs:
auto-fix:
# Only trigger on PR comments containing /claude-fix
if: |
github.event.issue.pull_request &&
contains(github.event.comment.body, '/claude-fix')
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.issue.pull_request.head.ref }}
fetch-depth: 0
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
max_turns: 20
allowed_tools: "Read,Grep,Glob,Edit,Write,Bash"
prompt: |
Read all review comments on this PR and fix the mentioned issues.
After fixing, commit the changes.
Commit message format: fix: <brief description of the fix>Usage: type /claude-fix in a PR comment, and Claude Code will automatically read review feedback and fix the code.
Issue-Driven Development
The most powerful use case — generating PRs directly from issues:
name: Claude Issue to PR
on:
issues:
types: [labeled]
jobs:
implement:
# Only trigger when the "claude" label is added
if: github.event.label.name == 'claude'
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
max_turns: 30
prompt: |
Read Issue #${{ github.event.issue.number }}.
Based on the issue description:
1. Create a new branch: claude/issue-${{ github.event.issue.number }}
2. Implement the feature or fix described in the issue
3. Ensure code passes lint and tests
4. Create a PR with the title referencing the issue number
5. Explain the implementation approach in the PR description
Follow the coding standards in the project's CLAUDE.md.Workflow: Create issue → Describe requirements → Add claude label → Claude Code implements → Generates PR → Human review → Merge.
Other CI Platform Integration
Not using GitHub Actions? No problem. Claude Code's Headless mode works on any CI platform.
GitLab CI
# .gitlab-ci.yml
claude-review:
stage: review
image: node:20
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
before_script:
- npm install -g @anthropic-ai/claude-code
script:
- |
git diff origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME...HEAD > /tmp/diff.txt
REVIEW=$(claude -p --output-format text --max-turns 10 \
--allowedTools "Read,Grep,Glob" \
"Review the following code changes, point out potential issues: $(cat /tmp/diff.txt)")
echo "$REVIEW"
# Post review as MR comment
curl --request POST \
--header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
--header "Content-Type: application/json" \
--data "{\"body\": \"## Claude Code Review\n\n${REVIEW}\"}" \
"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests/${CI_MERGE_REQUEST_IID}/notes"
variables:
ANTHROPIC_API_KEY: $ANTHROPIC_API_KEYGeneric CI Pattern
Regardless of CI platform, the core pattern is the same:
#!/bin/bash
# scripts/claude-review.sh
set -euo pipefail
# 1. Get changes
DIFF=$(git diff origin/main...HEAD)
if [ -z "$DIFF" ]; then
echo "No code changes, skipping review"
exit 0
fi
# 2. Claude Code review
REVIEW=$(echo "$DIFF" | claude -p \
--output-format text \
--max-turns 10 \
--allowedTools "Read,Grep,Glob" \
"Review these code changes. Focus on bugs, security vulnerabilities, and performance issues. If no issues found, reply LGTM.")
# 3. Output result
echo "$REVIEW"
# 4. Check for blocking issues (optional)
if echo "$REVIEW" | grep -q "🔴"; then
echo "::error::Claude Code found blocking issues"
exit 1
fiCall this script from any CI platform:
# Jenkins, CircleCI, Azure DevOps, etc.
- run: bash scripts/claude-review.sh
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}Docker Approach
If your CI environment can't easily install Node.js:
# .claude/Dockerfile
FROM node:20-slim
RUN npm install -g @anthropic-ai/claude-code
ENTRYPOINT ["claude"]# Use in CI
steps:
- run: |
docker build -t claude-code -f .claude/Dockerfile .
git diff main | docker run -i \
-e ANTHROPIC_API_KEY=${{ secrets.ANTHROPIC_API_KEY }} \
claude-code -p --max-turns 10 "Review these changes"Security Best Practices
Running an AI agent in CI/CD means security is the top priority.
API Key Management
✅ Do:
- Use your CI platform's Secrets management (GitHub Secrets, GitLab Variables, etc.)
- Rotate API keys regularly
- Use different keys for different environments
❌ Don't:
- Hardcode in YAML files
- Commit to Git repositories
- Print keys in logs
Tool Permission Control
In CI environments, Claude Code's permissions should be as tight as possible:
# Read-only review (safest)
- uses: anthropics/claude-code-action@v1
with:
allowed_tools: "Read,Grep,Glob"
prompt: "Review code changes"
# Can fix (needs write permissions)
- uses: anthropics/claude-code-action@v1
with:
allowed_tools: "Read,Grep,Glob,Edit,Write"
disallowed_tools: "Bash"
prompt: "Fix lint errors"
# Full permissions (use with caution)
- uses: anthropics/claude-code-action@v1
with:
disallowed_tools: "WebFetch,WebSearch"
prompt: "Implement this feature"Rule of thumb: Read-only for reviews, add write for fixes, only grant Bash for feature implementation. Always disable network tools unless you specifically need them.
Preventing Prompt Injection
Claude Code in CI reads PR titles, descriptions, and comments — all user input. Malicious users might attempt instruction injection:
# Don't concatenate user input directly into prompts
# ❌ Dangerous
prompt: "Review this PR: ${{ github.event.pull_request.title }}"
# ✅ Safe: let Claude Code read PR info itself
prompt: "Review the current PR's code changes, focus on security and correctness"Security Checklist
| Check | Description |
|---|---|
| API key in Secrets | Not in code or config files |
| Minimal tool permissions | Only grant necessary tools |
| max_turns is limited | Prevent infinite loops burning tokens |
| Network tools disabled | Prevent data exfiltration |
| User input not concatenated | Prevent prompt injection |
| Output contains no secrets | Review results don't leak sensitive data |
Cost Control
Claude Code call volume in CI/CD can add up fast. Cost control matters.
Model Selection Strategy
| Scenario | Recommended Model | Reason |
|---|---|---|
| Simple lint fixes | Haiku | Fast, cheap, sufficient for formatting |
| Code review | Sonnet | Best cost-performance ratio, good review quality |
| Complex feature implementation | Opus | Needs deep understanding and multi-step reasoning |
| PR description generation | Haiku | Template-like task, no heavy reasoning needed |
# Choose model based on task
- uses: anthropics/claude-code-action@v1
with:
model: claude-sonnet-4-6 # Sonnet for code review
max_turns: 10
# Haiku for simple tasks
- uses: anthropics/claude-code-action@v1
with:
model: claude-haiku-4-5
max_turns: 5Trigger Condition Optimization
Not every PR needs Claude Code review:
on:
pull_request:
types: [opened, synchronize]
paths:
# Only review source code changes, ignore docs and config
- 'src/**'
- 'lib/**'
- 'app/**'
- '!**/*.md'
- '!**/*.mdx'
jobs:
review:
# Skip draft PRs
if: github.event.pull_request.draft == false
# Skip bot PRs
if: github.event.pull_request.user.login != 'dependabot[bot]'max_turns Strategy
| Task Type | Recommended max_turns | Rationale |
|---|---|---|
| Code review (read-only) | 5-10 | Read diff + analyze |
| Lint fixes | 10-15 | Read + modify + verify |
| Feature implementation | 20-30 | Multi-file read/write + tests |
| Bug fixes | 15-20 | Investigate + fix + verify |
max_turns is the most effective cost control lever. Too low and tasks will not complete; too high and you waste tokens. Adjust based on task complexity.
Cost Monitoring
# Use JSON output to get cost info
- name: Claude Review
id: review
run: |
RESULT=$(claude -p --output-format json --max-turns 10 "Review code changes")
COST=$(echo "$RESULT" | jq -r '.total_cost_usd')
echo "cost=$COST" >> $GITHUB_OUTPUT
echo "Claude Code review cost: \$$COST"
# Set up cost alerts
- name: Cost Alert
if: steps.review.outputs.cost > 1.0
run: echo "::warning::Claude Code single review cost exceeded $1.0"CLAUDE.md for CI
Claude Code reads the project CLAUDE.md in CI just like it does locally. You can add CI-specific rules.
CI-Specific Rules Example
# CLAUDE.md
## CI/CD Rules
When running in CI (CI=true environment variable detected):
### Code Review
- Only focus on files changed in this PR, do not review unmodified code
- Categorize findings: 🔴 Must fix, 🟡 Suggestion, 🟢 Well done
- If no issues found, just reply "LGTM" — do not manufacture problems
- Do not suggest refactoring unmodified code
### Auto-Fix
- Only fix clear issues (lint errors, type errors), do not refactor opportunistically
- Run relevant tests after each fix to confirm nothing breaks
- Commit message format: fix: <brief description>
### Security
- Never include environment variable values in output
- Do not read .env files
- Do not make network requestsProject Context
Claude Code in CI reads the full project context, same as locally:
CLAUDE.md → Project standards and CI rules
.claude/settings.json → Hooks and permission config
package.json → Dependencies and scripts
tsconfig.json → TypeScript config
.eslintrc → Lint rules
This means standards you have configured locally are automatically followed in CI. No need to duplicate them in CI config.
Practical Example: Complete PR Automation Pipeline
Let us tie everything together into a complete PR automation pipeline.
Pipeline Design
Developer opens PR
↓
CI basic checks (lint, tests, build)
↓
Claude Code auto review
↓
Review passes → Await human review
Review fails → Developer fixes OR comment /claude-fix for auto-fix
↓
Human review approved
↓
Merge
Complete Workflow Configuration
# .github/workflows/claude-pr-pipeline.yml
name: Claude PR Pipeline
on:
pull_request:
types: [opened, synchronize]
paths:
- 'src/**'
- 'lib/**'
- 'app/**'
issue_comment:
types: [created]
jobs:
# Job 1: Auto review
review:
if: |
github.event_name == 'pull_request' &&
github.event.pull_request.draft == false
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
model: claude-sonnet-4-6
max_turns: 10
allowed_tools: "Read,Grep,Glob"
timeout_minutes: 10
prompt: |
Review this PR's code changes.
Review focus:
1. Correctness: Logic errors, edge cases, null handling
2. Security: Injection vulnerabilities, sensitive data leaks
3. Performance: Unnecessary loops, memory leaks
4. Maintainability: Naming, complexity, duplication
Output format:
- 🔴 Must fix (with specific file and line number)
- 🟡 Suggestion
- 🟢 Well done
No issues? Just say LGTM.
# Job 2: Auto fix (comment-triggered)
auto-fix:
if: |
github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
contains(github.event.comment.body, '/claude-fix')
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.issue.pull_request.head.ref }}
fetch-depth: 0
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
model: claude-sonnet-4-6
max_turns: 20
allowed_tools: "Read,Grep,Glob,Edit,Write,Bash"
disallowed_tools: "WebFetch,WebSearch"
prompt: |
Read all review comments on this PR and fix the mentioned issues.
After fixing:
1. Run lint to confirm it passes
2. Run tests to confirm nothing is broken
3. Commit changes with format: fix: <description>Usage Flow
- Developer opens a PR
- CI runs lint and tests
- Claude Code auto-reviews and posts comments
- If issues found:
- Developer fixes manually, or
- Types
/claude-fixin a PR comment for Claude Code to auto-fix
- After review passes, human reviewer does final confirmation
- Merge
FAQ
Q: How is Claude Code in CI different from local?
A: Functionally identical — it just runs in non-interactive mode via the -p flag. It still reads CLAUDE.md, settings.json, and other project config. The main difference is that CI typically restricts tool permissions (e.g., disabling network access).
Q: Are Claude Code review results reliable? A: Very reliable for pattern-based issues (null handling, type safety, common security vulnerabilities). For business logic correctness, it may lack context. That is why it is recommended as a first line of defense, not a replacement for human review.
Q: How much does it cost? A: Depends on PR size and model choice. A medium PR (200-500 lines changed) costs roughly $0.02-0.05 with Sonnet. Haiku is cheaper for simple tasks. For a moderately active team (5-10 PRs/day), expect around $30-50/month.
Q: Can Claude Code merge PRs automatically? A: Technically yes, but strongly discouraged. Claude Code should be an assistive tool — the final merge decision should be made by humans. The risk of auto-merging is too high.
Q: Will multiple Claude Code workflows conflict? A: No. Each workflow runs in an isolated environment with its own checkout and session. But watch out for auto-fix workflows pushing commits that trigger new CI runs, potentially causing loops. Use conditional checks (like checking commit author) to prevent this.
Q: Does it work with private repositories?
A: Yes. Claude Code runs in CI after the code is checked out locally, so no additional repo access is needed. You just need ANTHROPIC_API_KEY and a GitHub token (automatically provided by Actions).
Conclusion
Claude Code CI/CD integration boils down to two things:
- Headless mode lets Claude Code run in any automated environment — the
-pflag + tool permission control + cost limits, three levers that cover everything - The official GitHub Actions integration makes PR automation plug-and-play — auto review, auto fix, issue-driven development, pick the combination you need
Start with the simplest auto code review, get it running smoothly, then gradually add auto-fix and issue-driven development. Do not try to build the full automation suite from day one — let your team get comfortable with AI reviews first, then expand from there.
Further Reading
- Claude Code Testing Workflow Guide — Test automation and CI integration
- Claude Code Git Workflow Guide — Git operations and PR workflows
- Claude Code Hooks Guide — Deterministic local automation
- The Complete CLAUDE.md Guide — Project standards configuration
- Claude Code Performance & Cost Optimization Guide — Cost optimization for CI scenarios
- Claude Code Security Best Practices — Security in CI/CD pipelines
- Claude Code GitHub Actions Official Docs — Official integration documentation