Claude Code in CI/CD and Automation
Claude Code doesn't only run on your laptop; it also runs in GitHub Actions, GitLab CI and scripts. Write @claude in a PR/issue and Claude makes the code change and opens a PR.
24.1 GitHub Actions setup
- Quick: run /install-github-app in Claude Code; the GitHub App install, secret and workflow PR are all automatic (needs the gh CLI and repo admin access).
- Manual: install the Claude GitHub App → add the repo secret ANTHROPIC_API_KEY (or CLAUDE_CODE_OAUTH_TOKEN from claude setup-token for a subscription) → copy the workflow file.
- Organization: the App at org level, the secret as an org-level Actions secret, or Workload Identity Federation (GitHub OIDC) with no secret at all.
# .github/workflows/claude.yml — responds to an @claude mention (interactive mode)
name: Claude Code
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
jobs:
claude:
if: contains(github.event.comment.body, '@claude')
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
id-token: write
actions: read # to read CI results
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 1
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}# Automation mode: if `prompt` is given it doesn't wait for a mention — e.g. a report every morning
name: Daily Report
on:
schedule:
- cron: "0 9 * * *"
jobs:
report:
runs-on: ubuntu-latest
permissions: { contents: read, issues: read, id-token: write }
steps:
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: "Summarize yesterday's commits and the open issues"
claude_args: |
--model claude-opus-5-5
--max-turns 10
--allowedTools "mcp__github__list_commits,mcp__github__list_issues"| Input | What it does |
|---|---|
| prompt | Instructions or /skill-name; if absent, it waits for the @claude trigger |
| claude_args | CLI args: --model, --max-turns, --allowedTools, --mcp-config |
| anthropic_api_key / claude_code_oauth_token | Auth |
| plugin_marketplaces, plugins | Install plugins (like the code-review plugin) |
| settings | Claude Code settings JSON |
| trigger_phrase | Default @claude |
| use_bedrock / use_vertex / use_foundry | Inference through a cloud provider (OIDC) |
- Safety: only users with write access can trigger it; bots are blocked by default (allow them with allowed_bots).
- Cost: GitHub Actions minutes + API tokens. Set --max-turns, job timeouts and concurrency limits; keep CLAUDE.md short.
- Old @beta → @v1 : direct_prompt → prompt, model / max_turns → claude_args.
- For automatic PR reviews without a workflow there is also the Code Review feature; for GitLab, the GitLab CI/CD integration.
24.2 Headless scripting
# Review in a git pre-commit
git diff --cached | claude -p "Find bugs in this diff, list only the issues" --output-format json
# Streaming JSON events (to parse in your own tools)
claude -p "fix the tests" --output-format stream-json --allowedTools "Bash(npm test:*)" Edit24.3 Custom status line
// ~/.claude/settings.json
{ "statusLine": { "type": "command", "command": "~/.claude/statusline.sh" } }#!/bin/bash
# Claude Code passes the session JSON on stdin (model, cwd, cost...)
input=$(cat)
model=$(echo "$input" | jq -r '.model.display_name')
dir=$(basename "$(echo "$input" | jq -r '.workspace.current_dir')")
branch=$(git branch --show-current 2>/dev/null)
echo "[$model] $dir ($branch)"