Claude Code GitHub Actions Composite (2026)
GitHub Actions composite actions let you package multiple workflow steps into a single, reusable action When you combine composite actions with Claude Code, you create reusable automation building blocks that can run AI-powered tasks across different repositories. This guide shows you how to build composite actions that invoke Claude skills for code review, documentation generation, and test automation.
Why Composite Actions Matter for Claude Integration
Standard GitHub Actions workflows often repeat the same Claude invocation steps across multiple repositories. You might need to run a tdd skill to analyze test coverage on every pull request, use pdf skill to generate formatted reports reports, or invoke frontend-design skill to check accessibility. Composite actions eliminate this duplication by letting you define the Claude invocation once and reuse it anywhere.
Composite actions also solve the parameterization challenge. Different projects may need different Claude models, different skill configurations, or different file filters. A well-designed composite action accepts these as inputs, making your automation portable across teams and repositories.
Without composite actions, you end up copy-pasting YAML blocks between repositories. When the Claude CLI changes an argument name or you want to upgrade the model version, you must find and edit every copy. With a composite action stored in a shared repository, one change propagates everywhere that action is referenced.
There is also a readability benefit. A workflow that calls ./.github/actions/claude-review is far easier to understand at a glance than one containing fifteen steps of environment setup, CLI installation, and output parsing. Composite actions push the complexity behind a clean interface.
Composite Actions vs. Other Reuse Patterns
Before building a composite action, it helps to understand where it fits relative to other GitHub Actions reuse mechanisms:
| Pattern | When to Use | Shared State |
|---|---|---|
| Composite action | Package multiple steps into one callable unit | Shares the same job runner |
| Reusable workflow | Orchestrate entire jobs from a central definition | Runs in its own job context |
| JavaScript action | Need full Node.js logic or platform independence | Isolated execution |
| Docker container action | Need a specific runtime environment | Isolated execution |
For Claude Code integration, composite actions are usually the right choice. They run in the same job as the caller (so they have access to the checked-out repository), they require no containerization, and they support the simple input/output interface that Claude invocations need.
Creating a Basic Claude Composite Action
A composite action lives in .github/actions/claude-action/action.yml. The structure requires a name, description, inputs, and a runs section using runs.using: composite. Here is a minimal action that installs Claude Code and runs a review:
name: 'Claude Code Review'
description: 'Runs Claude Code analysis on changed files'
inputs:
api-key:
description: 'Anthropic API key'
required: true
model:
description: 'Claude model to use'
required: false
default: 'claude-opus-4-6'
prompt:
description: 'Review prompt to pass to Claude'
required: false
default: 'Review this code for correctness, security issues, and style problems.'
runs:
using: 'composite'
steps:
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Claude Code
shell: bash
run: npm install -g @anthropic-ai/claude-code
- name: Run Claude review
shell: bash
env:
ANTHROPIC_API_KEY: ${{ inputs.api-key }}
CLAUDE_MODEL: ${{ inputs.model }}
run: |
claude --model "$CLAUDE_MODEL" --print "${{ inputs.prompt }}"
This action sets up Node.js, installs Claude Code globally, and runs an analysis command. You can now invoke it from any workflow without repeating the setup steps.
Calling this action from a workflow looks like this:
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/claude-review
with:
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: 'Check for any security vulnerabilities in the changed files.'
Passing Context with GitHub Context
Composite actions have access to GitHub context through ${{ github }} and ${{ steps }} variables. This enables powerful patterns where Claude analyzes specific files from a pull request:
name: 'Claude PR Analysis'
description: 'Analyzes pull request changes with Claude'
inputs:
api-key:
description: 'Anthropic API key'
required: true
base-ref:
description: 'Base branch ref for diff comparison'
required: false
default: 'main'
runs:
using: 'composite'
steps:
- name: Install Claude Code
shell: bash
run: npm install -g @anthropic-ai/claude-code
- name: Get changed files
id: changed-files
shell: bash
run: |
git fetch origin ${{ inputs.base-ref }}
CHANGED=$(git diff --name-only origin/${{ inputs.base-ref }}...HEAD | tr '\n' ' ')
echo "files=$CHANGED" >> $GITHUB_OUTPUT
- name: Run Claude analysis on changed files
shell: bash
env:
ANTHROPIC_API_KEY: ${{ inputs.api-key }}
run: |
FILES="${{ steps.changed-files.outputs.files }}"
if [ -z "$FILES" ]; then
echo "No changed files detected."
exit 0
fi
claude --print "Review these changed files for issues: $FILES. Read each file and provide a summary of concerns."
The composite action captures the changed files between base and head commits, then passes them to Claude for review. This pattern works with any Claude skill you have installed.
You can extend this pattern to filter by file type before passing to Claude. For example, if you only want to review TypeScript files:
- name: Get changed TypeScript files
id: changed-ts
shell: bash
run: |
git fetch origin ${{ inputs.base-ref }}
CHANGED=$(git diff --name-only origin/${{ inputs.base-ref }}...HEAD \
| grep -E '\.(ts|tsx)$' | tr '\n' ' ')
echo "files=$CHANGED" >> $GITHUB_OUTPUT
Filtering before passing to Claude keeps the context window focused and reduces API costs on large pull requests.
Combining Multiple Claude Skills
A sophisticated composite action can invoke multiple Claude skills in sequence. For example, You should run both tdd and pdf skills together:
name: 'Claude TDD Report'
description: 'Runs TDD analysis and generates a summary report'
inputs:
api-key:
description: 'Anthropic API key'
required: true
output-file:
description: 'Path to write the report'
required: false
default: 'claude-tdd-report.md'
runs:
using: 'composite'
steps:
- name: Install Claude Code
shell: bash
run: npm install -g @anthropic-ai/claude-code
- name: Run TDD skill analysis
shell: bash
env:
ANTHROPIC_API_KEY: ${{ inputs.api-key }}
run: |
claude --print "/tdd Analyze the test coverage for recently changed files. \
Identify untested code paths and suggest missing test cases." \
> tdd-raw-output.txt
- name: Generate markdown report
shell: bash
env:
ANTHROPIC_API_KEY: ${{ inputs.api-key }}
run: |
ANALYSIS=$(cat tdd-raw-output.txt)
claude --print "Format this TDD analysis as a clean markdown report with \
sections for Coverage Summary, Missing Tests, and Recommendations: $ANALYSIS" \
> ${{ inputs.output-file }}
- name: Upload report as artifact
uses: actions/upload-artifact@v4
with:
name: claude-tdd-report
path: ${{ inputs.output-file }}
This composite action chains two Claude invocations. The first analyzes test coverage using TDD patterns, and the second generates a formatted markdown report. Splitting the work into two Claude calls means each call has a clear, bounded task, one for analysis, one for formatting, which tends to produce more reliable results than a single large prompt trying to do both at once.
Using Outputs for Pipeline Integration
Composite actions can output results that downstream steps consume. This matters when you want Claude’s analysis to gate deployments or when you need to pass findings to other tools:
outputs:
review-result:
description: 'Claude review result'
value: ${{ steps.review.outputs.result }}
review-passed:
description: 'Whether review passed (true/false)'
value: ${{ steps.parse.outputs.passed }}
runs:
using: 'composite'
steps:
- name: Install Claude Code
shell: bash
run: npm install -g @anthropic-ai/claude-code
- name: Run Claude review
id: review
shell: bash
env:
ANTHROPIC_API_KEY: ${{ inputs.api-key }}
run: |
RESULT=$(claude --print "Review this code. Respond with exactly one word: PASS or FAIL, \
followed by a newline and your reasoning.")
echo "result=$RESULT" >> $GITHUB_OUTPUT
- name: Parse result
id: parse
shell: bash
run: |
RESULT="${{ steps.review.outputs.result }}"
if echo "$RESULT" | grep -q "^PASS"; then
echo "passed=true" >> $GITHUB_OUTPUT
else
echo "passed=false" >> $GITHUB_OUTPUT
fi
Workflows can then use ${{ steps.action.outputs.review-result }} to make decisions:
jobs:
claude-review:
runs-on: ubuntu-latest
outputs:
review-result: ${{ steps.review.outputs.review-result }}
review-passed: ${{ steps.review.outputs.review-passed }}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/claude-review
id: review
with:
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
deploy:
needs: claude-review
if: needs.claude-review.outputs.review-passed == 'true'
runs-on: ubuntu-latest
steps:
- run: echo "Deploying..."
This gating pattern ensures Claude approval before deployment proceeds.
One important design consideration: Claude’s natural language output can be non-deterministic. If you are using outputs to drive boolean gate logic, write your prompt very precisely and add a parsing step that normalizes the response. Asking Claude to respond with “PASS” or “FAIL” as the first word makes parsing reliable. Asking Claude to “summarize whether the code is good or bad” will produce prose that is hard to parse reliably.
Caching Claude Code Installation
If your composite action is called frequently, the npm install -g @anthropic-ai/claude-code step adds time to every run. You can cache it using the actions/cache action:
- name: Cache Claude Code installation
uses: actions/cache@v4
id: cache-claude
with:
path: ~/.npm-global
key: claude-code-${{ runner.os }}-${{ hashFiles('/package-lock.json') }}
- name: Install Claude Code
if: steps.cache-claude.outputs.cache-hit != 'true'
shell: bash
run: |
npm config set prefix ~/.npm-global
npm install -g @anthropic-ai/claude-code
- name: Add Claude to PATH
shell: bash
run: echo "$HOME/.npm-global/bin" >> $GITHUB_PATH
This pattern checks the cache before installing, reducing installation time from roughly 30 seconds to under 2 seconds on cache hits.
Handling Authentication Securely
Composite actions should never hardcode API keys. Instead, use GitHub secrets and pass them as masked inputs:
inputs:
api-key:
description: 'Anthropic API key from secrets'
required: true
Workflows pass the secret like this:
- uses: ./.github/actions/claude-review
with:
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
For organizations with multiple repositories, consider using GitHub’s organization-level secrets so you update the key in one place.
You can also configure repository environments with specific secrets for staging vs. production keys:
jobs:
review:
environment: production
steps:
- uses: ./.github/actions/claude-review
with:
api-key: ${{ secrets.PROD_ANTHROPIC_API_KEY }}
Environment-scoped secrets let you use a restricted API key for pull request reviews and a separate key for production deployments, following the principle of least privilege.
Publishing and Versioning Composite Actions
When your composite action is mature enough to share across multiple repositories, move it to its own dedicated repository. The standard pattern is:
your-org/claude-actions
.github/
actions/
claude-review/
action.yml
claude-tdd-report/
action.yml
claude-pr-summary/
action.yml
Other repositories reference it with a tag:
- uses: your-org/claude-actions/.github/actions/[email protected]
with:
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
Tag your action releases with semantic versioning. When you make breaking changes to inputs or outputs, increment the major version. This lets consumers pin to a major version (@v1) and get patch updates automatically, or pin to an exact tag (@v1.2.0) for full control.
Best Practices for Claude Composite Actions
Keep composite actions focused on a single responsibility. Rather than building one massive action that does everything, create small, composable actions that chain together. This makes debugging easier and lets teams mix and match capabilities.
Always specify the Claude model explicitly in your action inputs rather than relying on defaults. Models change, and explicit versions ensure reproducible behavior across runs.
Test your composite actions locally before publishing. You can run the action steps manually on your machine using the same commands, verifying the Claude invocation works before automating in CI.
Document the expected inputs and outputs clearly in your action.yml. Other developers will need to know what environment variables Claude receives and what format the outputs use.
Add a timeout to Claude invocations to prevent runaway jobs. GitHub Actions jobs have a default timeout of 360 minutes, but a Claude invocation that enters an unexpected loop could consume that entire window. Set an explicit timeout:
- name: Run Claude analysis
shell: bash
timeout-minutes: 5
env:
ANTHROPIC_API_KEY: ${{ inputs.api-key }}
run: |
claude --print "Analyze the changed files."
Finally, log intermediate results for debugging. When a composite action fails, you need enough information in the logs to understand what Claude received and what it returned. Writing the raw output to a file and uploading it as an artifact makes post-failure debugging much faster.
Summary
Composite actions provide the building blocks for reusable Claude Code automation in GitHub. By packaging Claude skill invocations into versioned actions, you create portable automation that works across repositories. The patterns in this guide, context passing, output handling, secure authentication, installation caching, skill chaining, and versioned publishing, form a foundation you can extend with specific skills like supermemory for persistent context or custom skills tailored to your codebase.
The key principle is to invest in the composite action once and reuse it everywhere. Every minute spent designing clean inputs, outputs, and error handling pays back when the action runs hundreds of times across dozens of repositories.
Try it: Paste your error into our Error Diagnostic for an instant fix.
Related Reading
- Claude Code GitHub Actions Approval Workflows
- Claude Code GitHub Actions Matrix Builds Guide
- Automated Testing Pipeline with Claude TDD Skill 2026
- Workflows Hub
Built by theluckystrike. More at zovo.one
Find the right skill → Browse 155+ skills in our Skill Finder.
Quick setup → Launch your project with our Project Starter.