Claude Code in CI/CD: GitHub Actions, GitLab CI, and Automation
Automate code review, issue triage, and PR creation with Claude Code in GitHub Actions, GitLab CI, and headless mode.
Claude Code in CI/CD: GitHub Actions, GitLab CI, and Automation
Key Takeaways#
- One-command setup: Run
/install-github-appin Claude Code to get a working GitHub Actions workflow in seconds. - @claude triggers actions: Mention
@claudein issues or PRs to invoke automated code generation, review, or triage. - Headless mode (
-p) enables Claude Code in any CI system — GitLab CI, Jenkins, custom scripts — with structured JSON output. - Security is built in: API keys stay in secrets, tools can be restricted with
--allowedTools, and environment scrubbing prevents key leaks. - CLAUDE.md is your CI config: Define review criteria, code style, and project rules once — Claude Code follows them in every pipeline run.
Why Use Claude Code in CI/CD#
Manual code review and issue triage are bottlenecks. Claude Code in your pipeline gives you:
- Instant PR creation — describe what you need in a comment, get a ready-to-merge PR.
- Automated code implementation — Claude reads your codebase, understands context, and writes code that fits.
- Follows your standards — CLAUDE.md sets the rules; Claude enforces them.
- Simple setup — one workflow file, one API key secret, done.
- Secure by default — sandboxed execution, restricted tools, no key exposure.
GitHub Actions Setup#
Quick Install#
Open Claude Code in your terminal and run:
/install-github-app
This handles app installation, permissions, and workflow file creation automatically.
Manual Install#
- Install the Claude GitHub App from https://github.com/apps/claude
- Add
ANTHROPIC_API_KEYas a repository secret (Settings > Secrets and variables > Actions) - Copy the workflow YAML file (see below) into
.github/worklines/claude.yml
Requirements#
- Repository admin access to install the GitHub App
- Permissions: Contents (read+write), Issues (read+write), Pull Requests (read+write)
- Secret:
ANTHROPIC_API_KEYmust be set in repository secrets
Basic Workflow: Respond to @claude Mentions#
This workflow triggers when someone mentions @claude in an issue or PR comment:
name: Claude Code on: issue_comment: types: [created] jobs: claude: runs-on: ubuntu-latest permissions: contents: write issues: write pull-requests: write steps: - uses: anthropics/claude-code-action@v1 with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
When a user comments @claude fix the failing test in auth.ts, Claude reads the repo context, writes the fix, and opens a PR — all within the workflow run.
Code Review on PR Open/Sync#
Automate code review every time a PR is opened or updated:
name: Claude Code Review on: pull_request: types: [opened, synchronize] jobs: review: runs-on: ubuntu-latest permissions: contents: write pull-requests: write steps: - uses: anthropics/claude-code-action@v1 with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} prompt: | Review this PR for bugs, security issues, and style violations. Focus on: error handling, input validation, and performance. Leave inline comments on specific lines when you find issues. claude_args: "--max-turns 5"
The prompt field gives Claude specific review instructions. claude_args passes CLI flags to control behavior — here limiting the conversation to 5 turns to keep costs predictable.
Scheduled Custom Automation#
Run Claude on a schedule for recurring tasks like dependency updates, stale issue cleanup, or health checks:
name: Claude Scheduled Tasks on: schedule: - cron: "0 9 * * 1" # Every Monday at 9 AM UTC jobs: triage: runs-on: ubuntu-latest permissions: contents: write issues: write pull-requests: write steps: - uses: anthropics/claude-code-action@v1 with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} prompt: | Find all issues labeled "bug" with no activity in 14+ days. Comment on each asking if it's still reproducible. Close issues labeled "wontfix" that are older than 30 days.
Common @claude Commands#
Once the workflow is active, use these in issue/PR comments:
| Command | What It Does |
|---|---|
@claude fix the typo in README.md | Creates a PR with the fix |
@claude add unit tests for utils.ts | Generates tests and opens a PR |
@claude review this PR | Posts a code review as comments |
@claude explain the auth flow | Posts an explanation as a comment |
@claude triage this issue | Labels and categorizes the issue |
Headless Mode for Custom Automation#
The -p (print) flag runs Claude Code non-interactively — perfect for any CI system or script:
claude -p "Find all TODO comments in the src/ directory and list them" \ --output-format json \ --max-turns 5
JSON Output Structure#
With --output-format json, the output is a structured object:
{ "type": "result", "subtype": "success", "total_cost_usd": 0.0342, "duration_ms": 8420, "num_turns": 3, "result": "Found 7 TODO comments:\n1. src/auth.ts:12 - TODO: add rate limiting\n...", "session_id": "abc123-def456" }
Key fields:
- type/subtype — success, error, or cancelled
- total_cost_usd — API cost for the run
- num_turns — how many tool-use iterations occurred
- result — Claude's text output
- session_id — reuse with
--session-idfor follow-up
Piping Input#
Pipe content directly into Claude for analysis:
cat diff.txt | claude -p "Review this diff for security vulnerabilities" git diff main | claude -p "Summarize the changes and flag anything risky"
Script Example#
#!/bin/bash # Run Claude on every changed file in a PR CHANGED_FILES=$(git diff --name-only origin/main...HEAD) for file in $CHANGED_FILES; do echo "Reviewing $file..." cat "$file" | claude -p "Review this file for bugs and suggest improvements" \ --output-format json \ --max-turns 3 done
GitLab CI/CD Integration#
GitLab doesn't have a native action, but headless mode works identically. Set ANTHROPIC_API_KEY as a CI/CD variable in Settings > CI/CD > Variables.
# .gitlab-ci.yml stages: - review claude-review: stage: review image: node:20 only: - merge_requests before_script: - npm install -g @[anthropic](/organizations/anthropic)-ai/claude-code script: - | git diff origin/main...HEAD > diff.txt cat diff.txt | claude -p "Review this MR diff for bugs, security issues, and code style violations. Be concise." \ --output-format json \ --max-turns 5 > review_result.json - | RESULT=$(cat review_result.json | jq -r '.result') echo "## Claude Code Review" >> review_comment.md echo "$RESULT" >> review_comment.md artifacts: paths: - review_result.json - review_comment.md variables: ANTHROPIC_API_KEY: $ANTHROPIC_API_KEY
For Jenkins, Bitbucket Pipelines, or any other CI: the same pattern applies — install @anthropic-ai/claude-code, set the API key, run claude -p with your prompt.
Security Best Practices#
Never Expose API Keys in Logs#
GitHub Actions masks secrets automatically, but be explicit in custom scripts:
# Good — key comes from environment, never printed claude -p "review this code" --output-format json # Bad — key appears in process list and logs ANTHROPIC_API_KEY=sk-ant-... claude -p "review this code"
Restrict Allowed Tools#
Limit what Claude can do in CI to prevent unintended actions:
claude -p "review this code" \ --allowedTools "Read,Write" \ --max-turns 3
This restricts Claude to only reading files and writing to files — no shell execution, no network tools.
Scrub Environment Variables#
Set CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1 to strip sensitive environment variables from Claude's subprocess context:
env: CLAUDE_CODE_SUBPROCESS_ENV_SCRUB: "1"
This prevents Claude from accidentally reading or leaking secrets that are present in the CI environment.
Fail on Sandbox Unavailability#
In CI, you want hard failures, not silent ones:
claude -p "run the test suite" \ --allowedTools "Bash,Read,Write" \ --sandbox.failIfUnavailable
If the sandbox can't start (e.g., due to missing dependencies in the CI image), the process exits with an error instead of running unsandboxed.
Summary Checklist#
- Store
ANTHROPIC_API_KEYin GitHub/GitLab secrets — never in code or YAML - Use
--allowedToolsto restrict Claude's capabilities in CI - Set
CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1in pipeline environment - Add
--sandbox.failIfUnavailablefor strict sandbox enforcement - Use
--max-turnsto cap cost and execution time - Review
total_cost_usdin JSON output to monitor spending
CLAUDE.md for CI Context#
Your CLAUDE.md file is the single source of truth for how Claude should behave — in CI and locally. Place it at the repository root.
# Project: Auth Service ## Review Criteria - All functions must have JSDoc comments - No `any` types in TypeScript - Every API endpoint must validate input with Zod schemas - Error handlers must log with structured JSON ## Code Style - Use named exports, not default exports - Prefer `async/await` over `.then()` chains - Max function length: 30 lines ## CI Rules - Never modify .github/workflows/ files - Never push directly to main — always open a PR - Run `npm run lint` and `npm test` before finalizing any change
When Claude runs in GitHub Actions, it reads this file and follows every rule. No extra config needed.
Bottom line: One workflow file, one secret, and a CLAUDE.md give you an AI-powered CI pipeline that reviews code, triages issues, and creates PRs on demand. Start with the basic @claude workflow, then add scheduled jobs and headless scripts as your automation needs grow.