CI/CD Integration: Claude Code in Your Pipeline
Integrate Claude Code into GitHub Actions and GitLab CI/CD. Automate PR reviews, issue implementation, security audits, and documentation updates in your development pipeline.
⚠️ Community Pattern Notice: This CI/CD integration guide describes community-developed patterns, not official Claude Code features. The CLI commands like
claude code reviewand/github-action-setupare conceptual examples based on how Claude Code could be integrated into CI/CD pipelines. Official Claude Code features are documented at docs.anthropic.com.
Claude Code isn’t just a local development tool—it can be integrated into your CI/CD pipeline for automated PR reviews, issue implementation, security audits, and more.
This guide covers integration patterns for GitHub Actions and GitLab CI/CD.
Why CI/CD Integration?
Traditional CI/CD:
└── Run tests
└── Run linting
└── Deploy (if passing)
With Claude Code:
└── Run tests
└── Run linting
└── AI-powered code review
└── Automated security audit
└── Documentation sync check
└── Issue auto-triage
└── Implement features from issues
└── Deploy (if all pass)
GitHub Actions Integration
Quick Setup
/github-action-setup
This creates workflows for:
- PR review
- Issue triage
- Security audit
- Documentation check
PR Auto-Review Workflow
# .github/workflows/claude-pr-review.yml
name: Claude PR 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
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Claude Code
run: npm install -g @anthropic/claude-code
- name: Run PR Review
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude code review \
--pr ${{ github.event.pull_request.number }} \
--output-format github \
--post-comments
- name: Security Audit
if: contains(github.event.pull_request.labels.*.name, 'security-review')
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude code audit \
--security \
--pr ${{ github.event.pull_request.number }} \
--fail-on critical,high
Issue Auto-Triage Workflow
# .github/workflows/claude-issue-triage.yml
name: Claude Issue Triage
on:
issues:
types: [opened]
jobs:
triage:
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Claude Code
run: npm install -g @anthropic/claude-code
- name: Triage Issue
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
claude code triage-issue \
--issue ${{ github.event.issue.number }} \
--add-labels \
--estimate-complexity \
--suggest-assignee
Issue Auto-Implementation Workflow
# .github/workflows/claude-implement-issue.yml
name: Claude Implement Issue
on:
issues:
types: [labeled]
jobs:
implement:
if: contains(github.event.label.name, 'claude-implement')
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Dependencies
run: npm ci
- name: Install Claude Code
run: npm install -g @anthropic/claude-code
- name: Implement Feature
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
claude code implement-issue \
--issue ${{ github.event.issue.number }} \
--create-pr \
--run-tests \
--request-review
- name: Comment on Issue
if: success()
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: ${{ github.event.issue.number }},
body: '🤖 Implementation PR created. Please review.'
})
Documentation Sync Check
# .github/workflows/claude-doc-check.yml
name: Documentation Sync Check
on:
pull_request:
paths:
- 'src/api/**'
- 'src/lib/**'
jobs:
doc-check:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Claude Code
run: npm install -g @anthropic/claude-code
- name: Check Documentation
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude code doc-audit \
--changed-files \
--check-api-docs \
--check-readme \
--output-format github
- name: Post Comment
if: failure()
uses: actions/github-script@v7
with:
script: |
github.rest.pulls.createReview({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: ${{ github.event.pull_request.number }},
event: 'REQUEST_CHANGES',
body: '📚 Documentation needs to be updated for API changes. Please update docs before merging.'
})
GitLab CI/CD Integration
Quick Setup
/gitlab-ci-setup
GitLab CI Configuration
# .gitlab-ci.yml
stages:
- review
- security
- implement
- deploy
variables:
CLAUDE_MODEL: "sonnet"
# PR/MR Review
claude-review:
stage: review
image: node:20
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
script:
- npm install -g @anthropic/claude-code
- |
claude code review \
--mr $CI_MERGE_REQUEST_IID \
--output-format gitlab \
--post-comments
variables:
ANTHROPIC_API_KEY: $ANTHROPIC_API_KEY
# Security Audit
claude-security:
stage: security
image: node:20
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: manual
allow_failure: false
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
script:
- npm install -g @anthropic/claude-code
- |
claude code audit \
--security \
--fail-on critical,high \
--output-format junit > security-report.xml
artifacts:
reports:
junit: security-report.xml
variables:
ANTHROPIC_API_KEY: $ANTHROPIC_API_KEY
# Issue Implementation
claude-implement:
stage: implement
image: node:20
rules:
- if: $CI_PIPELINE_SOURCE == "issue"
when: manual
script:
- npm install -g @anthropic/claude-code
- npm ci
- |
claude code implement-issue \
--issue $CI_ISSUE_IID \
--create-mr \
--run-tests
variables:
ANTHROPIC_API_KEY: $ANTHROPIC_API_KEY
GITLAB_TOKEN: $GITLAB_TOKEN
GitLab Webhook Integration
For @claude mentions in MRs:
# claude-mention-handler.yml
claude-mention:
stage: review
image: node:20
rules:
- if: $CI_PIPELINE_SOURCE == "chat"
script:
- npm install -g @anthropic/claude-code
- |
claude code respond-mention \
--mr $CI_MERGE_REQUEST_IID \
--comment-id $COMMENT_ID \
--context-depth 10
variables:
ANTHROPIC_API_KEY: $ANTHROPIC_API_KEY
API Provider Options
Anthropic API (Direct)
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
AWS Bedrock
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: us-east-1
CLAUDE_PROVIDER: bedrock
CLAUDE_MODEL: anthropic.claude-3-5-sonnet-20241022-v2:0
Google Vertex AI
env:
GOOGLE_APPLICATION_CREDENTIALS: /tmp/gcp-key.json
CLAUDE_PROVIDER: vertex
CLAUDE_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }}
CLAUDE_REGION: us-east5
steps:
- name: Setup GCP Credentials
run: echo '${{ secrets.GCP_SA_KEY }}' > /tmp/gcp-key.json
Workflow Patterns
Pattern 1: Full PR Review
# Complete PR review with multiple checks
jobs:
review:
strategy:
matrix:
check: [quality, security, performance, docs]
steps:
- name: Run Check
run: |
claude code review \
--type ${{ matrix.check }} \
--pr ${{ github.event.pull_request.number }}
Pattern 2: Staged Security Review
# Different review depth based on changed files
jobs:
security:
steps:
- name: Determine Review Depth
id: depth
run: |
if git diff --name-only ${{ github.event.pull_request.base.sha }} | grep -E 'auth/|payment/|admin/'; then
echo "depth=thorough" >> $GITHUB_OUTPUT
else
echo "depth=standard" >> $GITHUB_OUTPUT
fi
- name: Security Review
run: |
claude code audit \
--security \
--depth ${{ steps.depth.outputs.depth }} \
--fail-on critical
Pattern 3: Issue to PR Pipeline
# Complete issue to implementation pipeline
name: Issue Implementation Pipeline
on:
issues:
types: [labeled]
jobs:
analyze:
if: contains(github.event.label.name, 'auto-implement')
outputs:
complexity: ${{ steps.analyze.outputs.complexity }}
assignee: ${{ steps.analyze.outputs.assignee }}
steps:
- name: Analyze Issue
id: analyze
run: |
claude code analyze-issue \
--issue ${{ github.event.issue.number }} \
--output complexity,assignee
implement:
needs: analyze
if: needs.analyze.outputs.complexity != 'high'
steps:
- name: Implement
run: |
claude code implement-issue \
--issue ${{ github.event.issue.number }} \
--model ${{ needs.analyze.outputs.complexity == 'low' && 'haiku' || 'sonnet' }}
create-pr:
needs: implement
steps:
- name: Create PR
run: |
claude code create-pr \
--issue ${{ github.event.issue.number }} \
--assign ${{ needs.analyze.outputs.assignee }} \
--label auto-generated
Security Considerations
Secret Management
# Never expose API keys
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
# Use repository secrets, not hardcoded values
# Configure in: Settings > Secrets > Actions
Permission Scoping
# Minimum required permissions
permissions:
contents: read
pull-requests: write
issues: write
# Don't use: permissions: write-all
Rate Limiting
# Add rate limiting to prevent abuse
steps:
- name: Check Rate Limit
run: |
# Check if we've exceeded daily limit
USAGE=$(cat .claude-usage 2>/dev/null || echo "0")
if [ "$USAGE" -gt 100 ]; then
echo "Rate limit exceeded"
exit 1
fi
Audit Logging
# Log all Claude operations
steps:
- name: Run with Audit
run: |
claude code review \
--pr ${{ github.event.pull_request.number }} \
--audit-log .claude-audit.json
- name: Upload Audit Log
uses: actions/upload-artifact@v4
with:
name: claude-audit
path: .claude-audit.json
Cost Management
Model Selection by Task
# Use appropriate model for task
env:
CLAUDE_MODEL: ${{ github.event.label.name == 'security-critical' && 'opus' || 'sonnet' }}
Token Budgets
# Set token limits
steps:
- name: Review with Budget
run: |
claude code review \
--pr ${{ github.event.pull_request.number }} \
--max-tokens 10000
Caching
# Cache Claude responses for identical inputs
steps:
- name: Setup Cache
uses: actions/cache@v4
with:
path: ~/.claude-cache
key: claude-${{ hashFiles('src/**') }}
- name: Review with Cache
run: |
claude code review \
--cache-dir ~/.claude-cache \
--pr ${{ github.event.pull_request.number }}
Output Formats
GitHub Format
run: |
claude code review \
--output-format github \
--post-comments
Output:
- Inline comments on specific lines
- Summary comment on PR
- Check run with annotations
JUnit Format
run: |
claude code audit --output-format junit > report.xml
artifacts:
reports:
junit: report.xml
Output:
- JUnit XML for CI integration
- Test suite visualization
- Failure tracking
JSON Format
run: |
claude code review --output-format json > review.json
# Process in subsequent steps
- name: Process Results
run: |
CRITICAL=$(jq '.issues | map(select(.severity == "critical")) | length' review.json)
if [ "$CRITICAL" -gt 0 ]; then
exit 1
fi
Integration Examples
Example 1: Complete Review Pipeline
name: Complete PR Pipeline
on:
pull_request:
types: [opened, synchronize]
jobs:
# Stage 1: Quick checks
quick-checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run lint
- run: npm run typecheck
# Stage 2: Claude review (only if quick checks pass)
claude-review:
needs: quick-checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Claude Code
run: npm install -g @anthropic/claude-code
- name: Code Review
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude code review \
--pr ${{ github.event.pull_request.number }} \
--checks quality,patterns,security \
--post-comments
# Stage 3: Security audit (for labeled PRs)
security-audit:
needs: quick-checks
if: contains(github.event.pull_request.labels.*.name, 'needs-security-review')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Claude Code
run: npm install -g @anthropic/claude-code
- name: Security Audit
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude code audit \
--security \
--model opus \
--fail-on critical,high
# Stage 4: Tests (parallel with Claude review)
tests:
needs: quick-checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm test -- --coverage
Example 2: Nightly Security Scan
name: Nightly Security Scan
on:
schedule:
- cron: '0 2 * * *' # 2 AM daily
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Claude Code
run: npm install -g @anthropic/claude-code
- name: Full Security Audit
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude code audit \
--security \
--model opus \
--depth thorough \
--output-format json > security-report.json
- name: Create Issue if Findings
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const report = JSON.parse(fs.readFileSync('security-report.json'));
if (report.critical > 0 || report.high > 0) {
github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `🚨 Security Issues Found (${report.critical} critical, ${report.high} high)`,
body: '## Security Scan Results\n\n' + report.summary,
labels: ['security', 'urgent']
});
}
Troubleshooting
API Key Issues
# Verify API key is set
- name: Check API Key
run: |
if [ -z "$ANTHROPIC_API_KEY" ]; then
echo "Error: ANTHROPIC_API_KEY not set"
exit 1
fi
Rate Limiting
# Add retry with backoff
- name: Review with Retry
uses: nick-fields/retry@v2
with:
timeout_minutes: 10
max_attempts: 3
retry_wait_seconds: 60
command: |
claude code review --pr ${{ github.event.pull_request.number }}
Large PRs
# Split review for large PRs
- name: Check PR Size
id: size
run: |
FILES=$(gh pr view ${{ github.event.pull_request.number }} --json files -q '.files | length')
if [ "$FILES" -gt 50 ]; then
echo "large=true" >> $GITHUB_OUTPUT
fi
- name: Review Large PR
if: steps.size.outputs.large == 'true'
run: |
claude code review \
--pr ${{ github.event.pull_request.number }} \
--batch-size 10 \
--summary-only
Best Practices
1. Start Small
# Begin with code review only
- run: claude code review --pr ${{ github.event.pull_request.number }}
# Add more features gradually
# - Security audit
# - Issue implementation
# - Documentation checks
2. Use Appropriate Models
# Match model to task
# Quick review: haiku
# Standard review: sonnet
# Security/critical: opus
env:
CLAUDE_MODEL: ${{ contains(github.event.pull_request.labels.*.name, 'security') && 'opus' || 'sonnet' }}
3. Set Expectations
<!-- Add to PR template -->
## AI Review Note
This PR will be reviewed by Claude Code.
Review findings are suggestions—use your judgment.
Security issues flagged as critical/high block merge.
4. Monitor Usage
# Track usage for cost management
- name: Log Usage
run: |
echo "$(date): PR ${{ github.event.pull_request.number }}" >> .claude-usage.log
gh api repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments \
--method POST \
--field body="Claude review completed. Tokens used: $(cat .claude-tokens)"
Getting Started
Today:
- Run
/github-action-setupor/gitlab-ci-setup - Add API key to repository secrets
- Test on one PR
This week:
- Configure review settings
- Add security audit for sensitive paths
- Train team on review comments
This month:
- Full pipeline integration
- Add issue implementation
- Measure review quality
CI/CD integration brings Claude Code into your automated workflow. Every PR gets consistent, thorough review. Every issue can be auto-triaged. Your team focuses on what matters.
Note: This guide describes community-developed integration patterns and conceptual workflows. The specific CLI commands shown (e.g., claude code review, claude code audit) are illustrative examples of how such integration could work. Actual implementation may require custom scripting or use of the Claude API directly.
References:
- Claude Code Official Documentation - Official Claude Code features
- GitHub Actions Documentation - GitHub’s CI/CD platform
- GitLab CI/CD Documentation - GitLab’s CI/CD platform
- Claude API Documentation - For building custom integrations