diff --git a/base-action/README.md b/base-action/README.md index 78568439..f765a182 100644 --- a/base-action/README.md +++ b/base-action/README.md @@ -22,7 +22,7 @@ Add the following to your workflow file: uses: anthropics/claude-code-base-action@beta with: prompt: "Your prompt here" - allowed_tools: "Bash(git:*),View,GlobTool,GrepTool,BatchTool" + claude_args: '--allowedTools "Bash(git:*),Read,Glob,Grep"' anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} # Or using a prompt from a file @@ -30,7 +30,7 @@ Add the following to your workflow file: uses: anthropics/claude-code-base-action@beta with: prompt_file: "/path/to/prompt.txt" - allowed_tools: "Bash(git:*),View,GlobTool,GrepTool,BatchTool" + claude_args: '--allowedTools "Bash(git:*),Read,Glob,Grep"' anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} # Or limiting the conversation turns @@ -38,8 +38,9 @@ Add the following to your workflow file: uses: anthropics/claude-code-base-action@beta with: prompt: "Your prompt here" - allowed_tools: "Bash(git:*),View,GlobTool,GrepTool,BatchTool" - max_turns: "5" # Limit conversation to 5 turns + claude_args: | + --allowedTools "Bash(git:*),Read,Glob,Grep" + --max-turns 5 anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} # Using custom system prompts @@ -47,8 +48,9 @@ Add the following to your workflow file: uses: anthropics/claude-code-base-action@beta with: prompt: "Build a REST API" - system_prompt: "You are a senior backend engineer. Focus on security, performance, and maintainability." - allowed_tools: "Bash(git:*),View,GlobTool,GrepTool,BatchTool" + claude_args: | + --system-prompt "You are a senior backend engineer. Focus on security, performance, and maintainability." + --allowedTools "Bash(git:*),Read,Glob,Grep" anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} # Or appending to the default system prompt @@ -56,8 +58,9 @@ Add the following to your workflow file: uses: anthropics/claude-code-base-action@beta with: prompt: "Create a database schema" - append_system_prompt: "After writing code, be sure to code review yourself." - allowed_tools: "Bash(git:*),View,GlobTool,GrepTool,BatchTool" + claude_args: | + --append-system-prompt "After writing code, be sure to code review yourself." + --allowedTools "Bash(git:*),Read,Glob,Grep" anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} # Using custom environment variables @@ -65,11 +68,15 @@ Add the following to your workflow file: uses: anthropics/claude-code-base-action@beta with: prompt: "Deploy to staging environment" - claude_env: | - ENVIRONMENT: staging - API_URL: https://api-staging.example.com - DEBUG: true - allowed_tools: "Bash(git:*),View,GlobTool,GrepTool,BatchTool" + settings: | + { + "env": { + "ENVIRONMENT": "staging", + "API_URL": "https://api-staging.example.com", + "DEBUG": "true" + } + } + claude_args: '--allowedTools "Bash(git:*),Read,Glob,Grep"' anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} # Using fallback model for handling API errors @@ -77,9 +84,10 @@ Add the following to your workflow file: uses: anthropics/claude-code-base-action@beta with: prompt: "Review and fix TypeScript errors" - model: "claude-opus-4-1-20250805" - fallback_model: "claude-sonnet-4-20250514" - allowed_tools: "Bash(git:*),View,GlobTool,GrepTool,BatchTool" + claude_args: | + --model "claude-opus-4-1-20250805" + --fallback-model "claude-sonnet-4-20250514" + --allowedTools "Bash(git:*),Read,Glob,Grep" anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} # Using OAuth token instead of API key @@ -87,7 +95,7 @@ Add the following to your workflow file: uses: anthropics/claude-code-base-action@beta with: prompt: "Update dependencies" - allowed_tools: "Bash(git:*),View,GlobTool,GrepTool,BatchTool" + claude_args: '--allowedTools "Bash(git:*),Read,Glob,Grep"' claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} ``` @@ -114,32 +122,28 @@ Do not set `anthropic_api_key` or `claude_code_oauth_token` alongside the federa ## Inputs -| Input | Description | Required | Default | -| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------- | -------- | ---------------------------- | -| `prompt` | The prompt to send to Claude Code | No\* | '' | -| `prompt_file` | Path to a file containing the prompt to send to Claude Code | No\* | '' | -| `allowed_tools` | Comma-separated list of allowed tools for Claude Code to use | No | '' | -| `disallowed_tools` | Comma-separated list of disallowed tools that Claude Code cannot use | No | '' | -| `max_turns` | Maximum number of conversation turns (default: no limit) | No | '' | -| `mcp_config` | Path to the MCP configuration JSON file, or MCP configuration JSON string | No | '' | -| `settings` | Path to Claude Code settings JSON file, or settings JSON string | No | '' | -| `system_prompt` | Override system prompt | No | '' | -| `append_system_prompt` | Append to system prompt | No | '' | -| `claude_env` | Custom environment variables to pass to Claude Code execution (YAML multiline format) | No | '' | -| `model` | Model to use (provider-specific format required for Bedrock/Vertex) | No | 'claude-4-0-sonnet-20250219' | -| `anthropic_model` | DEPRECATED: Use 'model' instead | No | 'claude-4-0-sonnet-20250219' | -| `fallback_model` | Enable automatic fallback to specified model when default model is overloaded | No | '' | -| `anthropic_api_key` | Anthropic API key (required for direct Anthropic API) | No | '' | -| `claude_code_oauth_token` | Claude Code OAuth token (alternative to anthropic_api_key) | No | '' | -| `anthropic_federation_rule_id` | Workload identity federation rule ID (fdrl\_...). Requires `id-token: write` permission | No | '' | -| `anthropic_organization_id` | Anthropic organization UUID used for workload identity federation | No | '' | -| `anthropic_service_account_id` | Service account ID (svac\_...) the federated token acts as (optional) | No | '' | -| `anthropic_workspace_id` | Workspace ID (wrkspc\_...) for federation. Optional when the rule targets a single workspace | No | '' | -| `anthropic_oidc_audience` | Audience to request on the GitHub OIDC token. Defaults to https://api.anthropic.com | No | '' | -| `use_bedrock` | Use Amazon Bedrock with OIDC authentication instead of direct Anthropic API | No | 'false' | -| `use_vertex` | Use Google Vertex AI with OIDC authentication instead of direct Anthropic API | No | 'false' | -| `use_node_cache` | Whether to use Node.js dependency caching (set to true only for Node.js projects with lock files) | No | 'false' | -| `show_full_output` | Show full JSON output (⚠️ May expose secrets - see [security docs](../docs/security.md#️-full-output-security-warning)) | No | 'false'\*\* | +| Input | Description | Required | Default | +| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -------- | ------------- | +| `prompt` | The prompt to send to Claude Code | No\* | `''` | +| `prompt_file` | Path to a file containing the prompt to send to Claude Code | No\* | `''` | +| `settings` | Claude Code settings as a JSON string or path to a settings JSON file | No | `''` | +| `claude_args` | Additional arguments to pass directly to the Claude CLI | No | `''` | +| `anthropic_api_key` | Anthropic API key for direct Anthropic API authentication | No | `''` | +| `claude_code_oauth_token` | Claude Code OAuth token as an alternative to an Anthropic API key | No | `''` | +| `anthropic_federation_rule_id` | Workload identity federation rule ID (fdrl\_...). Requires `id-token: write` permission | No | `''` | +| `anthropic_organization_id` | Anthropic organization UUID used for workload identity federation | No | `''` | +| `anthropic_service_account_id` | Service account ID (svac\_...) the federated token acts as | No | `''` | +| `anthropic_workspace_id` | Workspace ID (wrkspc\_...) for federation | No | `''` | +| `anthropic_oidc_audience` | Audience for the GitHub OIDC token request | No | `''` | +| `use_bedrock` | Use Amazon Bedrock with OIDC authentication | No | `'false'` | +| `use_vertex` | Use Google Vertex AI with OIDC authentication | No | `'false'` | +| `use_foundry` | Use Microsoft Foundry with OIDC authentication | No | `'false'` | +| `use_node_cache` | Enable Node.js dependency caching for projects with lock files | No | `'false'` | +| `path_to_claude_code_executable` | Path to a custom Claude Code executable | No | `''` | +| `path_to_bun_executable` | Path to a custom Bun executable | No | `''` | +| `show_full_output` | Show full JSON output (⚠️ May expose secrets - see [security docs](../docs/security.md#️-full-output-security-warning)) | No | `'false'`\*\* | +| `plugins` | Newline-separated Claude Code plugin names to install | No | `''` | +| `plugin_marketplaces` | Newline-separated plugin marketplace Git URLs to install | No | `''` | \*Either `prompt` or `prompt_file` must be provided, but not both. @@ -176,55 +180,28 @@ Example usage: ## Custom Environment Variables -You can pass custom environment variables to Claude Code execution using the `claude_env` input. This allows Claude to access environment-specific configuration during its execution. - -The `claude_env` input accepts YAML multiline format with key-value pairs: +You can pass custom environment variables to Claude Code through the `env` object in `settings`: ```yaml - name: Deploy with custom environment uses: anthropics/claude-code-base-action@beta with: prompt: "Deploy the application to the staging environment" - claude_env: | - ENVIRONMENT: staging - API_BASE_URL: https://api-staging.example.com - DATABASE_URL: ${{ secrets.STAGING_DB_URL }} - DEBUG: true - LOG_LEVEL: debug - allowed_tools: "Bash(git:*),View,GlobTool,GrepTool,BatchTool" + settings: | + { + "env": { + "ENVIRONMENT": "staging", + "API_BASE_URL": "https://api-staging.example.com", + "DATABASE_URL": "${{ secrets.STAGING_DB_URL }}", + "DEBUG": "true", + "LOG_LEVEL": "debug" + } + } + claude_args: '--allowedTools "Bash(git:*),Read,Glob,Grep"' anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} ``` -### Features: - -- **YAML Format**: Use standard YAML key-value syntax (`KEY: value`) -- **Multiline Support**: Define multiple environment variables in a single input -- **Comments**: Lines starting with `#` are ignored -- **GitHub Secrets**: Can reference GitHub secrets using `${{ secrets.SECRET_NAME }}` -- **Runtime Access**: Environment variables are available to Claude during execution - -### Example Use Cases: - -```yaml -# Development configuration -claude_env: | - NODE_ENV: development - API_URL: http://localhost:3000 - DEBUG: true - -# Production deployment -claude_env: | - NODE_ENV: production - API_URL: https://api.example.com - DATABASE_URL: ${{ secrets.PROD_DB_URL }} - REDIS_URL: ${{ secrets.REDIS_URL }} - -# Feature flags and configuration -claude_env: | - FEATURE_NEW_UI: enabled - MAX_RETRIES: 3 - TIMEOUT_MS: 5000 -``` +The `settings` input accepts either inline JSON or a path to a settings JSON file. Values in the `env` object are available during the Claude Code session and can reference GitHub secrets. ## Using Settings Configuration @@ -240,7 +217,7 @@ Provide a path to a JSON file containing Claude Code settings: with: prompt: "Your prompt here" settings: "path/to/settings.json" - allowed_tools: "Bash(git:*),View,GlobTool,GrepTool,BatchTool" + claude_args: '--allowedTools "Bash(git:*),Read,Glob,Grep"' anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} ``` @@ -274,7 +251,7 @@ Provide the settings configuration directly as a JSON string: }] } } - allowed_tools: "Bash(git:*),View,GlobTool,GrepTool,BatchTool" + claude_args: '--allowedTools "Bash(git:*),Read,Glob,Grep"' anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} ``` @@ -302,8 +279,9 @@ Provide a path to a JSON file containing MCP configuration: uses: anthropics/claude-code-base-action@beta with: prompt: "Your prompt here" - mcp_config: "path/to/mcp-config.json" - allowed_tools: "Bash(git:*),View,GlobTool,GrepTool,BatchTool" + claude_args: | + --mcp-config "path/to/mcp-config.json" + --allowedTools "Bash(git:*),Read,Glob,Grep" anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} ``` @@ -316,19 +294,9 @@ Provide the MCP configuration directly as a JSON string: uses: anthropics/claude-code-base-action@beta with: prompt: "Your prompt here" - mcp_config: | - { - "mcpServers": { - "server-name": { - "command": "node", - "args": ["./server.js"], - "env": { - "API_KEY": "your-api-key" - } - } - } - } - allowed_tools: "Bash(git:*),View,GlobTool,GrepTool,BatchTool" + claude_args: >- + --mcp-config '{"mcpServers":{"server-name":{"command":"node","args":["./server.js"],"env":{"API_KEY":"your-api-key"}}}}' + --allowedTools "Bash(git:*),Read,Glob,Grep" anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} ``` @@ -356,8 +324,9 @@ You can combine MCP config with other inputs like allowed tools: uses: anthropics/claude-code-base-action@beta with: prompt: "Access the custom MCP server and use its tools" - mcp_config: "mcp-config.json" - allowed_tools: "Bash(git:*),View,mcp__server-name__custom_tool" + claude_args: | + --mcp-config "mcp-config.json" + --allowedTools "Bash(git:*),Read,mcp__server-name__custom_tool" anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} ``` @@ -384,7 +353,7 @@ jobs: uses: anthropics/claude-code-base-action@beta with: prompt: "Review the PR changes. Focus on code quality, potential bugs, and performance issues. Suggest improvements where appropriate. Write your review as markdown text." - allowed_tools: "Bash(git diff --name-only HEAD~1),Bash(git diff HEAD~1),View,GlobTool,GrepTool,Write" + claude_args: '--allowedTools "Bash(git diff --name-only HEAD~1),Bash(git diff HEAD~1),Read,Glob,Grep,Write"' anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} - name: Extract and Comment PR Review @@ -472,7 +441,7 @@ Use provider-specific model names based on your chosen provider: uses: anthropics/claude-code-base-action@beta with: prompt: "Your prompt here" - model: "claude-3-7-sonnet-20250219" + claude_args: "--model claude-3-7-sonnet-20250219" anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} # For Amazon Bedrock (requires OIDC authentication) @@ -486,7 +455,7 @@ Use provider-specific model names based on your chosen provider: uses: anthropics/claude-code-base-action@beta with: prompt: "Your prompt here" - model: "anthropic.claude-3-7-sonnet-20250219-v1:0" + claude_args: "--model anthropic.claude-3-7-sonnet-20250219-v1:0" use_bedrock: "true" # For Google Vertex AI (requires OIDC authentication) @@ -500,7 +469,7 @@ Use provider-specific model names based on your chosen provider: uses: anthropics/claude-code-base-action@beta with: prompt: "Your prompt here" - model: "claude-3-7-sonnet@20250219" + claude_args: "--model claude-3-7-sonnet@20250219" use_vertex: "true" ``` @@ -520,8 +489,9 @@ This example shows how to use OIDC authentication with AWS Bedrock: with: prompt: "Your prompt here" use_bedrock: "true" - model: "anthropic.claude-3-7-sonnet-20250219-v1:0" - allowed_tools: "Bash(git:*),View,GlobTool,GrepTool,BatchTool" + claude_args: | + --model "anthropic.claude-3-7-sonnet-20250219-v1:0" + --allowedTools "Bash(git:*),Read,Glob,Grep" ``` ## Example: Using OIDC Authentication for GCP Vertex AI @@ -540,8 +510,9 @@ This example shows how to use OIDC authentication with GCP Vertex AI: with: prompt: "Your prompt here" use_vertex: "true" - model: "claude-3-7-sonnet@20250219" - allowed_tools: "Bash(git:*),View,GlobTool,GrepTool,BatchTool" + claude_args: | + --model "claude-3-7-sonnet@20250219" + --allowedTools "Bash(git:*),Read,Glob,Grep" ``` ## Security Best Practices diff --git a/base-action/test/readme.test.ts b/base-action/test/readme.test.ts new file mode 100644 index 00000000..f82a9e1a --- /dev/null +++ b/base-action/test/readme.test.ts @@ -0,0 +1,50 @@ +import { readFileSync } from "node:fs"; +import { describe, expect, test } from "bun:test"; + +const actionMetadata = readFileSync( + new URL("../action.yml", import.meta.url), + "utf8", +); +const readme = readFileSync(new URL("../README.md", import.meta.url), "utf8"); + +describe("base action README", () => { + test("should document every input declared in the action metadata", () => { + const inputMetadata = actionMetadata.match( + /^inputs:\n([\s\S]*?)^outputs:/m, + )?.[1]; + const inputReference = readme.match( + /^## Inputs\n([\s\S]*?)^## Outputs/m, + )?.[1]; + + expect(inputMetadata).toBeDefined(); + expect(inputReference).toBeDefined(); + + const declaredInputs = [ + ...(inputMetadata?.matchAll(/^ ([a-z0-9_]+):$/gm) ?? []), + ].map((match) => match[1]); + const documentedInputs = [ + ...(inputReference?.matchAll(/^\| `([^`]+)`/gm) ?? []), + ].map((match) => match[1]); + + expect(documentedInputs).toEqual(declaredInputs); + }); + + test("should not use removed legacy inputs in workflow examples", () => { + const removedInputs = [ + "allowed_tools", + "disallowed_tools", + "max_turns", + "mcp_config", + "system_prompt", + "append_system_prompt", + "claude_env", + "model", + "anthropic_model", + "fallback_model", + ]; + + for (const input of removedInputs) { + expect(readme).not.toMatch(new RegExp(`^\\s+${input}:`, "m")); + } + }); +});