GitHub Actions with Claude Code: PR Automation
GitHub Actions lets you trigger Claude Code workflows directly from pull requests—enabling @claude mentions in PRs, automated code reviews, security scans, and instant improvements without leaving GitHub. This guide teaches how to wire Claude Code into your CI/CD pipeline for practical gains: review code quality on every push, auto-fix formatting, generate migration scripts, or validate against your team's patterns.
The workflow is straightforward: @mention Claude in a PR comment, GitHub Actions captures the context, Claude Code runs your configured task, and results appear as automated commits or comments. This turns code review from a manual bottleneck into a collaborative loop where AI handles routine checks while engineers focus on logic and design. For the GitLab equivalent, see GitLab CI/CD with Claude Code; to add scheduled and recurring automation on top of push-triggered workflows, see routines and scheduled automation.
GitHub Actions Setup for Claude Code
GitHub Actions runs on every push, pull request, or on-demand trigger. To integrate Claude Code, you define a workflow file (YAML) in .github/workflows/ that spins up a runner and executes a shell script or Node.js task. The key ingredients are:
1. Trigger event (push, pull_request, workflow_dispatch) — when the action runs. 2. Runner (ubuntu-latest, macos-latest, or self-hosted) — the machine that executes Claude Code. 3. Steps — shell commands or actions that call the Claude Code CLI with your authentication token.
Claude Code runs in the runner environment with access to your repository checkout. A typical workflow initializes the repo, sets a CLAUDE_API_KEY secret, and calls claude-code run with a prompt or task file. The runner exits with a status code indicating success or failure, which GitHub then reports on the PR.
Quick reference
- GitHub stores secrets (API keys) encrypted; only the runner process decrypts them at runtime.
- Runners have 6-hour timeouts by default; long-running tasks may need job management or scheduled cron workflows.
- Self-hosted runners give you full environment control but require maintenance and security hardening.
- Matrix builds run the same workflow on multiple OS/Node versions in parallel—useful for testing across environments.
- GitHub provides
${{ secrets.VAR }}and${{ github.event.* }}context so your script accesses repo info and PR data.
Remember this
A GitHub Actions workflow is a trigger (event) + runner (machine) + steps (CLI commands); Claude Code runs as one step via the CLI, receiving repo context and returning code changes or reports.
@claude Mentions and PR Comments
The most human-friendly way to invoke Claude Code in GitHub is a simple @claude mention in a PR comment. GitHub Actions can monitor pull_request_comment events, parse the @claude mention, extract the requested task, and dispatch Claude Code to run. The workflow captures the PR's diff, file context, and the human's question from the comment.
For example, a developer writes "Review this PR for security issues" as a comment. The workflow detects @claude, creates a prompt like "Here is a PR for {repo}. Analyze for OWASP top 10 risks and suggest fixes", and runs Claude Code with that context. Claude then comments back on the PR with findings and optional auto-fixes.
This model is low friction: no need to manually trigger pipelines or edit YAML. Engineers work in their natural GitHub interface, and Claude Code acts as an always-on assistant. The workflow logs all interactions, so there is a permanent audit trail of what was asked and what Claude suggested.
Quick reference
- PR comment events include the PR diff, files changed, and the full conversation history in that PR.
- Use GitHub Actions filters (
contains()functions in YAML) to detect @claude mentions specifically. - Subsequent comments in the same PR thread can refine the task—Claude reads the thread history for context.
- Comment-based workflows scale well: no bottleneck, no queue, and engineers control when Claude runs.
- Permissions: use
GITHUB_TOKEN(auto-granted) to post replies; useCLAUDE_API_KEYsecret for Claude requests.
Remember this
A @claude mention in a PR comment triggers a workflow that runs Claude Code in the runner, reads the PR context (diff, files, thread history), and posts results as PR comments or commits.
Auto-Creating PRs from Issues or Manual Triggers
Beyond responding to comments, Claude Code can autonomously create pull requests. An issue is filed ("Refactor auth module", "Add Pydantic validation to API"), a workflow triggers (manually or on issue creation), Claude Code runs a task like "Refactor the auth module to use dependency injection", and the result is committed to a branch and a PR is opened.
This workflow uses the GitHub CLI (gh) or the REST API to:
1. Create a new branch (e.g., claude/auth-refactor-${TIMESTAMP}).
2. Commit Claude's changes to that branch.
3. Open a PR with a title and description summarizing the work.
The approach is useful for well-scoped, repeatable tasks: adding a new API endpoint from a template, upgrading a dependency, or applying a code style across the repo. Human review is still mandatory—the PR is opened as draft or with a review request to enforce approval before merge.
Quick reference
- Use
gh pr create --draftto open a PR that cannot be auto-merged; requires human approval. - Title and description should summarize the task and rationale; automate this via Claude's own output.
- Branch naming (e.g.,
claude/feature-name) helps identify auto-generated PRs in the git log. - Combine with branch protection rules: require PR reviews, status checks (linter, tests), before merge.
- If multiple Claude-generated PRs are open simultaneously, use sequential workflows or a queue to avoid conflicts.
Remember this
Workflows can instruct Claude Code to generate code, commit it to a new branch, and open a PR for human review; this automates repetitive refactors or boilerplate without manual branch management.
Automated PR Code Review and Comments
The most demanding task for GitHub Actions + Claude Code is asynchronous, high-quality code review. A PR is opened, a workflow extracts the diff (via git diff origin/base...HEAD), sends it to Claude Code with a prompt like "Review this diff for bugs, security, and best practices", and Claude responds with detailed comments on specific lines.
GitHub's REST API (POST /repos/.../pulls/{pull_number}/comments) allows you to post review comments on exact lines. Claude's output format should be structured: identify each issue as "File: path/to/file.py, Line 42: Security risk in SQL injection...", then map that to an API call that posts the comment at that specific location.
The review happens in real time (under 30 seconds typically for a reasonable diff), so reviewers see feedback immediately when they open the PR. Multiple review passes are possible: initial review, then after fixes, re-review to confirm issues are resolved.
Quick reference
- Extract the PR diff:
git diff origin/${GITHUB_BASE_REF}...HEADcaptures only changed lines. - Include file metadata (file names, line numbers) in the prompt so Claude can map findings to exact locations.
- Post line-level comments via GitHub REST API; these appear inline in the PR diff view.
- Use review status checks: set the workflow to 'fail' if critical issues are found, blocking merge until resolved.
- Combine with automated fixes: if an issue is auto-fixable (format, lint), commit the fix on the same branch.
Remember this
A review workflow extracts the PR diff, sends it to Claude Code with review criteria, parses findings, and posts line-level comments via GitHub API; combines detection (is there a bug?) with action (fix or comment).
GitHub Runners and Matrix Builds
GitHub Actions runs on GitHub-hosted runners (ubuntu-latest, windows-latest, macos-latest) or self-hosted runners you manage. For Claude Code workflows, a standard ubuntu-latest runner is sufficient: it has git, Node.js/Python, and network access to call Claude's API.
Matrix builds run the same workflow on multiple configurations. For example, test a build on Node 18, 20, and 22 in one workflow run. Each matrix job runs independently, and GitHub reports results per matrix element. For Claude Code, this is less common—you rarely need to run the same Claude task on 5 different Node versions—but if your task involves building or testing across environments, matrices save time.
A typical matrix build for a Node project runs the same job configuration on multiple Node versions. Self-hosted runners are runners you operate (on your own machine, a server, or a cloud VM). They run arbitrary workflows with full environment access but require you to maintain the runner software and security. Use self-hosted runners for tasks that need GPU, large memory, or private tool access.
Quick reference
- GitHub-hosted runners are free for public repos; private repos get 2,000 minutes/month included in GitHub Free.
- Self-hosted runners start a long-lived process that polls for jobs; they can run workflows for private networks.
- Runner logs show full command output; helpful for debugging if Claude Code exits with an error.
- Concurrency limits: free GitHub accounts allow 1 concurrent job; pro allows 3-5.
- Timeouts: jobs have 6-hour limits by default; jobs killed after timeout show no output.
Remember this
GitHub Actions runs on managed (ubuntu-latest) or self-hosted runners; matrix builds run the same workflow across multiple configs; Claude Code runs as a step in any runner.
Secrets and Credential Management
GitHub Actions secures sensitive data (API keys, tokens) via repository or organization secrets. Define a secret (e.g., CLAUDE_API_KEY) in the repo settings (Settings > Secrets and variables), and reference it in your workflow as ${{ secrets.CLAUDE_API_KEY }}. GitHub decrypts the secret only when the runner starts and injects it as an environment variable.
Best practices: - Never hardcode API keys in YAML or commit history. - Use fine-grained tokens: a CLAUDE_API_KEY should allow only Claude API calls, not full account access. - Rotate keys periodically (e.g., every quarter) and revoke old tokens immediately. - Enable secret masking in logs: GitHub automatically redacts any value that matches a known secret. - Use separate secrets for dev, staging, and production if your workflow deploys to multiple environments.
For GitHub-specific tasks (e.g., opening a PR, posting comments), GitHub provides a default GITHUB_TOKEN with repo access. This token is scoped to the current repo and expires after the workflow completes, so it is safe to use without additional secrets.
Quick reference
- Secrets are encrypted at rest in GitHub; only runners in that repo can access them.
- Environment variables are logged as plain text unless you mask them manually; never do this.
- Use branch protection rules to enforce that certain secrets are only available to runs on main.
- Audit secret access: GitHub logs all workflow runs; review logs if you suspect unauthorized access.
- For external services (Slack, AWS, etc.), use deploy keys or service account tokens with minimal permissions.
Remember this
GitHub secrets store API keys encrypted; a runner decrypts and injects them as env vars; use fine-grained tokens and rotate regularly to minimize blast radius if a token leaks.
Real Example: Daily Security Scan + Auto-Create PR
Here is a complete, working workflow that scans your codebase daily for security issues using Claude Code:
1name: Daily Security Scan2 3on:4 schedule:5 - cron: "0 9 * * *"6 workflow_dispatch:7 8jobs:9 security-review:10 runs-on: ubuntu-latest11 permissions:12 contents: write13 pull-requests: write14 steps:15 - uses: actions/checkout@v416 - uses: actions/setup-node@v417 with:18 node-version: "20"19 - name: Run security scan20 run: |21 claude-code run "22 Analyze this repository for common security vulnerabilities:23 - Hardcoded credentials (API keys, tokens, passwords)24 - SQL injection or command injection risks25 - Unvalidated user input in APIs26 - Missing authentication/authorization checks27 - Unencrypted sensitive data28 - Insecure dependencies (known CVEs)29 30 For each issue found, explain the risk and suggest a fix.31 Output a JSON summary: { issues: [ { file, line, risk, fix } ] }32 " > scan-report.json33 env:34 CLAUDE_API_KEY: ${{ secrets.CLAUDE_API_KEY }}35 - name: Create PR if issues found36 if: hashFiles('scan-report.json') != ''37 run: |38 ISSUES=$(cat scan-report.json | jq '.issues | length')39 if [ "$ISSUES" -gt 0 ]; then40 git config user.name "claude-code-bot"41 git config user.email "bot@coreconcept.dev"42 git checkout -b "security-scan-$(date +%Y%m%d-%H%M%S)"43 cp scan-report.json docs/security-report.md44 git add docs/security-report.md45 git commit -m "docs: security scan report - $ISSUES issues found"46 git push origin HEAD47 gh pr create --title "Security scan: $ISSUES vulnerabilities found" --body "Automated security scan identified potential vulnerabilities. Review the report in docs/security-report.md" --draft48 fi49 env:50 GH_TOKEN: ${{ github.token }}This workflow runs every morning at 9 AM UTC. It invokes Claude Code with a detailed security checklist, parses the output, and if issues are found, commits the report and opens a draft PR. Engineers review the PR and either fix the issues or override if the finding is a false positive.
Quick reference
- Schedule syntax:
0 9 * * *is cron (5 fields: minute, hour, day, month, weekday); see crontab.guru. - workflow_dispatch allows manual triggering from the GitHub UI without waiting for the schedule.
- Permissions block specifies what the workflow can do; write to contents (repo code) and PRs (create reviews).
- hashFiles() checks if the output file exists; avoids creating empty PRs.
- Draft PR (
--draft) prevents accidental merge; requires manual approval.
Remember this
A scheduled workflow runs Claude Code on your codebase, parses findings, and auto-creates a PR with results; this provides recurring security audits without manual effort.
Troubleshooting and Debugging Workflows
When a workflow fails, GitHub shows the logs for each step. To debug Claude Code in a workflow:
1. Check runner logs: Click the failed step in the Actions tab; see full output. Look for errors from claude-code (e.g., "Invalid API key", "Command not found").
2. Enable debug logging: Set ACTIONS_STEP_DEBUG=true in workflow secrets to see detailed runner diagnostics (git commands, env vars).
3. Test locally first: Run the same script locally on your machine with the same API key and repo state. If it works locally but fails in the runner, the issue is environment-specific (Node version, missing tools, file paths).
4. Common failures:
- API key invalid or expired: Check Settings > Secrets; verify the key works via curl.
- Git push fails: Ensure the runner has write access to the repo; check branch protection rules.
- Claude Code not found: Runner may not have Claude Code CLI installed; add npm install -g claude-code or use a container image with Claude Code pre-installed.
- Timeout: PR diff or large repos may take >6 minutes; consider splitting the task or using larger runners.
- Permissions denied: GITHUB_TOKEN may lack permissions; check the job's permissions: block in the YAML.
5. Use workflow artifacts: Upload logs, reports, or debug files so they persist after the workflow completes. This helps with auditing and historical analysis.
Quick reference
- GitHub Actions UI shows a timeline of each step; click each step to expand its logs.
- Workflow runs are logged in the repo's Actions tab; logs persist for 90 days (free) or indefinitely (paid).
- Re-run failed workflows from the GitHub UI without editing code; useful for transient failures.
- Branch protection rules can block merges if any required status check fails; use this to enforce Claude review.
- Disable workflows temporarily with
on: nullor delete the file; no way to pause a workflow in GitHub itself.
Remember this
Debugging workflows: check runner logs, test locally first, verify env vars/keys, and review job permissions; use ACTIONS_STEP_DEBUG for verbose output.
Key takeaway
Integrating Claude Code into GitHub Actions unlocks powerful automation: PR reviews run instantly, security scans happen on schedule, and developers stay in GitHub's interface. The key is defining clear, scoped tasks in your workflow YAML and letting Claude Code handle the analysis or code generation.
Practice: Create a new workflow file .github/workflows/claude-review.yml that listens for pull_request events and runs Claude Code to review the diff for any function that lacks a docstring. Expected result: Claude posts a comment on each undocumented function. Test by creating a PR with a function missing a docstring—Claude should detect it and comment. If Claude doesn't detect it, refine the prompt (e.g., ask Claude to list all functions and their docstring status). Once working, update the workflow to auto-commit fixes for functions Claude can document automatically.
Polo Khan
Lead Author & Systems ArchitectSoftware engineer and distributed systems architect specializing in backend scalability, cloud-native infrastructure, databases, and AI engineering workflows. Author and maintainer of Core Concept Learning.
Related Articles
Explore this topic