Run Claude Code with GitHub Actions
workflow.yml reviews each pull request with Claude Code and writes the
review to the job summary. It pipes the diff into claude -p (print mode) with --max-turns 10.
- Images
- GHCR
ghcr.io/hambn/claude-code - Docker Hub
docker.io/hambn/claude-code
- GHCR
- Use case
- Code review in CI on GitHub pull requests
Prerequisites
- A repository with GitHub Actions enabled and a Linux runner with Docker, such as
GitHub-hosted
ubuntu-24.04. - An
ANTHROPIC_API_KEYrepository secret (opens in new tab).
Set up
Shell
mkdir -p .github/workflows
cp workflow.yml .github/workflows/claude-code-review.ymlIt runs on every pull request opened from a branch of the same repository.
The workflow runs ghcr.io/hambn/claude-code:ubuntu. Replace the tag with @sha256:<digest> to pin one build.
Variables
| Variable | Required | Purpose |
|---|---|---|
ANTHROPIC_API_KEY |
yes | Repository secret: Anthropic API key, passed to the review step only. |
Workspace
The runner checks out the pull request merge commit and its first parent. The review
container mounts the checkout read-only at /workspace and runs as sysadmin
(UID 1000); it does not receive the job's GitHub token.
Files
workflow.yml: pull request review workflow.
Limitations
- Pull requests from forks are skipped, because GitHub does not pass secrets to workflows they trigger.
- The review is advisory: the job does not comment on the pull request or fail on findings. Read it in the job summary.
- The diff is untrusted model input. The step has a read-only mount and no GitHub token, which limits what a crafted change can make the agent do.
File contents
workflow.yml40 lines
# Copy to .github/workflows/claude-code-review.yml and add an ANTHROPIC_API_KEY repository secret.
name: claude-code review
on:
pull_request:
permissions: {}
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
review:
name: Review with Claude Code
# GitHub does not pass secrets to workflows triggered from forks, so skip those pull requests.
if: github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-24.04
timeout-minutes: 30
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# The pull request merge commit and its first parent, the base branch, cover the diff.
fetch-depth: 2
persist-credentials: false
- name: Review
# An explicit bash shell adds pipefail, so a failed git diff fails the step.
shell: bash
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
# --max-turns bounds how many agent turns, and so how much API usage, one review takes.
git diff HEAD^1 HEAD |
docker run --rm -i -e ANTHROPIC_API_KEY \
-v "$GITHUB_WORKSPACE:/workspace:ro" \
ghcr.io/hambn/claude-code:ubuntu \
-p --max-turns 10 "Review this pull request diff for bugs, security issues, and missing tests. Reply in Markdown." \
>> "$GITHUB_STEP_SUMMARY"