Skip to content

CI/CD Integration & Automation

Claude Code transforms from a developer tool into a powerful automation engine when integrated with CI/CD pipelines. By leveraging GitHub Actions, headless mode, and the Claude Code SDK, you can automate everything from code reviews to bug fixes, creating an AI-powered development pipeline that works 24/7.

The fastest way to enable GitHub integration:

  1. Run the installer command

    Terminal window
    claude> /install-github-app
  2. Follow the prompts

    • Authorize the Claude GitHub App
    • Grant repository permissions
    • API key is configured automatically
  3. Test the integration Create an issue comment:

    @claude implement this feature based on the issue description

For custom configurations or cloud providers:

.github/workflows/claude.yml
name: Claude Code Actions
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened]
permissions:
contents: write
pull-requests: write
issues: write
jobs:
claude-pr:
if: contains(github.event.comment.body, '@claude')
runs-on: ubuntu-latest
steps: - uses: actions/checkout@v4
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
trigger_phrase: "@claude"
max_turns: 30
timeout_minutes: 60

Transform issues directly into pull requests:

.github/workflows/issue-to-pr.yml
name: Issue to PR
on:
issues:
types: [labeled]
jobs:
implement-feature:
if: github.event.label.name == 'implement-with-claude'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: anthropics/claude-code-action@v1
with:
prompt: |
Implement the feature described in issue #${{ github.event.issue.number }}:
${{ github.event.issue.title }}
${{ github.event.issue.body }}
Follow our coding standards in CLAUDE.md.
Create comprehensive tests.
Update documentation as needed.
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
auto_pr: true
pr_title: "feat: ${{ github.event.issue.title }}"

Enhance PR reviews with AI analysis:

.github/workflows/claude-review.yml
name: AI Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for better analysis
- uses: anthropics/claude-code-action@v1
with:
prompt_file: .github/claude-review-prompt.md
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
comment_on_pr: true

Review prompt template:

.github/claude-review-prompt.md
Review this pull request focusing on:
1. **Security vulnerabilities** - Authentication, authorization, injection attacks
2. **Performance issues** - O(n²) algorithms, unnecessary queries, memory leaks
3. **Code quality** - DRY violations, unclear naming, missing error handling
4. **Test coverage** - Missing edge cases, insufficient assertions
5. **Documentation** - Outdated comments, missing API docs
Be concise. Only report actual issues, not style preferences.
Format: `[SEVERITY: HIGH/MEDIUM/LOW] Issue description`

Automatically attempt to fix CI failures:

.github/workflows/fix-ci.yml
name: Auto-fix CI Failures
on:
workflow_run:
workflows: ['CI']
types: [completed]
jobs:
fix-failures:
if: ${{ github.event.workflow_run.conclusion == 'failure' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.workflow_run.head_branch }}
- name: Get failure logs
uses: actions/github-script@v7
id: logs
with:
script: |
const logs = await github.rest.actions.downloadJobLogsForWorkflowRun({
owner: context.repo.owner,
repo: context.repo.repo,
job_id: ${{ github.event.workflow_run.id }}
});
return logs.data;
- uses: anthropics/claude-code-action@v1
with:
prompt: |
The CI build failed with these errors:
${{ steps.logs.outputs.result }}
Fix the issues causing the build to fail.
Focus on test failures, linting errors, and type errors.
auto_commit: true
commit_message: 'fix: resolve CI failures'

Run Claude Code programmatically:

Terminal window
# Simple one-shot command
claude -p "Update all copyright headers to 2025" --json
# With specific permissions
claude -p "Fix the failing test in auth.test.js" \
--allow-tools Edit,View,Bash \
--output-format json
# Pipe data for processing
cat error.log | claude -p "Analyze these errors and suggest fixes"

Handle large-scale migrations:

migrate-components.sh
#!/bin/bash
# Generate task list
claude -p "List all React class components that need hooks migration" \
--output-format json > tasks.json
# Process each component
jq -r '.files[]' tasks.json | while read file; do
echo "Migrating $file..."
claude -p "Convert $file from class component to hooks. Preserve all functionality." \
--allow-tools Edit \
--timeout 300
done

Integrate with existing tools:

Terminal window
# Code quality pipeline
npm run lint 2>&1 | \
claude -p "Fix all linting errors" --allow-tools Edit | \
claude -p "Now run tests and fix any failures" --allow-tools Bash,Edit | \
claude -p "Generate a summary of changes" > changes.md
.git/hooks/pre-commit
#!/bin/bash
# Check for TODO comments
if git diff --cached --name-only | xargs grep -l "TODO" > /dev/null; then
echo "Found TODO comments. Asking Claude to address them..."
git diff --cached --name-only | xargs grep -l "TODO" | while read file; do
claude -p "In $file, implement any TODO comments or convert them to proper issues" \
--allow-tools Edit \
--timeout 60
done
# Re-stage changes
git add -u
fi
.github/workflows/update-docs.yml
name: Update Documentation
on:
schedule:
- cron: '0 2 * * *' # 2 AM daily
workflow_dispatch:
jobs:
update-docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Update API Documentation
run: |
claude -p "Update API documentation in docs/api.md based on current code in src/api/" \
--allow-tools Edit,View \
--output-format json > result.json
- name: Update README
run: |
claude -p "Update README.md badges, dependencies list, and examples based on package.json and recent changes" \
--allow-tools Edit,View
- name: Create PR if changes
uses: peter-evans/create-pull-request@v5
with:
title: 'docs: automated documentation updates'
commit-message: 'docs: update API docs and README'
branch: auto-update-docs

Orchestrate changes across microservices:

