name: "Claude Code Action Official" description: "General-purpose Claude agent for GitHub PRs and issues. Can answer questions and implement code changes." 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" branch_prefix: description: "The prefix to use for Claude branches (defaults to 'claude/', use 'claude-' for dash format)" required: false default: "claude/" mode: description: "Execution mode for the action. Valid modes: 'tag' (default) or 'agent'" required: false default: "tag" base_branch: description: "The branch to use as the base/source when creating new branches (defaults to repository default branch)" required: false # Claude Code configuration model: description: "Model to use (provider-specific format required for Bedrock/Vertex)" required: false anthropic_model: description: "DEPRECATED: Use 'model' instead. Model to use (provider-specific format required for Bedrock/Vertex)" required: false allowed_tools: description: "Additional tools for Claude to use (the base GitHub tools will always be included)" required: false default: "" disallowed_tools: description: "Tools that Claude should never use" required: false default: "" custom_instructions: description: "Additional custom instructions to include in the prompt for Claude" required: false default: "" direct_prompt: description: "Direct instruction for Claude (bypasses normal trigger detection)" required: false default: "" override_prompt: description: "Complete replacement of Claude's prompt with custom template (supports variable substitution)" required: false default: "" # New Claude Code settings settings: description: "Path to Claude Code settings JSON file, or settings JSON string" required: false default: "" system_prompt: description: "Override system prompt" required: false default: "" append_system_prompt: description: "Append to system prompt" required: false default: "" claude_env: description: "Custom environment variables to pass to Claude Code execution (YAML multiline format)" required: false default: "" additional_permissions: description: "Additional permissions to enable. Currently supports 'actions: read' for viewing workflow results" required: false default: "" fallback_model: description: "Enable automatic fallback to specified model when default model is overloaded" 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 default: "" gitea_token: description: "Gitea token with repo and pull request permissions (defaults to GITHUB_TOKEN)" required: false path_to_claude_code_executable: description: "Path to a custom Claude Code executable to use instead of installing" required: false default: "" 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" use_node_cache: description: "Whether to use Node.js dependency caching (set to true only for Node.js projects with lock files)" required: false default: "false" max_turns: description: "Maximum number of conversation turns" required: false default: "" timeout_minutes: description: "Timeout in minutes for execution" required: false default: "30" claude_git_name: description: "Git user.name for commits made by Claude" required: false default: "Claude" claude_git_email: description: "Git user.email for commits made by Claude" required: false default: "claude@anthropic.com" 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 }} runs: using: "composite" steps: - name: Install Bun 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: 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 }} 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 }} ALLOWED_TOOLS: ${{ inputs.allowed_tools }} DISALLOWED_TOOLS: ${{ inputs.disallowed_tools }} CUSTOM_INSTRUCTIONS: ${{ inputs.custom_instructions }} DIRECT_PROMPT: ${{ inputs.direct_prompt }} OVERRIDE_PROMPT: ${{ inputs.override_prompt }} ADDITIONAL_PERMISSIONS: ${{ inputs.additional_permissions }} OVERRIDE_GITHUB_TOKEN: ${{ inputs.gitea_token }} GITHUB_TOKEN: ${{ github.token }} GITHUB_RUN_ID: ${{ github.run_id }} GITEA_API_URL: ${{ env.GITHUB_SERVER_URL }} ANTHROPIC_API_KEY: ${{ inputs.anthropic_api_key }} - name: Install Claude if: steps.prepare.outputs.contains_trigger == 'true' shell: bash run: | # 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.117 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 # TODO pass claude_code_executable as input and use it here - name: Run Claude Code id: claude-code if: steps.prepare.outputs.contains_trigger == 'true' uses: anthropics/claude-code-base-action@v0.0.63 with: prompt_file: /tmp/claude-prompts/claude-prompt.txt allowed_tools: ${{ env.ALLOWED_TOOLS }} disallowed_tools: ${{ env.DISALLOWED_TOOLS }} max_turns: ${{ inputs.max_turns }} timeout_minutes: ${{ inputs.timeout_minutes }} model: ${{ inputs.model || inputs.anthropic_model }} mcp_config: ${{ steps.prepare.outputs.mcp_config }} use_bedrock: ${{ inputs.use_bedrock }} use_vertex: ${{ inputs.use_vertex }} anthropic_api_key: ${{ inputs.anthropic_api_key }} claude_code_oauth_token: ${{ inputs.claude_code_oauth_token }} settings: ${{ inputs.settings }} system_prompt: ${{ inputs.system_prompt }} append_system_prompt: ${{ inputs.append_system_prompt }} claude_env: ${{ inputs.claude_env }} fallback_model: ${{ inputs.fallback_model }} use_node_cache: ${{ inputs.use_node_cache }} env: # Core configuration PROMPT_FILE: /tmp/claude-prompts/claude-prompt.txt ALLOWED_TOOLS: ${{ env.ALLOWED_TOOLS }} DISALLOWED_TOOLS: ${{ env.DISALLOWED_TOOLS }} TIMEOUT_MINUTES: ${{ inputs.timeout_minutes }} MODEL: ${{ inputs.model || inputs.anthropic_model }} ANTHROPIC_MODEL: ${{ inputs.model || inputs.anthropic_model }} MCP_CONFIG: ${{ steps.prepare.outputs.mcp_config }} USE_BEDROCK: ${{ inputs.use_bedrock }} USE_VERTEX: ${{ inputs.use_vertex }} ANTHROPIC_API_KEY: ${{ inputs.anthropic_api_key }} CLAUDE_CODE_OAUTH_TOKEN: ${{ inputs.claude_code_oauth_token }} # New settings support SETTINGS: ${{ inputs.settings }} SYSTEM_PROMPT: ${{ inputs.system_prompt }} APPEND_SYSTEM_PROMPT: ${{ inputs.append_system_prompt }} CLAUDE_ENV: ${{ inputs.claude_env }} FALLBACK_MODEL: ${{ inputs.fallback_model }} USE_NODE_CACHE: ${{ inputs.use_node_cache }} # GitHub token for repository access GITHUB_TOKEN: ${{ steps.prepare.outputs.GITHUB_TOKEN }} GITEA_API_URL: ${{ env.GITHUB_SERVER_URL }} # Git configuration CLAUDE_GIT_NAME: ${{ inputs.claude_git_name }} CLAUDE_GIT_EMAIL: ${{ inputs.claude_git_email }} # Provider configuration (for future cloud provider support) ANTHROPIC_BASE_URL: ${{ env.ANTHROPIC_BASE_URL }} 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 }} 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 }} 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 || '' }} GITEA_API_URL: ${{ env.GITHUB_SERVER_URL }} - name: Display Claude Code Report if: steps.prepare.outputs.contains_trigger == 'true' && steps.claude-code.outputs.execution_file != '' shell: bash run: | if [ -f "${{ steps.claude-code.outputs.execution_file }}" ]; then echo "## Claude Code Report" >> $GITHUB_STEP_SUMMARY echo '```json' >> $GITHUB_STEP_SUMMARY cat "${{ steps.claude-code.outputs.execution_file }}" >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY else echo "⚠️ Claude Code execution completed but no report file was generated" >> $GITHUB_STEP_SUMMARY fi