CI/CD Integration
Integrating Claude Code into your CI/CD pipeline lets you make automated PR reviews, code quality checks, and automatic documentation part of the pipeline itself.
Key use casesโ
- Automated PR reviews: Claude writes review comments when a PR is opened
- Automatic issue resolution: mention Claude on an issue and it opens a fix PR
- Automatic test generation: tests suggested automatically for new code
- Release note automation: release notes generated from commit history
- Code quality gates: block PRs that fail quality criteria
The official GitHub Actionโ
Anthropic's anthropics/claude-code-action@v1 integrates Claude Code into GitHub Actions with minimal setup.
Quick start: PR reviewโ
.github/workflows/claude-review.yml:
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize, reopened]
issue_comment:
types: [created]
jobs:
claude-review:
if: |
github.event_name == 'pull_request' ||
(github.event_name == 'issue_comment' &&
contains(github.event.comment.body, '@claude'))
runs-on: ubuntu-latest
permissions:
contents: read
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 }}
That's all it takes โ mentioning @claude on a PR now triggers an automated review.
Key configuration parametersโ
| Parameter | Description | Required |
|---|---|---|
anthropic_api_key | Anthropic API key | O* |
github_token | GitHub token (for API access) | - |
prompt | Instructions for Claude (text or a skill name) | - |
claude_args | Claude Code CLI arguments (--max-turns, --model, etc.) | - |
trigger_phrase | Mention trigger phrase (default: @claude) | - |
use_bedrock | Use AWS Bedrock | - |
use_vertex | Use Google Vertex AI | - |
* Not required when using Bedrock/Vertex
If you're upgrading from the beta: remove mode (now auto-detected), rename direct_prompt โ prompt, move custom_instructions/max_turns/model into claude_args, and convert claude_env to the settings JSON format.
Custom prompt exampleโ
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: |
Focus the code review on these criteria:
1. Security vulnerabilities (OWASP Top 10)
2. Potential performance bottlenecks
3. TypeScript type safety
4. Areas lacking test coverage
claude_args: "--model claude-sonnet-5"
Automatic issue resolutionโ
Mention @claude on an issue to have it open a fix PR automatically:
name: Claude Issue Resolver
on:
issues:
types: [opened, assigned]
issue_comment:
types: [created]
jobs:
resolve:
if: |
(github.event_name == 'issue_comment' &&
contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'issues' &&
contains(github.event.issue.assignees.*.login, 'claude-bot'))
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 }}
assignee_trigger: true
AWS Bedrock integrationโ
- uses: anthropics/claude-code-action@v1
with:
use_bedrock: true
claude_args: "--model us.anthropic.claude-sonnet-5 --max-turns 10"
env:
AWS_REGION: us-west-2
OIDC authentication (auto-refreshing temporary credentials) is recommended. Set up an IAM role with aws-actions/configure-aws-credentials@v4.
Google Vertex AI integrationโ
- uses: anthropics/claude-code-action@v1
with:
use_vertex: true
claude_args: "--model claude-sonnet-5 --max-turns 10"
env:
ANTHROPIC_VERTEX_PROJECT_ID: ${{ steps.auth.outputs.project_id }}
CLOUD_ML_REGION: us-east5
The official Action handles PR context loading, issue integration, and comment posting automatically. Use the official Action for simple CI jobs; use a custom workflow (below) for heavily customized pipelines.
Custom workflowsโ
These workflows use the Claude Code CLI directly instead of the official Action.
PR review (direct CLI)โ
name: Claude Code Review (Custom)
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
- 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: Run Code Review
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD)
claude -p "Review the changes in the following files.
Check for bugs, security issues, performance problems, and code style.
Provide specific feedback for each file:
$CHANGED_FILES" \
--allowedTools "Read,Grep,Glob" > review.md
gh pr comment ${{ github.event.pull_request.number }} --body-file review.md
Automated release notesโ
name: Release Notes
on:
push:
tags:
- 'v*'
jobs:
release-notes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: Generate Release Notes
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PREV_TAG=$(git describe --tags --abbrev=0 HEAD~1)
COMMITS=$(git log $PREV_TAG..HEAD --oneline)
claude -p "Based on the following commit list,
write user-friendly release notes.
Group them into new features, bug fixes, and improvements:
$COMMITS" > release-notes.md
gh release edit ${{ github.ref_name }} --notes-file release-notes.md
GitLab CI integrationโ
.gitlab-ci.yml:
stages:
- review
claude-review:
stage: review
image: node:20
script:
- npm install -g @anthropic-ai/claude-code
- CHANGED=$(git diff --name-only origin/main...HEAD)
- claude -p "Review this code: $CHANGED"
--allowedTools "Read,Grep,Glob" > review.md
- cat review.md
only:
- merge_requests
variables:
ANTHROPIC_API_KEY: $ANTHROPIC_API_KEY
Headless modeโ
In CI environments, use non-interactive mode with the -p (or --print) flag:
# Run a single command and exit
claude -p "Analyze this code for security vulnerabilities" < vulnerable-code.ts
# Process piped input
cat error.log | claude -p "Analyze this error log and find the root cause"
# JSON output format
claude -p "Generate an API schema" --output-format json
# Streaming output
claude -p "Analyze this code" --output-format stream-json
Multi-turn conversations (via the SDK)โ
claude -p is single-turn. When you need multiple turns, use the SDK:
import { ClaudeCode } from "@anthropic-ai/claude-code";
const claude = new ClaudeCode();
const conversation = await claude.startConversation();
// Turn 1: analyze
const analysis = await conversation.send("Analyze this code");
// Turn 2: fix based on the analysis
const fix = await conversation.send("Fix the issues you found");
Security configurationโ
API key managementโ
# Store in GitHub Secrets
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
Never put an API key directly in a workflow file.
Least-privilege permissionsโ
permissions:
contents: read # read code only
pull-requests: write # post PR comments
issues: write # issue comments (if needed)
Tool restrictionsโ
In CI environments, restrict the available tools with --allowedTools and --disallowedTools:
# Read-only review
claude -p "Review this code" \
--allowedTools "Read,Grep,Glob" \
--disallowedTools "Bash,Edit,Write"
# Allow edits (only in isolated environments)
claude -p "Fix this bug" \
--allowedTools "Read,Edit,Write,Bash(npm test *)"
In CI, explicitly allowlisting only the tools you need with --allowedTools is safer than --dangerously-skip-permissions. Use bypass mode only in isolated containers.
Cost considerationsโ
Using the Claude API in CI incurs cost. Manage it with these strategies:
# Run only on PRs with a specific label
if: contains(github.event.pull_request.labels.*.name, 'needs-review')
# Limit the number of changed files
- name: Check file count
run: |
COUNT=$(git diff --name-only origin/main...HEAD | wc -l)
if [ $COUNT -gt 20 ]; then
echo "Too many files - skipping Claude review"
exit 0
fi
# Use a lightweight model
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
claude_args: "--model claude-haiku-4-5-20251001"
A full pipeline in practiceโ
name: Full CI Pipeline with Claude
on:
pull_request:
push:
branches: [main]
jobs:
# Stage 1: lint and build
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci
- run: npm run build
- run: npm run lint
# Stage 2: test
test:
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci
- run: npm test -- --coverage
# Stage 3: Claude review (PRs only)
claude-review:
runs-on: ubuntu-latest
needs: test
if: github.event_name == 'pull_request'
permissions:
contents: read
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 }}
prompt: |
Check the following in your code review:
1. Bugs and security vulnerabilities
2. Performance issues
3. Test coverage
# Stage 4: deploy (main branch only)
deploy:
runs-on: ubuntu-latest
needs: [build, test]
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Deploy
run: echo "Running deployment script"