Skip to main content

Someone wanted to learn this too, so Grasp built them a personal learning path.

You can keep exploring this one or create your own

Automating Claude Code with GitHub Actions in Headless Mode

Welcome back!

In our previous lesson, we built a multi-step shell script to automate FastAPI resource scaffolding on your local machine. You learned how to maintain conversational context with session IDs and manage permissions with --allow-tools.

Today, we're taking that automation to the next level by moving it into the cloud. This lesson is all about integrating Claude Code directly into your development pipeline using GitHub Actions. You'll learn how to set up automated tasks, such as code reviews, that run on every pull request. This is a crucial step towards creating professional-grade, "headless" workflows that operate without any manual intervention.

Understanding Claude Code Integration with GitHub

There are two primary ways to use Claude Code within a GitHub repository, each suited for different levels of control and customization.

  1. The Official GitHub App: This is a high-level, managed integration. You install it in your repository, and it enables you to trigger Claude by mentioning @Claude in issue comments or pull requests. It's fantastic for quickly delegating tasks like implementing features or fixing bugs.

  2. Custom Workflows with Headless Mode: This approach gives you full control. You write your own GitHub Actions workflow file from scratch, using the claude -p command we practiced in the last lesson. This allows you to design highly specific, automated pipelines tailored to your project's needs.

Let's start by seeing the official GitHub App in action. It's a powerful demonstration of what's possible when you connect Claude directly to your codebase's lifecycle.

Building headless automation with Claude Code | Code w/ Claude

This video from Anthropic, 'Building headless automation with Claude Code', includes an excellent live demo of the official GitHub Action.

Watch the segment from 05:09 to 16:15. The presenter uses a simple '@cloud please implement this feature' comment on a GitHub issue to have Claude code a new 'power-up' feature for a quiz app, create a new branch, and prepare a pull request. This showcases the end-to-end potential of CI/CD integration.

As you saw, the integration is seamless. Claude can read the context from the issue, understand the project structure, implement the feature, and prepare the changes for your review.

Claude AI Fixing a Build Issue in GitHub
This image is a perfect example of what the GitHub Action can do. Here, Claude has detected a build failure, identified the missing semicolon causing it, created a fix, committed it to a new branch, and is ready for a human to review and merge the resulting pull request.

Setting Up the Official GitHub App

The easiest way to get started with GitHub integration is to install the official app. The process is straightforward and guided by a built-in Claude Code command.

Claude Code Tutorial #9 - Claude Code with GitHub

The video 'Claude Code Tutorial #9 - Claude Code with GitHub' by Net Ninja provides a clear, step-by-step walkthrough of the installation process.

Watch from 00:34 to 02:33. The video covers two key parts: The prerequisite: ensuring the GitHub CLI is installed and you are logged in (gh auth login). The installation command: using /install github app inside the Claude Code terminal to initiate the setup, authorize the app, and create the pull request that adds the workflow files to your repository.

Once you merge the PR created by the installation command, your repository will be equipped with two primary workflows:

  • Issue Resolution: Mentioning @Claude in an issue will prompt it to work on a fix or feature on a new branch.
  • Pull Request Review: Claude will automatically review new pull requests, providing feedback on code quality, potential bugs, and security.

While this automated setup is powerful, your goal is to master advanced, custom workflows. So, let's move on to building our own pipeline.

Building a Custom GitHub Actions Workflow

This is where your knowledge of headless mode and shell scripting comes into play. We will now create a GitHub Actions workflow from scratch that automatically reviews the code changes in a pull request. This gives you far more granular control than the default app.

Our goal is to create a workflow that:

  1. Triggers whenever a pull request is opened or updated.
  2. Installs Claude Code on the GitHub runner.
  3. Calculates the git diff for the pull request.
  4. Pipes that diff into a headless Claude Code command with a prompt asking for a code review.
  5. Posts Claude's review as a comment on the pull request.

The following resource provides a complete, production-ready recipe for this exact task.

Headless Mode and CI/CD - Tutorial - SFEIR Institute

The tutorial 'Headless Mode and CI/CD' from the SFEIR Institute is the definitive guide for this task. It provides the exact YAML file and commands needed.