.github/workflows/coordinated-update.yml
name: Coordinated Service Update
on:
workflow_dispatch:
inputs:
change_description:
description: 'Describe the change to implement'
required: true
jobs:
plan:
runs-on: ubuntu-latest
outputs:
plan: ${{ steps.create-plan.outputs.plan }}
steps:
- uses: actions/checkout@v4
- id: create-plan
run: |
PLAN=$(claude -p "Create an implementation plan for: ${{ github.event.inputs.change_description }}. List affected services and order of updates." --json)
echo "plan=$PLAN" >> $GITHUB_OUTPUT
update-services:
needs: plan
strategy:
matrix:
service: ${{ fromJson(needs.plan.outputs.plan).services }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
repository: myorg/${{ matrix.service }}
- uses: anthropics/claude-code-action@v1
with:
prompt: |
Implement this change: ${{ github.event.inputs.change_description }}
This is service: ${{ matrix.service }}
Full plan: ${{ needs.plan.outputs.plan }}
Ensure backward compatibility.
auto_pr: true
.github/workflows/security-scan.yml
name: Security Analysis
on:
pull_request:
branches: [main]
jobs:
security-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Security Scan
run: |
npm audit --json > audit.json
bandit -r . -f json -o bandit.json || true
- name: Analyze and Fix
run: |
claude -p "Analyze security reports and fix critical issues:
NPM Audit: $(cat audit.json)
Bandit: $(cat bandit.json)
Fix only CRITICAL and HIGH severity issues.
Document any issues that require manual review." \
--allow-tools Edit,View \
--timeout 600
- name: Generate Security Report
run: |
claude -p "Generate a security assessment report based on the changes made" \
> security-report.md
- name: Comment on PR
uses: actions/github-script@v7
with:
script: |
const report = require('fs').readFileSync('security-report.md', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: report
});

Only run Claude on relevant changes:

name: Smart Claude Trigger
on:
pull_request:
paths:
- '**.ts'
- '**.tsx'
- '**.js'
- '**.jsx'
jobs:
analyze-complexity:
runs-on: ubuntu-latest
outputs:
should-run-claude: ${{ steps.check.outputs.result }}
steps:
- uses: actions/checkout@v4
- id: check
run: |
# Only run Claude for substantial changes
LINES_CHANGED=$(git diff --numstat origin/main..HEAD | awk '{sum+=$1+$2} END {print sum}')
if [ $LINES_CHANGED -gt 50 ]; then
echo "result=true" >> $GITHUB_OUTPUT
else
echo "result=false" >> $GITHUB_OUTPUT
fi
claude-review:
needs: analyze-complexity
if: needs.analyze-complexity.outputs.should-run-claude == 'true'
runs-on: ubuntu-latest
steps:
- uses: anthropics/claude-code-action@v1
# ... rest of configuration

Reduce redundant API calls:

- name: Cache Claude Analysis
uses: actions/cache@v3
with:
path: .claude-cache
key: claude-${{ hashFiles('**/*.ts', '**/*.tsx') }}
- name: Run Claude Analysis
run: |
if [ -f .claude-cache/analysis.json ]; then
echo "Using cached analysis"
else
claude -p "Analyze codebase for potential improvements" \
--output-format json > .claude-cache/analysis.json
fi
- name: Report Usage Metrics
if: always()
run: |
claude -p "Summarize the work done in this CI run" --json > usage.json
# Send to monitoring service
curl -X POST https://metrics.company.com/claude-usage \
-H "Content-Type: application/json" \
-d @usage.json
claude-metrics.js
const { execSync } = require('child_process');
function trackClaudePerformance(command, context) {
const start = Date.now();
try {
const result = execSync(`claude -p "${command}" --json`, {
encoding: 'utf8',
maxBuffer: 10 * 1024 * 1024,
});
const duration = Date.now() - start;
const parsed = JSON.parse(result);
// Send to monitoring
sendMetrics({
command,
context,
duration,
tokensUsed: parsed.usage?.total_tokens,
success: true,
});
return parsed;
} catch (error) {
sendMetrics({
command,
context,
duration: Date.now() - start,
success: false,
error: error.message,
});
throw error;
}
}

Use CLAUDE.md Files

Configure project-specific guidelines for consistent CI behavior

Set Appropriate Timeouts

Prevent runaway costs with reasonable time limits

Review Before Merge

Always have human review for Claude-generated changes

Monitor Costs

Track API usage and optimize triggers

Symptoms: @claude mentions ignored

Solutions:

  1. Verify GitHub App installation
  2. Check workflow permissions
  3. Ensure trigger conditions match
  4. Verify API key is set correctly
  5. Check GitHub Actions logs

For custom integrations beyond GitHub Actions:

claude-automation.ts
import { query, type SDKMessage } from '@anthropic-ai/claude-code';
async function automateCodeReview(prNumber: number) {
const messages: SDKMessage[] = [];
// Use Claude Code SDK to review the PR
for await (const message of query({
prompt: `Review pull request #${prNumber} for:
- Security vulnerabilities
- Performance issues
- Code style violations
- Missing tests
Use the CLAUDE.md file for project context and
.github/review-guide.md for review guidelines.`,
abortController: new AbortController(),
options: {
maxTurns: 20,
systemPrompt: 'You are a code reviewer. Be thorough but constructive.',
},
})) {
messages.push(message);
}
return messages;
}
// Alternative: Using command line in Node.js
import { exec } from 'child_process';
import { promisify } from 'util';
const execAsync = promisify(exec);
async function reviewWithCLI(prNumber: number) {
const { stdout } = await execAsync(
`claude -p "Review PR #${prNumber} for security and performance" --output-format json`
);
return JSON.parse(stdout);
}

Team Workflows

Scale CI/CD patterns across your organization

Cost Management

Optimize CI/CD costs and usage

Security Patterns

Implement secure CI/CD practices