mirror of
https://github.com/anthropics/claude-code-action.git
synced 2026-01-22 22:44:13 +08:00
* Remove mcp_config input in favor of --mcp-config in claude_args
BREAKING CHANGE: The mcp_config input has been removed. Users should now use --mcp-config flag in claude_args instead.
This simplifies the action's input surface area and aligns better with the Claude Code CLI interface. Users can still add multiple MCP configurations by using multiple --mcp-config flags.
Migration:
- Before: mcp_config: '{"mcpServers": {...}}'
- After: claude_args: '--mcp-config {"mcpServers": {...}}'
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Add outer action MCP tests to workflow
- Add test-outer-action-inline-mcp job to test inline MCP config via claude_args
- Add test-outer-action-file-mcp job to test file-based MCP config via claude_args
- Keep base-action tests unchanged (they still use mcp_config parameter)
- Test that MCP tools are properly discovered and can be executed through the outer action
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix: Add Bun setup to outer action MCP test jobs
The test jobs for the outer action were failing because Bun wasn't installed.
Added Setup Bun step to both test-outer-action-inline-mcp and test-outer-action-file-mcp jobs.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Add id-token permission to outer action MCP test jobs
The outer action needs id-token: write permission for OIDC authentication
when using the GitHub App. Added full permissions block to both
test-outer-action-inline-mcp and test-outer-action-file-mcp jobs.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Use github_token parameter instead of id-token permission
Replace id-token: write permission with explicit github_token parameter
for both outer action MCP test jobs. This simplifies authentication by
using the provided GitHub token directly.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Use RUNNER_TEMP environment variable consistently
Changed from GitHub Actions expression syntax to environment variable
for consistency with the rest of the workflow file.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Use execution_file output from action instead of hardcoded path
Updated outer action test jobs to:
- Add step IDs (claude-inline-test, claude-file-test)
- Use the execution_file output from the action steps
- This is more reliable than hardcoding the output file path
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* tmp
* Fix MCP test assertions to match actual output format
Updated the test assertions to match the actual JSON structure:
- Tool calls are in assistant messages with type='tool_use'
- Tool results are in user messages with type='tool_result'
- The test tool returns 'Test tool response' not 'Hello from test tool'
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Make inline MCP test actually use the tool instead of just listing
Changed the inline MCP test to:
- Request that Claude uses the test tool (not just list it)
- Add --allowedTools to ensure the tool can be used
- Check that the tool was actually called and returned expected result
- Output the full JSON for debugging
This makes both tests (inline and file-based) consistent in their approach.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
278 lines
12 KiB
YAML
278 lines
12 KiB
YAML
name: "Claude Code Action v1.0"
|
|
description: "Flexible GitHub automation platform with Claude. Auto-detects mode based on event type: PR reviews, @claude mentions, or custom automation."
|
|
branding:
|
|
icon: "at-sign"
|
|
color: "orange"
|
|
|
|
inputs:
|
|
trigger_phrase:
|
|
description: "The trigger phrase to look for in comments or issue body"
|
|
required: false
|
|
default: "@claude"
|
|
assignee_trigger:
|
|
description: "The assignee username that triggers the action (e.g. @claude)"
|
|
required: false
|
|
label_trigger:
|
|
description: "The label that triggers the action (e.g. claude)"
|
|
required: false
|
|
default: "claude"
|
|
base_branch:
|
|
description: "The branch to use as the base/source when creating new branches (defaults to repository default branch)"
|
|
required: false
|
|
branch_prefix:
|
|
description: "The prefix to use for Claude branches (defaults to 'claude/', use 'claude-' for dash format)"
|
|
required: false
|
|
default: "claude/"
|
|
allowed_bots:
|
|
description: "Comma-separated list of allowed bot usernames, or '*' to allow all bots. Empty string (default) allows no bots."
|
|
required: false
|
|
default: ""
|
|
|
|
# Claude Code configuration
|
|
prompt:
|
|
description: "Instructions for Claude. Can be a direct prompt or custom template."
|
|
required: false
|
|
default: ""
|
|
settings:
|
|
description: "Claude Code settings as JSON string or path to settings JSON file"
|
|
required: false
|
|
default: ""
|
|
|
|
# Auth configuration
|
|
anthropic_api_key:
|
|
description: "Anthropic API key (required for direct API, not needed for Bedrock/Vertex)"
|
|
required: false
|
|
claude_code_oauth_token:
|
|
description: "Claude Code OAuth token (alternative to anthropic_api_key)"
|
|
required: false
|
|
github_token:
|
|
description: "GitHub token with repo and pull request permissions (optional if using GitHub App)"
|
|
required: false
|
|
use_bedrock:
|
|
description: "Use Amazon Bedrock with OIDC authentication instead of direct Anthropic API"
|
|
required: false
|
|
default: "false"
|
|
use_vertex:
|
|
description: "Use Google Vertex AI with OIDC authentication instead of direct Anthropic API"
|
|
required: false
|
|
default: "false"
|
|
|
|
claude_args:
|
|
description: "Additional arguments to pass directly to Claude CLI"
|
|
required: false
|
|
default: ""
|
|
additional_permissions:
|
|
description: "Additional GitHub permissions to request (e.g., 'actions: read')"
|
|
required: false
|
|
default: ""
|
|
use_sticky_comment:
|
|
description: "Use just one comment to deliver issue/PR comments"
|
|
required: false
|
|
default: "false"
|
|
use_commit_signing:
|
|
description: "Enable commit signing using GitHub's commit signature verification. When false, Claude uses standard git commands"
|
|
required: false
|
|
default: "false"
|
|
experimental_allowed_domains:
|
|
description: "Restrict network access to these domains only (newline-separated). If not set, no restrictions are applied. Provider domains are auto-detected."
|
|
required: false
|
|
default: ""
|
|
path_to_claude_code_executable:
|
|
description: "Optional path to a custom Claude Code executable. If provided, skips automatic installation and uses this executable instead. WARNING: Using an older version may cause problems if the action begins taking advantage of new Claude Code features. This input is typically not needed unless you're debugging something specific or have unique needs in your environment."
|
|
required: false
|
|
default: ""
|
|
path_to_bun_executable:
|
|
description: "Optional path to a custom Bun executable. If provided, skips automatic Bun installation and uses this executable instead. WARNING: Using an incompatible version may cause problems if the action requires specific Bun features. This input is typically not needed unless you're debugging something specific or have unique needs in your environment."
|
|
required: false
|
|
default: ""
|
|
|
|
outputs:
|
|
execution_file:
|
|
description: "Path to the Claude Code execution output file"
|
|
value: ${{ steps.claude-code.outputs.execution_file }}
|
|
branch_name:
|
|
description: "The branch created by Claude Code for this execution"
|
|
value: ${{ steps.prepare.outputs.CLAUDE_BRANCH }}
|
|
github_token:
|
|
description: "The GitHub token used by the action (Claude App token if available)"
|
|
value: ${{ steps.prepare.outputs.github_token }}
|
|
|
|
runs:
|
|
using: "composite"
|
|
steps:
|
|
- name: Install Bun
|
|
if: inputs.path_to_bun_executable == ''
|
|
uses: oven-sh/setup-bun@735343b667d3e6f658f44d0eca948eb6282f2b76 # https://github.com/oven-sh/setup-bun/releases/tag/v2.0.2
|
|
with:
|
|
bun-version: 1.2.11
|
|
|
|
- name: Setup Custom Bun Path
|
|
if: inputs.path_to_bun_executable != ''
|
|
shell: bash
|
|
run: |
|
|
echo "Using custom Bun executable: ${{ inputs.path_to_bun_executable }}"
|
|
# Add the directory containing the custom executable to PATH
|
|
BUN_DIR=$(dirname "${{ inputs.path_to_bun_executable }}")
|
|
echo "$BUN_DIR" >> "$GITHUB_PATH"
|
|
|
|
- name: Install Dependencies
|
|
shell: bash
|
|
run: |
|
|
cd ${GITHUB_ACTION_PATH}
|
|
bun install
|
|
|
|
- name: Prepare action
|
|
id: prepare
|
|
shell: bash
|
|
run: |
|
|
bun run ${GITHUB_ACTION_PATH}/src/entrypoints/prepare.ts
|
|
env:
|
|
MODE: ${{ inputs.mode }}
|
|
PROMPT: ${{ inputs.prompt }}
|
|
TRIGGER_PHRASE: ${{ inputs.trigger_phrase }}
|
|
ASSIGNEE_TRIGGER: ${{ inputs.assignee_trigger }}
|
|
LABEL_TRIGGER: ${{ inputs.label_trigger }}
|
|
BASE_BRANCH: ${{ inputs.base_branch }}
|
|
BRANCH_PREFIX: ${{ inputs.branch_prefix }}
|
|
OVERRIDE_GITHUB_TOKEN: ${{ inputs.github_token }}
|
|
ALLOWED_BOTS: ${{ inputs.allowed_bots }}
|
|
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
USE_STICKY_COMMENT: ${{ inputs.use_sticky_comment }}
|
|
DEFAULT_WORKFLOW_TOKEN: ${{ github.token }}
|
|
USE_COMMIT_SIGNING: ${{ inputs.use_commit_signing }}
|
|
ADDITIONAL_PERMISSIONS: ${{ inputs.additional_permissions }}
|
|
CLAUDE_ARGS: ${{ inputs.claude_args }}
|
|
ALL_INPUTS: ${{ toJson(inputs) }}
|
|
|
|
- name: Install Base Action Dependencies
|
|
if: steps.prepare.outputs.contains_trigger == 'true'
|
|
shell: bash
|
|
run: |
|
|
echo "Installing base-action dependencies..."
|
|
cd ${GITHUB_ACTION_PATH}/base-action
|
|
bun install
|
|
echo "Base-action dependencies installed"
|
|
cd -
|
|
|
|
# Install Claude Code if no custom executable is provided
|
|
if [ -z "${{ inputs.path_to_claude_code_executable }}" ]; then
|
|
echo "Installing Claude Code..."
|
|
curl -fsSL https://claude.ai/install.sh | bash -s 1.0.92
|
|
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
|
|
else
|
|
echo "Using custom Claude Code executable: ${{ inputs.path_to_claude_code_executable }}"
|
|
# Add the directory containing the custom executable to PATH
|
|
CLAUDE_DIR=$(dirname "${{ inputs.path_to_claude_code_executable }}")
|
|
echo "$CLAUDE_DIR" >> "$GITHUB_PATH"
|
|
fi
|
|
|
|
- name: Setup Network Restrictions
|
|
if: steps.prepare.outputs.contains_trigger == 'true' && inputs.experimental_allowed_domains != ''
|
|
shell: bash
|
|
run: |
|
|
chmod +x ${GITHUB_ACTION_PATH}/scripts/setup-network-restrictions.sh
|
|
${GITHUB_ACTION_PATH}/scripts/setup-network-restrictions.sh
|
|
env:
|
|
EXPERIMENTAL_ALLOWED_DOMAINS: ${{ inputs.experimental_allowed_domains }}
|
|
|
|
- name: Run Claude Code
|
|
id: claude-code
|
|
if: steps.prepare.outputs.contains_trigger == 'true'
|
|
shell: bash
|
|
run: |
|
|
|
|
# Run the base-action
|
|
bun run ${GITHUB_ACTION_PATH}/base-action/src/index.ts
|
|
env:
|
|
# Base-action inputs
|
|
CLAUDE_CODE_ACTION: "1"
|
|
INPUT_PROMPT_FILE: ${{ runner.temp }}/claude-prompts/claude-prompt.txt
|
|
INPUT_SETTINGS: ${{ inputs.settings }}
|
|
INPUT_CLAUDE_ARGS: ${{ steps.prepare.outputs.claude_args }}
|
|
INPUT_EXPERIMENTAL_SLASH_COMMANDS_DIR: ${{ github.action_path }}/slash-commands
|
|
INPUT_ACTION_INPUTS_PRESENT: ${{ steps.prepare.outputs.action_inputs_present }}
|
|
INPUT_PATH_TO_CLAUDE_CODE_EXECUTABLE: ${{ inputs.path_to_claude_code_executable }}
|
|
INPUT_PATH_TO_BUN_EXECUTABLE: ${{ inputs.path_to_bun_executable }}
|
|
|
|
# Model configuration
|
|
GITHUB_TOKEN: ${{ steps.prepare.outputs.GITHUB_TOKEN }}
|
|
NODE_VERSION: ${{ env.NODE_VERSION }}
|
|
DETAILED_PERMISSION_MESSAGES: "1"
|
|
|
|
# Provider configuration
|
|
ANTHROPIC_API_KEY: ${{ inputs.anthropic_api_key }}
|
|
CLAUDE_CODE_OAUTH_TOKEN: ${{ inputs.claude_code_oauth_token }}
|
|
ANTHROPIC_BASE_URL: ${{ env.ANTHROPIC_BASE_URL }}
|
|
CLAUDE_CODE_USE_BEDROCK: ${{ inputs.use_bedrock == 'true' && '1' || '' }}
|
|
CLAUDE_CODE_USE_VERTEX: ${{ inputs.use_vertex == 'true' && '1' || '' }}
|
|
|
|
# AWS configuration
|
|
AWS_REGION: ${{ env.AWS_REGION }}
|
|
AWS_ACCESS_KEY_ID: ${{ env.AWS_ACCESS_KEY_ID }}
|
|
AWS_SECRET_ACCESS_KEY: ${{ env.AWS_SECRET_ACCESS_KEY }}
|
|
AWS_SESSION_TOKEN: ${{ env.AWS_SESSION_TOKEN }}
|
|
ANTHROPIC_BEDROCK_BASE_URL: ${{ env.ANTHROPIC_BEDROCK_BASE_URL || (env.AWS_REGION && format('https://bedrock-runtime.{0}.amazonaws.com', env.AWS_REGION)) }}
|
|
|
|
# GCP configuration
|
|
ANTHROPIC_VERTEX_PROJECT_ID: ${{ env.ANTHROPIC_VERTEX_PROJECT_ID }}
|
|
CLOUD_ML_REGION: ${{ env.CLOUD_ML_REGION }}
|
|
GOOGLE_APPLICATION_CREDENTIALS: ${{ env.GOOGLE_APPLICATION_CREDENTIALS }}
|
|
ANTHROPIC_VERTEX_BASE_URL: ${{ env.ANTHROPIC_VERTEX_BASE_URL }}
|
|
|
|
# Model-specific regions for Vertex
|
|
VERTEX_REGION_CLAUDE_3_5_HAIKU: ${{ env.VERTEX_REGION_CLAUDE_3_5_HAIKU }}
|
|
VERTEX_REGION_CLAUDE_3_5_SONNET: ${{ env.VERTEX_REGION_CLAUDE_3_5_SONNET }}
|
|
VERTEX_REGION_CLAUDE_3_7_SONNET: ${{ env.VERTEX_REGION_CLAUDE_3_7_SONNET }}
|
|
|
|
- name: Update comment with job link
|
|
if: steps.prepare.outputs.contains_trigger == 'true' && steps.prepare.outputs.claude_comment_id && always()
|
|
shell: bash
|
|
run: |
|
|
bun run ${GITHUB_ACTION_PATH}/src/entrypoints/update-comment-link.ts
|
|
env:
|
|
REPOSITORY: ${{ github.repository }}
|
|
PR_NUMBER: ${{ github.event.issue.number || github.event.pull_request.number }}
|
|
CLAUDE_COMMENT_ID: ${{ steps.prepare.outputs.claude_comment_id }}
|
|
GITHUB_RUN_ID: ${{ github.run_id }}
|
|
GITHUB_TOKEN: ${{ steps.prepare.outputs.GITHUB_TOKEN }}
|
|
GITHUB_EVENT_NAME: ${{ github.event_name }}
|
|
TRIGGER_COMMENT_ID: ${{ github.event.comment.id }}
|
|
CLAUDE_BRANCH: ${{ steps.prepare.outputs.CLAUDE_BRANCH }}
|
|
IS_PR: ${{ github.event.issue.pull_request != null || github.event_name == 'pull_request_review_comment' }}
|
|
BASE_BRANCH: ${{ steps.prepare.outputs.BASE_BRANCH }}
|
|
CLAUDE_SUCCESS: ${{ steps.claude-code.outputs.conclusion == 'success' }}
|
|
OUTPUT_FILE: ${{ steps.claude-code.outputs.execution_file || '' }}
|
|
TRIGGER_USERNAME: ${{ github.event.comment.user.login || github.event.issue.user.login || github.event.pull_request.user.login || github.event.sender.login || github.triggering_actor || github.actor || '' }}
|
|
PREPARE_SUCCESS: ${{ steps.prepare.outcome == 'success' }}
|
|
PREPARE_ERROR: ${{ steps.prepare.outputs.prepare_error || '' }}
|
|
USE_STICKY_COMMENT: ${{ inputs.use_sticky_comment }}
|
|
USE_COMMIT_SIGNING: ${{ inputs.use_commit_signing }}
|
|
|
|
- name: Display Claude Code Report
|
|
if: steps.prepare.outputs.contains_trigger == 'true' && steps.claude-code.outputs.execution_file != ''
|
|
shell: bash
|
|
run: |
|
|
# Try to format the turns, but if it fails, dump the raw JSON
|
|
if bun run ${{ github.action_path }}/src/entrypoints/format-turns.ts "${{ steps.claude-code.outputs.execution_file }}" >> $GITHUB_STEP_SUMMARY 2>/dev/null; then
|
|
echo "Successfully formatted Claude Code report"
|
|
else
|
|
echo "## Claude Code Report (Raw Output)" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo "Failed to format output (please report). Here's the raw JSON:" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo '```json' >> $GITHUB_STEP_SUMMARY
|
|
cat "${{ steps.claude-code.outputs.execution_file }}" >> $GITHUB_STEP_SUMMARY
|
|
echo '```' >> $GITHUB_STEP_SUMMARY
|
|
fi
|
|
|
|
- name: Revoke app token
|
|
if: always() && inputs.github_token == '' && steps.prepare.outputs.skipped_due_to_workflow_validation_mismatch != 'true'
|
|
shell: bash
|
|
run: |
|
|
curl -L \
|
|
-X DELETE \
|
|
-H "Accept: application/vnd.github+json" \
|
|
-H "Authorization: Bearer ${{ steps.prepare.outputs.GITHUB_TOKEN }}" \
|
|
-H "X-GitHub-Api-Version: 2022-11-28" \
|
|
${GITHUB_API_URL:-https://api.github.com}/installation/token
|