Please read the section 'How to integrate Claude Code into GitHub Actions?'. It's composed of two parts: 'Step 4: Create the workflow file' and 'Step 5: Secure the API secret'. Study the provided claude-review.yml file carefully. We will break it down next.

Let's dissect the claude-review.yml file from the tutorial.

1. Create the Workflow File

In your project repository, create the file .github/workflows/claude-review.yml with the following content:

name: Claude Code Review

on:
  pull_request:
    types: [opened, synchronize]

permissions:
  contents: read
  pull-requests: write

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0 # Important for comparing with main branch

      - uses: actions/setup-node@v4
        with:
          node-version: '22'

      - name: Install Claude Code
        run: npm install -g @anthropic-ai/claude-code

      - name: Run Code Review
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
        run: |
          DIFF=$(git diff origin/main...HEAD)
          echo "$DIFF" | claude -p \
            "You are an expert code reviewer. Analyze this diff for potential bugs, security issues, and style improvements based on best practices for Python and FastAPI. Format your response as clean Markdown." \
            > review.md

      - name: Post Review Comment
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const review = fs.readFileSync('review.md', 'utf8');
            github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              body: `## 🤖 Claude Code Review\n\n${review}`
            });

2. Breakdown of the Workflow

  • on: pull_request: This defines the trigger. The workflow runs when a PR is opened or a new commit is pushed to it (synchronize).
  • permissions: We need pull-requests: write permission for our workflow to be able to post a comment on the PR.
  • actions/checkout@v4: This step checks out your code. fetch-depth: 0 is crucial because it fetches the full git history, allowing us to compare the PR branch with the main branch.
  • Install Claude Code: These steps set up the Node.js environment and install the Claude Code CLI on the virtual runner.
  • Run Code Review: This is the core logic.
    • env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}: This securely injects your API key from GitHub's encrypted secrets storage into the environment. Never hardcode API keys in your workflow files.
    • DIFF=$(git diff origin/main...HEAD): This command calculates the changes between the tip of your main branch and the current PR branch (HEAD).
    • echo "$DIFF" | claude -p "...": Here, we pipe the diff directly into a headless Claude command, just as we practiced locally. The prompt is tailored for a high-quality review.
    • > review.md: The text output from Claude is saved to a file.
  • Post Review Comment: This step uses the github-script action, a convenient tool for making GitHub API calls. It reads the review.md file and uses the GitHub REST API to post its contents as a new comment on the PR that triggered the workflow.

3. Secure the API Key

As mentioned in the tutorial, your ANTHROPIC_API_KEY must be stored as a repository secret. You can do this via the GitHub UI (Settings > Secrets and variables > Actions) or with the GitHub CLI:

gh secret set ANTHROPIC_API_KEY

The CLI will then prompt you to paste your key.

With this file committed to your repository and the secret configured, every new pull request will now receive an automated code review from Claude.

Claude Code Review Output in Terminal
This terminal output shows the kind of detailed feedback a custom review workflow can generate, identifying specific issues like dead code or potential errors.

Conclusion

Congratulations! You have successfully bridged the gap between local automation and a fully integrated CI/CD pipeline. You can now automate sophisticated tasks that run directly within your software development lifecycle.

Key Takeaways:

  • Two Paths to CI/CD: You can use the high-level, easy-to-set-up GitHub App for common tasks or build custom workflows with headless mode for maximum control and flexibility.
  • Custom Workflows are Scripts in the Cloud: A custom GitHub Actions workflow is essentially a shell script running on a GitHub runner. It uses the same headless commands (claude -p), piping (|), and environment variables you're already familiar with.
  • The git diff Pattern is Key: A common and powerful pattern in CI/CD is to calculate the git diff of a pull request and use it as context for an AI prompt.
  • Security is Non-Negotiable: Always store sensitive information like API keys in GitHub Secrets, never in plain text in your workflow files.

Next Up:

In this lesson, we generated a plain text review and posted it. In the next lesson, "Write a script that prompts headless Claude to generate a structured PR description from a git diff," we will refine this process. You'll learn how to instruct Claude to provide structured JSON output and then parse and format that data to automatically populate a pull request's description field in a clean, organized way.

Can't find a good explanation? Sign up and we'll make it for you

Sign up