Imagine your development team sleeping while your code gets smarter. No, really—GitHub Actions can run Claude Code workflows automatically whenever something happens in your repository. Want to generate API documentation from your code? Done. Auto-review pull requests? Easy. Run tests and fix failures in the same action? Absolutely possible. But how do you actually set this up? Let’s walk through it step by step, from zero to a working action that leverages Claude Code’s intelligence.
Why Claude Code in GitHub Actions Matters
GitHub Actions is already powerful—it lets you automate testing, deployment, and code checks. But GitHub Actions without Claude Code is like having a hammer without a hand to swing it. Claude Code brings reasoning, context-awareness, and creative problem-solving to your workflows. Instead of running the same static checks every time, you get an AI assistant that understands your entire codebase and can make intelligent decisions.
Here’s what becomes possible:
Intelligent Code Review: Claude Code can read a pull request, understand the context, spot logical issues that linters miss, and suggest improvements—all automatically. Unlike static analysis tools, Claude understands intent. It sees that a refactoring changes the behavior in subtle ways that a regex-based linter would never catch.
Smart Documentation Generation: Update your code, and Claude Code generates fresh docs, API references, and change summaries without manual work. When you update a function signature, Claude Code can automatically update the documentation to match, including examples and edge cases.
Automated Testing and Fixing: Tests fail? Claude Code can diagnose why, attempt fixes, and even learn from your test suite to prevent similar issues. It can suggest optimizations based on performance characteristics or security patterns it detects.
Context-Aware Refactoring: Need to refactor a component? Claude Code understands your architecture and can suggest improvements that actually fit your codebase, not generic cookbook solutions.
On-Demand Scripting: Generate one-off scripts, data migrations, or utility functions triggered by commits or pull requests. Need to migrate data between schema versions? Claude Code can write and run the migration for you.
Release Notes and Changelogs: Automatically generate structured release notes from commits, pull requests, and code changes. Claude Code understands what’s user-facing and what’s internal plumbing.
The magic is that Claude Code doesn’t just execute pre-written logic—it reasons about your code, makes decisions based on understanding, and adapts to your specific patterns. Every repository has its own conventions, architecture style, and coding patterns. Claude Code learns these patterns and applies them consistently.
Prerequisites: What You Need Before Starting
Let’s make sure you have the foundation in place. There’s not much, but it matters.
A GitHub Repository: Obviously. If you don’t have one yet, create a free repo on github.com. GitHub Actions runs on every repository, including free ones. You don’t need a fancy setup—a simple repo with a README and some code is enough to start experimenting.
Anthropic API Key: You need this to authenticate Claude Code’s requests to Anthropic’s API. Grab one free at console.anthropic.com. Create an account, navigate to API Keys, and generate a new key. Keep this safe—it’s like your credentials to Claude’s intelligence. Don’t commit it to the repository.
Basic Git Knowledge: You should be comfortable with concepts like branches, commits, and pull requests. You don’t need to be an expert, but you need to understand the flow. If you’re not sure about any concepts, GitHub’s documentation is thorough and beginner-friendly.
GitHub Secrets Understanding: GitHub allows you to store sensitive data (like API keys) encrypted as “secrets” in your repository settings. We’ll use this to keep your Anthropic API key safe and inaccessible to the public. Secrets are encrypted at rest and only exposed to workflows that need them.
Node.js 18+ (Optional but Recommended): While not strictly required for running actions in GitHub’s environment, understanding Node.js helps if you’re debugging or testing locally before pushing to GitHub. You don’t need to be a Node.js expert—just basic familiarity with npm and running commands is enough.
If you have a GitHub account and can create API keys, you’re ready. Everything else we’ll cover as we go. You can learn the rest by building.
Understanding GitHub Actions Fundamentals
Before we jump into Claude Code, let’s establish what GitHub Actions actually does. Think of it as an automation engine that runs code in response to events.
When you push to your repository, create a pull request, open an issue, or run a scheduled task, GitHub can automatically trigger a “workflow”—a series of commands executed in a clean environment called a “runner.” That runner is a virtual machine (usually Ubuntu, but you can pick Windows or macOS too) where you can run bash commands, call APIs, build projects, or anything else you’d normally do in a terminal.
Here’s the flow:
- Event: Something happens (push, PR, schedule, manual trigger)
- Workflow Runs: GitHub spins up a runner and executes your workflow
- Jobs Run in Sequence or Parallel: Each workflow contains jobs, and jobs contain steps
- Steps Execute Commands: Each step can run a shell command or a pre-built action
- Results: Output is captured, logs are saved, and you can set up notifications
A typical GitHub Actions workflow file looks like this:
name: My Workflow
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: npm install
- run: npm test
This triggers on pushes and PRs, checks out your code, installs dependencies, and runs tests. Simple but powerful. Now imagine if that last step—instead of just running pre-written tests—could reason about your code, understand what you’re trying to do, and make intelligent decisions. That’s Claude Code in GitHub Actions.
Now, Claude Code integrates into this workflow as a step. Instead of just running static commands, you invoke Claude Code to reason about your code and take intelligent actions. You get the automation reliability of GitHub Actions plus the intelligence of Claude.
Setting Up Your Repository Secret
Your Anthropic API key is sensitive data. GitHub provides “secrets”—encrypted environment variables stored securely. You can reference them in workflows, but they’re never exposed in logs or to the public. This is important for security.
Here’s how to add your API key as a secret:
-
Navigate to Your Repository Settings
-
Go to your repository on GitHub
-
Click the “Settings” tab at the top (you need admin or owner permissions)
-
Find Secrets and Variables
-
In the left sidebar, look for “Secrets and variables” under “Security”
-
Click “Actions”
-
Create a New Repository Secret
- Click the “New repository secret” button
- In the “Name” field, type:
ANTHROPIC_API_KEY - In the “Secret” field, paste your Anthropic API key (the long string that starts with
sk-or similar) - Click “Add secret”
That’s it. Now your workflow can reference this secret using ${{ secrets.ANTHROPIC_API_KEY }}. GitHub automatically masks this value in logs, so even if someone views the workflow run output, they won’t see the actual key. They’ll see something like *** instead.
Security Note: Repository secrets are tied to a specific repository. If you want the secret available across multiple repositories in an organization, you can use organization secrets instead (available from Settings > Secrets and variables > Actions at the organization level). Organization secrets are managed centrally but work the same way.
Important: When you add a secret, GitHub doesn’t show you the value afterward—not even to you. If you need to change it, you have to delete and recreate it. This is intentional for security. You can’t accidentally paste it somewhere.
Your First Claude Code GitHub Action: An Annotated Workflow
Alright, let’s write your first workflow that uses Claude Code. This example creates a simple workflow that generates documentation for new Python files. We’ll build it step by step, and I’ll explain every single line.
Create a new file in your repository at .github/workflows/claude-code-demo.yml:
name: Claude Code Demo - Auto-Generate Documentation
# Trigger this workflow when code is pushed to main or when
# a pull request is opened/updated
on:
push:
branches:
- main
paths:
- "**.py" # Only trigger if Python files change
pull_request:
paths:
- "**.py"
jobs:
generate-docs:
# Run on GitHub's Ubuntu environment
runs-on: ubuntu-latest
steps:
# Step 1: Check out your repository code
# This makes the repository contents available to the workflow
- name: Checkout code
uses: actions/checkout@v4
# Step 2: Set up Node.js environment
# Claude Code runs on Node.js, so we need it installed
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "18"
# Step 3: Install Claude Code globally
# This gives us the `claude-code` command in our workflow
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code
# Step 4: Run Claude Code to generate documentation
# This is where the magic happens. Claude Code reads your Python files
# and generates docstring documentation for any functions without them.
- name: Generate documentation with Claude Code
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude-code \
--task "Review all Python files in this repository. For any function without a docstring, generate a concise docstring that explains what the function does, its parameters, and return value. Add the docstrings but do not modify the function logic." \
--mode batch \
--auto-approve
# Step 5: Commit and push changes (if any were made)
# If Claude Code generated docstrings, commit them back to the repo
- name: Commit changes
run: |
git config --local user.email "[email protected]"
git config --local user.name "Claude Code Bot"
if ! git diff --quiet; then
git add -A
git commit -m "docs: Auto-generate docstrings via Claude Code"
git push
else
echo "No changes to commit"
fi
Let’s break down what’s happening here:
The on: section defines when the workflow triggers. We’ve set it to run on pushes to main and PRs, but only if Python files change. This saves API quota by not running unnecessarily. The paths filter is key—without it, you’d trigger Claude Code every time you commit a markdown change, wasting money and compute.
runs-on: ubuntu-latest tells GitHub to use their standard Ubuntu runner. This is a clean Linux environment with common tools pre-installed (git, Python, curl, etc.). Every run gets a fresh machine, so you don’t have state leaking between runs.
The steps: section is the heart of the workflow:
-
Checkout: The
actions/checkoutaction clones your repository into the runner. Without this, Claude Code can’t see your code. It pulls the commit that triggered the workflow, so Claude sees the actual code you’re working with. -
Setup Node.js: We install Node.js 18 because Claude Code is a Node.js application. We specify the version explicitly to ensure consistency across runs—no surprises if GitHub changes their default Node version.
-
Install Claude Code: We use npm to install the global Claude Code CLI tool. The
-gflag installs it globally so it’s available in your PATH for subsequent steps. The first time this runs, npm downloads the package (this takes a few seconds). Subsequent runs are faster if you cache the npm packages (we’ll cover caching later). -
Run Claude Code: This is the intelligent step. The
--taskflag tells Claude Code what to do. The--mode batchruns in non-interactive mode (important for CI/CD), and--auto-approvelets Claude Code make changes without asking permission (useful in automated contexts where there’s no human to approve). -
Commit Changes: If Claude Code modified files, we commit and push those changes back to the repository. We configure git with a bot email and name so commits are labeled as coming from an action, not a person. The
if ! git diff --quietcheck ensures we only commit if there are actual changes (preventing empty commits).
Understanding Runner Environments
When your workflow runs, it runs on a “runner”—a temporary virtual machine GitHub provides. Understanding how these work is crucial for debugging and optimization.
GitHub-Hosted Runners: These are machines GitHub manages. You have three main options:
- ubuntu-latest: Linux environment, most common, cheapest, and best-supported
- windows-latest: Windows environment, good for .NET projects or Windows-specific tools
- macos-latest: macOS environment, slower and pricier, good for iOS/macOS development
Each runner comes pre-installed with common tools (git, Node.js, Python, Docker, etc.), but the exact versions vary. If you need a specific version of something, always install it explicitly in your workflow (like we did with Node.js). Don’t rely on the pre-installed versions because they change with GitHub’s updates.
Self-Hosted Runners: You can also run workflows on your own machine or server. This is useful if you need special hardware (GPU, for example), offline access, or want to use a fast local machine instead of GitHub’s cloud runners. Setting up self-hosted runners is more complex, but it’s documented well in GitHub’s runner configuration guide. For beginners, stick with GitHub-hosted runners.
Claude Code in Runners: Claude Code installs like any other Node.js package. The key requirement is that the runner has Node.js 18+ and internet access (to reach Anthropic’s API). GitHub-hosted runners have both by default, including internet access (though restricted to certain protocols and destinations).
Important: The runner is ephemeral. Once your workflow finishes, the machine is destroyed. Any files you create vanish unless you commit them (back to your repository) or upload them as artifacts (GitHub’s artifact storage system). This ephemeral nature is actually a feature—every run starts fresh, no state leaks between runs.
Installing and Verifying Claude Code in Your Workflow
Let’s drill deeper into the installation step, because getting this right is critical. If Claude Code doesn’t install correctly, all subsequent steps fail.
When you run npm install -g @anthropic-ai/claude-code in a GitHub Actions workflow, npm fetches the Claude Code package and its dependencies, then installs them globally on the runner. The -g flag means “global,” so Claude Code is available in the system PATH for any subsequent step.
Here’s a more robust installation step that also verifies success:
- name: Install and verify Claude Code
run: |
# Install Claude Code globally
npm install -g @anthropic-ai/claude-code
# Verify installation succeeded
claude-code --version
# Check that the command is in PATH
which claude-code
# Show Node.js version for debugging
node --version
npm --version
When you run this step, the output will show you:
- The exact version of Claude Code installed
- The full path to the Claude Code executable (should be something like
/usr/local/bin/claude-code) - The versions of Node.js and npm
If the claude-code --version command fails, Claude Code didn’t install correctly. Check the step’s output for errors—usually it’s a Node.js version mismatch (unlikely if you specified 18) or a network issue (the runner can’t reach npm’s registry, rare but possible).
Pro tip: If you want faster workflows, you can build a custom Docker image with Claude Code pre-installed and use that as your runner, rather than installing it every time. But for beginners, the npm install approach is simpler and more transparent. You can always optimize later.
Writing Your First Real Claude Code Action
Now let’s create a more practical example: a workflow that reviews pull requests using Claude Code. This is closer to real-world usage.
Create .github/workflows/claude-code-pr-review.yml:
name: Claude Code PR Review
on:
pull_request:
types: [opened, synchronize] # Trigger when PR is opened or updated
jobs:
review:
runs-on: ubuntu-latest
steps:
- name: Checkout PR code
uses: actions/checkout@v4
with:
# Fetch full history so Claude can understand context
fetch-depth: 0
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "18"
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: Review PR with Claude Code
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
# Get the base branch and compare to current branch
git diff origin/${{ github.base_ref }}...HEAD > /tmp/pr.diff
# Run Claude Code review, passing the diff
claude-code \
--task "Review the following code diff from a pull request. Check for: 1) Logic errors or bugs, 2) Performance issues, 3) Security vulnerabilities, 4) Code style inconsistencies, 5) Missing tests. For each issue found, explain the problem and suggest a fix. Be constructive and helpful." \
--input /tmp/pr.diff \
--mode batch
- name: Comment review on PR
if: always() # Run even if Claude Code step fails
uses: actions/github-script@v7
with:
script: |
// This step would post Claude Code's review as a comment
// In a real workflow, you'd parse Claude Code's output and format it nicely
const body = `## Claude Code Review\n\nReview completed. Check the workflow logs for details.`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
This workflow:
- Triggers whenever a PR is opened or updated (but not on every commit—only when the PR itself changes)
- Checks out the PR code with full git history (crucial for context)
- Installs Claude Code
- Generates a diff of the PR’s changes
- Passes that diff to Claude Code with a review task
- Comments the results back on the PR (or at minimum posts a notification)
The fetch-depth: 0 is important—it tells Git to fetch the entire history, giving Claude Code context about how the code has evolved. Without it, Claude Code might not understand the codebase as well. With full history, Claude can see what changed before, what the original implementation looked like, and make more informed suggestions.
The types: [opened, synchronize] means the workflow triggers when the PR is first opened and also when you push new commits to the PR branch. This ensures the review runs with the latest code.
Debugging a Failing Action
Things go wrong. That’s normal. Here’s how to debug when your Claude Code action fails. Debugging is a skill—learning to be systematic about it saves hours.
Step 1: Check the Workflow Logs
Go to your repository’s “Actions” tab. Find the failed workflow run and click on it. You’ll see all the steps listed. Click on the step that failed to expand its output. The logs usually tell you exactly what went wrong. Look for red text or ERROR markers.
Common errors:
“claude-code: command not found”: Installation failed. Check the Node.js installation step—make sure it succeeded. Also verify that npm installed globally. The error usually appears right after you try to run claude-code. Look at the npm install output to see what went wrong (might be a network issue, package not found, etc.).
“ANTHROPIC_API_KEY is not set”: The secret isn’t being passed correctly. Double-check that you named the secret exactly ANTHROPIC_API_KEY in your repository settings, and that you’re referencing it correctly as ${{ secrets.ANTHROPIC_API_KEY }} in the workflow. GitHub’s secret names are case-sensitive.
“API request failed”: Your API key is invalid, your quota is exhausted, or there’s a network issue. Verify the key is correct in your repository secrets. If you just created the key, give it a moment to propagate through GitHub’s systems (usually instant, but worth waiting 30 seconds). Check your Anthropic account’s usage dashboard to see if you’ve hit rate limits.
“Permission denied”: The runner doesn’t have permission to commit or push. In GitHub Actions, workflows have default permissions that may need adjusting. Go to Settings > Actions > General > Workflow permissions and ensure “Read and write permissions” is enabled. This is a common gotcha—without write permissions, your workflow can’t push changes back to the repository.
“fatal: not a git repository”: The checkout step failed. Make sure actions/checkout@v4 is the first step in your workflow (or at least before any git commands).
Step 2: Run Locally
The best debugging is to reproduce the issue on your own machine. Clone your repository, install Claude Code locally, and run the same command your workflow runs. This eliminates the mystery of what the runner is doing. Local reproduction is often faster than pushing, waiting for the action to run, checking logs, pushing again.
# Install Claude Code locally (if not already)
npm install -g @anthropic-ai/claude-code
# Set your API key
export ANTHROPIC_API_KEY=your-key-here
# Run the same task your workflow runs
claude-code --task "Your task here" --mode batch
If it fails locally, you’ve isolated the issue. If it works locally but fails in the action, the problem is environmental (runner permissions, installed tools, different working directory, etc.). If it works locally and in the action, you’re golden.
Step 3: Add Debug Output
You can add extra logging to see what’s happening:
- name: Debug info
run: |
echo "Node version:"
node --version
echo "NPM version:"
npm --version
echo "Claude Code location:"
which claude-code
echo "Current directory:"
pwd
echo "Directory contents:"
ls -la
This helps you understand the state of the runner when your action runs. Are you in the right directory? Is the right version of Node installed? Is Claude Code in the PATH?
Verifying a Successful Run
How do you know your action actually worked?
In the GitHub UI:
- Go to the “Actions” tab in your repository
- Find the workflow run you care about
- Click on it to see the job details
- Each step will have a green checkmark if it succeeded, a red X if it failed
- Click on a step to see its full output
- Look for output from Claude Code indicating it did what you asked
Look for Claude Code’s Output: If Claude Code successfully ran, its output will appear in the logs. You’ll see task descriptions, reasoning, and results. The output format depends on what you asked Claude Code to do—if you asked it to generate code, you’ll see the generated code. If you asked for analysis, you’ll see the analysis.
Check for Commits: If your workflow commits changes, they’ll appear in your repository history. Go to the “Commits” section and look for commits from the GitHub action bot. The commit message you specified in the workflow (e.g., “docs: Auto-generate docstrings via Claude Code”) will appear with the bot’s avatar.
Verify Permissions: If the action was supposed to create a PR comment, check the PR. Click through to the PR and scroll down to see if Claude Code left a comment. If it was supposed to push changes, check your branch. If nothing happened, check the logs for permission errors. The most common issue is insufficient permissions—make sure your workflow has contents: write permission.
Test with Manual Trigger: GitHub Actions lets you manually trigger workflows for testing. Go to the “Actions” tab, select your workflow, click “Run workflow,” choose your branch, and click the green “Run workflow” button. This is great for testing without needing to push code. Useful when you’re developing and testing the workflow itself.
Real-World Example: Complete Code Generation Workflow
Let’s tie it all together with a practical example: a workflow that generates React component unit tests automatically whenever you add a new component. This is a real use case that many teams benefit from.
Create .github/workflows/generate-tests.yml:
name: Generate Component Tests
on:
push:
branches:
- main
paths:
- "src/components/**/*.jsx"
- "src/components/**/*.tsx"
jobs:
generate-tests:
runs-on: ubuntu-latest
permissions:
contents: write # Allow pushing commits
pull-requests: write # Allow creating PRs
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "18"
- name: Install dependencies
run: npm install
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: Generate tests with Claude Code
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude-code \
--task "For each React component in src/components that doesn't have a corresponding .test.jsx or .test.tsx file, generate comprehensive unit tests using Jest and React Testing Library. The tests should cover: 1) Basic rendering, 2) User interactions, 3) Props handling, 4) Edge cases. Place test files in the same directory with a .test extension." \
--mode batch \
--auto-approve
- name: Run tests to verify they work
run: npm test -- --coverage
- name: Create PR with generated tests
if: always()
uses: peter-evans/create-pull-request@v5
with:
commit-message: "test: Auto-generate component tests via Claude Code"
title: "Auto-generated component tests"
body: |
This PR contains unit tests generated by Claude Code for new React components.
Please review the tests and merge if they look good. You may want to add additional edge case tests based on your specific component behavior.
branch: claude-code-tests-${{ github.run_number }}
This workflow:
- Triggers when new React components are pushed to main
- Checks out the code and installs dependencies
- Installs Claude Code
- Asks Claude Code to generate tests for components without them
- Runs the generated tests to verify they’re valid and don’t break anything
- Creates a pull request with the tests for human review (rather than committing directly)
The beauty here: Claude Code understands your component structure, existing tests (if any), and can write tests that match your style and testing patterns. The npm test -- --coverage step verifies the tests actually run (no syntax errors, correct imports, etc.).
The peter-evans/create-pull-request@v5 action creates a PR instead of pushing directly to main. This is safer—it lets humans review the generated tests before they’re merged. The branch: claude-code-tests-${{ github.run_number }} ensures each run gets a unique branch name (using the run number), so multiple runs don’t conflict.
Common Pitfalls and How to Avoid Them
Pitfall 1: Forgetting the API Key
Forgetting to set up ANTHROPIC_API_KEY as a repository secret is the #1 mistake. Your workflow will fail silently or with a cryptic “API key missing” error. You spend 30 minutes wondering why your action isn’t working, then realize you never set up the secret.
Fix: Always check your repository settings and verify the secret exists. Test it by echoing its presence in a step:
- name: Verify API key exists
run: |
if [ -z "$ANTHROPIC_API_KEY" ]; then
echo "ERROR: ANTHROPIC_API_KEY not set"
exit 1
fi
echo "API key is set (length: ${#ANTHROPIC_API_KEY})"
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
This step checks if the secret is set and fails the workflow if it’s not, rather than silently continuing with an empty value. The exit 1 tells GitHub the step failed.
Pitfall 2: Insufficient Permissions
Workflows have default permissions that may restrict pushing changes or creating comments. You’ll see “Permission denied” errors when your workflow tries to commit or comment.
Fix: Explicitly grant permissions in your workflow:
jobs:
my-job:
permissions:
contents: write # To commit changes
pull-requests: write # To comment on PRs
issues: write # To comment on issues
Add these permissions to the job that needs them. Permissions are scoped to the job, so you can grant different permissions to different jobs in the same workflow.
Pitfall 3: Running on Every Commit
If your workflow triggers on every push, you’ll burn through your API quota quickly and slow down your workflows. Developers will complain that pushing is slow because the action takes 60 seconds to run.
Fix: Use paths to only trigger on relevant files:
on:
push:
paths:
- "src/**" # Only trigger if src/ changes
- "!src/**/*.test.js" # But not test files
The paths filter is powerful. You can include specific directories and exclude others (with !). This keeps costs down and feedback loops fast.
Pitfall 4: Assuming Installation is Instant
Node.js and Claude Code installation takes time. On every run, npm downloads and installs. This can feel slow—30+ seconds just for installation.
Fix: Use GitHub’s action caching to speed things up:
- name: Cache npm packages
uses: actions/cache@v3
with:
path: ~/.npm
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-npm-
Caching stores the npm packages between runs. The second time your workflow runs, npm install is instant (or near-instant). The cache is invalidated when package-lock.json changes, ensuring you always get the right versions.
Or, if you run Claude Code workflows frequently, consider building a custom Docker image with Claude Code pre-installed and using that as your runner. But that’s advanced—start with npm install.
Pitfall 5: Not Handling Task Failures Gracefully
If Claude Code encounters an error mid-task, the entire workflow stops. Sometimes you want the workflow to continue and log the error instead, rather than stopping everything.
Fix: Use continue-on-error:
- name: Generate docs
continue-on-error: true
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: claude-code --task "..."
With continue-on-error: true, the step can fail without failing the entire job. Subsequent steps still run. This is useful for non-critical tasks. For critical tasks (like tests), don’t use this—let them fail the workflow so humans notice.
Pitfall 6: Committing Large Generated Files
Claude Code generates files (tests, docs, etc.). These might be large. Committing large files repeatedly can bloat your repository size.
Fix: Consider storing generated files in a separate branch or uploading them as artifacts instead of committing:
- name: Upload generated files
uses: actions/upload-artifact@v3
with:
name: generated-docs
path: docs/generated/
Artifacts are stored temporarily (30 days by default) rather than permanently in your repository. This keeps your repo lean.
Monitoring and Cost Management
Claude Code in GitHub Actions uses Anthropic’s API, which costs money based on token usage. It’s important to monitor usage and set budgets so you don’t get surprised by large bills.
Monitor Usage:
- Go to console.anthropic.com
- Navigate to Billing
- Check your current usage and costs
- Set up email alerts if available (you can usually set a threshold and get notified when you exceed it)
- Review which workflows are consuming the most tokens
Control Costs:
- Use
pathsfilters so workflows only trigger when necessary (the #1 cost saver) - Set up rate limits or throttling for tasks (run reviews only on main branch, not every branch)
- Use batch mode (which is more efficient) instead of interactive mode
- Cache results when possible (don’t regenerate docs every run if nothing changed)
- Consider model selection—Haiku is cheaper than Opus for certain tasks (Haiku for summaries, Opus for complex reasoning)
- Monitor which tasks cost the most and optimize those first
Example Budget-Conscious Workflow:
- name: Rate-limited Claude Code task
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
# Only run this on weekdays during business hours
HOUR=$(date +%H)
DOW=$(date +%w)
if [[ $DOW -ge 1 && $DOW -le 5 && $HOUR -ge 9 && $HOUR -le 17 ]]; then
claude-code --task "..."
else
echo "Skipping costly operation outside business hours"
fi
This runs expensive operations only during business hours (Mon-Fri, 9-5), saving costs during nights and weekends when the code won’t be reviewed until later anyway.
Summary: Your Claude Code GitHub Actions Journey
You’ve just learned how to integrate Claude Code into GitHub Actions workflows. Let’s recap the essentials:
You understand:
- Why Claude Code in Actions is powerful (intelligent, context-aware automation beyond static checks)
- How GitHub Actions works (events trigger workflows, workflows contain jobs, jobs contain steps)
- How to securely store your API key (repository secrets with encryption)
- How to install Claude Code in a workflow (npm install -g)
- How to write Claude Code tasks that actually make sense (clear instructions, specific goals)
- How to handle commits and pushes from workflows (git config, conditional commits)
- How to debug failures systematically (logs, local reproduction, permission checks)
- How to monitor costs and optimize workflows (paths filters, rate limiting)
Your next steps:
- Set up your Anthropic API key as a repository secret
- Create your first workflow file (
.github/workflows/your-workflow.yml) - Commit and push to trigger it
- Watch the “Actions” tab to see it run
- Iterate and improve based on results
- Add monitoring to track costs
Start small. Maybe generate documentation or run simple code analysis. As you get comfortable, build more complex workflows—code generation, testing, refactoring, whatever your team needs automated.
The beauty of Claude Code in Actions is that it brings intelligence to your CI/CD pipeline. It’s not just checking rules; it’s reasoning about your code, understanding context, and making decisions. That’s a game-changer for development velocity. Your team gets free code review, auto-generated tests, and smart documentation—while sleeping.
-iNet