From 59a49d170c94470d444d095ee09b159056581e59 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 4 Sep 2025 11:28:30 -0700 Subject: [PATCH] tmp --- action.yml | 7 +++- docs/faq.md | 16 ++++++- docs/usage.md | 47 +++++++++++---------- src/github/constants.ts | 5 +-- src/github/context.ts | 6 ++- src/github/operations/git-config.ts | 23 ++++------ src/modes/agent/index.ts | 65 +++-------------------------- src/modes/tag/index.ts | 8 +++- test/install-mcp-server.test.ts | 8 +++- test/mockContext.ts | 8 +++- test/permissions.test.ts | 8 +++- 11 files changed, 89 insertions(+), 112 deletions(-) diff --git a/action.yml b/action.yml index 3f47a2f..a6882ff 100644 --- a/action.yml +++ b/action.yml @@ -74,9 +74,13 @@ inputs: required: false default: "false" bot_id: - description: "GitHub user ID to use for git operations when authenticated user cannot be fetched (defaults to github-actions[bot] ID)" + description: "GitHub user ID to use for git operations (defaults to github-actions[bot] ID)" required: false default: "41898282" # github-actions[bot] ID - see src/github/constants.ts + bot_name: + description: "GitHub username to use for git operations (defaults to github-actions[bot])" + required: false + default: "github-actions[bot]" track_progress: description: "Force tag mode with tracking comments for pull_request and issue events. Only applicable to pull_request (opened, synchronize, ready_for_review, reopened) and issue (opened, edited, labeled, assigned) events." required: false @@ -149,6 +153,7 @@ runs: DEFAULT_WORKFLOW_TOKEN: ${{ github.token }} USE_COMMIT_SIGNING: ${{ inputs.use_commit_signing }} BOT_ID: ${{ inputs.bot_id }} + BOT_NAME: ${{ inputs.bot_name }} TRACK_PROGRESS: ${{ inputs.track_progress }} ADDITIONAL_PERMISSIONS: ${{ inputs.additional_permissions }} CLAUDE_ARGS: ${{ inputs.claude_args }} diff --git a/docs/faq.md b/docs/faq.md index a5b11de..a50e2fc 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -32,13 +32,25 @@ The OIDC token is required in order for the Claude GitHub app to function. If yo This error occurs when the action tries to fetch the authenticated user information using a GitHub App installation token. GitHub App tokens have limited access and cannot access the `/user` endpoint, which causes this 403 error. -**Solution**: The action now includes a `bot_id` input that defaults to the github-actions[bot] ID (41898282). This avoids the need to fetch user information. If you need to use a different bot user, you can specify a custom bot_id: +**Solution**: The action now includes `bot_id` and `bot_name` inputs that default to github-actions[bot]. This avoids the need to fetch user information from the API. + +For the default github-actions[bot]: ```yaml - uses: anthropics/claude-code-action@v1 with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} - bot_id: "12345678" # Custom bot user ID + # bot_id and bot_name have sensible defaults, no need to specify +``` + +For custom bots, specify both: + +```yaml +- uses: anthropics/claude-code-action@v1 + with: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + bot_id: "12345678" # Your bot's GitHub user ID + bot_name: "my-bot" # Your bot's username ``` This issue typically only affects agent/automation mode workflows. Interactive workflows (with @claude mentions) don't encounter this issue as they use the comment author's information. diff --git a/docs/usage.md b/docs/usage.md index c18f8a5..c284ddc 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -47,29 +47,30 @@ jobs: ## Inputs -| Input | Description | Required | Default | -| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------- | -------- | ---------- | -| `anthropic_api_key` | Anthropic API key (required for direct API, not needed for Bedrock/Vertex) | No\* | - | -| `claude_code_oauth_token` | Claude Code OAuth token (alternative to anthropic_api_key) | No\* | - | -| `prompt` | Instructions for Claude. Can be a direct prompt or custom template for automation workflows | No | - | -| `track_progress` | Force tag mode with tracking comments. Only works with specific PR/issue events. Preserves GitHub context | No | `false` | -| `claude_args` | Additional arguments to pass directly to Claude CLI (e.g., `--max-turns 10 --model claude-4-0-sonnet-20250805`) | No | "" | -| `base_branch` | The base branch to use for creating new branches (e.g., 'main', 'develop') | No | - | -| `use_sticky_comment` | Use just one comment to deliver PR comments (only applies for pull_request event workflows) | No | `false` | -| `github_token` | GitHub token for Claude to operate with. **Only include this if you're connecting a custom GitHub app of your own!** | 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` | -| `mcp_config` | Additional MCP configuration (JSON string) that merges with the built-in GitHub MCP servers | No | "" | -| `assignee_trigger` | The assignee username that triggers the action (e.g. @claude). Only used for issue assignment | No | - | -| `label_trigger` | The label name that triggers the action when applied to an issue (e.g. "claude") | No | - | -| `trigger_phrase` | The trigger phrase to look for in comments, issue/PR bodies, and issue titles | No | `@claude` | -| `branch_prefix` | The prefix to use for Claude branches (defaults to 'claude/', use 'claude-' for dash format) | No | `claude/` | -| `settings` | Claude Code settings as JSON string or path to settings JSON file | No | "" | -| `additional_permissions` | Additional permissions to enable. Currently supports 'actions: read' for viewing workflow results | No | "" | -| `experimental_allowed_domains` | Restrict network access to these domains only (newline-separated). | No | "" | -| `use_commit_signing` | Enable commit signing using GitHub's commit signature verification. When false, Claude uses standard git commands | No | `false` | -| `bot_id` | GitHub user ID to use for git operations when authenticated user cannot be fetched (defaults to github-actions[bot] ID) | No | `41898282` | -| `allowed_bots` | Comma-separated list of allowed bot usernames, or '\*' to allow all bots. Empty string (default) allows no bots | No | "" | +| Input | Description | Required | Default | +| ------------------------------ | -------------------------------------------------------------------------------------------------------------------- | -------- | --------------------- | +| `anthropic_api_key` | Anthropic API key (required for direct API, not needed for Bedrock/Vertex) | No\* | - | +| `claude_code_oauth_token` | Claude Code OAuth token (alternative to anthropic_api_key) | No\* | - | +| `prompt` | Instructions for Claude. Can be a direct prompt or custom template for automation workflows | No | - | +| `track_progress` | Force tag mode with tracking comments. Only works with specific PR/issue events. Preserves GitHub context | No | `false` | +| `claude_args` | Additional arguments to pass directly to Claude CLI (e.g., `--max-turns 10 --model claude-4-0-sonnet-20250805`) | No | "" | +| `base_branch` | The base branch to use for creating new branches (e.g., 'main', 'develop') | No | - | +| `use_sticky_comment` | Use just one comment to deliver PR comments (only applies for pull_request event workflows) | No | `false` | +| `github_token` | GitHub token for Claude to operate with. **Only include this if you're connecting a custom GitHub app of your own!** | 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` | +| `mcp_config` | Additional MCP configuration (JSON string) that merges with the built-in GitHub MCP servers | No | "" | +| `assignee_trigger` | The assignee username that triggers the action (e.g. @claude). Only used for issue assignment | No | - | +| `label_trigger` | The label name that triggers the action when applied to an issue (e.g. "claude") | No | - | +| `trigger_phrase` | The trigger phrase to look for in comments, issue/PR bodies, and issue titles | No | `@claude` | +| `branch_prefix` | The prefix to use for Claude branches (defaults to 'claude/', use 'claude-' for dash format) | No | `claude/` | +| `settings` | Claude Code settings as JSON string or path to settings JSON file | No | "" | +| `additional_permissions` | Additional permissions to enable. Currently supports 'actions: read' for viewing workflow results | No | "" | +| `experimental_allowed_domains` | Restrict network access to these domains only (newline-separated). | No | "" | +| `use_commit_signing` | Enable commit signing using GitHub's commit signature verification. When false, Claude uses standard git commands | No | `false` | +| `bot_id` | GitHub user ID to use for git operations (defaults to github-actions[bot] ID) | No | `41898282` | +| `bot_name` | GitHub username to use for git operations (defaults to github-actions[bot]) | No | `github-actions[bot]` | +| `allowed_bots` | Comma-separated list of allowed bot usernames, or '\*' to allow all bots. Empty string (default) allows no bots | No | "" | ### Deprecated Inputs diff --git a/src/github/constants.ts b/src/github/constants.ts index f7bfbf4..ff5d8de 100644 --- a/src/github/constants.ts +++ b/src/github/constants.ts @@ -3,10 +3,9 @@ */ /** - * GitHub Actions bot user ID - * This is the official ID for github-actions[bot] used in GitHub repositories + * Claude App bot user ID */ -export const GITHUB_ACTIONS_BOT_ID = 41898282; +export const CLAUDE_APP_BOT_ID = 41898282; /** * GitHub Actions bot username diff --git a/src/github/context.ts b/src/github/context.ts index 6332efb..59ab993 100644 --- a/src/github/context.ts +++ b/src/github/context.ts @@ -8,7 +8,7 @@ import type { PullRequestReviewCommentEvent, WorkflowRunEvent, } from "@octokit/webhooks-types"; -import { GITHUB_ACTIONS_BOT_ID } from "./constants"; +import { CLAUDE_APP_BOT_ID, GITHUB_ACTIONS_BOT_LOGIN } from "./constants"; // Custom types for GitHub Actions events that aren't webhooks export type WorkflowDispatchEvent = { action?: never; @@ -76,6 +76,7 @@ type BaseContext = { useStickyComment: boolean; useCommitSigning: boolean; botId: string; + botName: string; allowedBots: string; trackProgress: boolean; }; @@ -124,7 +125,8 @@ export function parseGitHubContext(): GitHubContext { branchPrefix: process.env.BRANCH_PREFIX ?? "claude/", useStickyComment: process.env.USE_STICKY_COMMENT === "true", useCommitSigning: process.env.USE_COMMIT_SIGNING === "true", - botId: process.env.BOT_ID ?? String(GITHUB_ACTIONS_BOT_ID), + botId: process.env.BOT_ID ?? String(CLAUDE_APP_BOT_ID), + botName: process.env.BOT_NAME ?? GITHUB_ACTIONS_BOT_LOGIN, allowedBots: process.env.ALLOWED_BOTS ?? "", trackProgress: process.env.TRACK_PROGRESS === "true", }, diff --git a/src/github/operations/git-config.ts b/src/github/operations/git-config.ts index 5d759ab..8244e95 100644 --- a/src/github/operations/git-config.ts +++ b/src/github/operations/git-config.ts @@ -8,7 +8,6 @@ import { $ } from "bun"; import type { GitHubContext } from "../context"; import { GITHUB_SERVER_URL } from "../api/config"; -import { GITHUB_ACTIONS_BOT_ID, GITHUB_ACTIONS_BOT_LOGIN } from "../constants"; type GitUser = { login: string; @@ -18,7 +17,7 @@ type GitUser = { export async function configureGitAuth( githubToken: string, context: GitHubContext, - user: GitUser | null, + user: GitUser, ) { console.log("Configuring git authentication for non-signing mode"); @@ -29,20 +28,14 @@ export async function configureGitAuth( ? "users.noreply.github.com" : `users.noreply.${serverUrl.hostname}`; - // Configure git user based on the comment creator + // Configure git user console.log("Configuring git user..."); - if (user) { - const botName = user.login; - const botId = user.id; - console.log(`Setting git user as ${botName}...`); - await $`git config user.name "${botName}"`; - await $`git config user.email "${botId}+${botName}@${noreplyDomain}"`; - console.log(`✓ Set git user as ${botName}`); - } else { - console.log("No user data in comment, using default bot user"); - await $`git config user.name "${GITHUB_ACTIONS_BOT_LOGIN}"`; - await $`git config user.email "${GITHUB_ACTIONS_BOT_ID}+${GITHUB_ACTIONS_BOT_LOGIN}@${noreplyDomain}"`; - } + const botName = user.login; + const botId = user.id; + console.log(`Setting git user as ${botName}...`); + await $`git config user.name "${botName}"`; + await $`git config user.email "${botId}+${botName}@${noreplyDomain}"`; + console.log(`✓ Set git user as ${botName}`); // Remove the authorization header that actions/checkout sets console.log("Removing existing git authentication headers..."); diff --git a/src/modes/agent/index.ts b/src/modes/agent/index.ts index 6a4f1c3..ce526ba 100644 --- a/src/modes/agent/index.ts +++ b/src/modes/agent/index.ts @@ -7,7 +7,6 @@ import { parseAllowedTools } from "./parse-tools"; import { configureGitAuth } from "../../github/operations/git-config"; import type { GitHubContext } from "../../github/context"; import { isEntityContext } from "../../github/context"; -import { GITHUB_ACTIONS_BOT_ID } from "../../github/constants"; /** * Extract GitHub context as environment variables for agent mode @@ -78,66 +77,14 @@ export const agentMode: Mode = { return false; }, - async prepare({ - context, - githubToken, - octokit, - }: ModeOptions): Promise { + async prepare({ context, githubToken }: ModeOptions): Promise { // Configure git authentication for agent mode (same as tag mode) if (!context.inputs.useCommitSigning) { - let user = null; - - // Check if bot_id is provided - console.log("yolobot", context.inputs.botId); - const botId = context.inputs.botId; - if (botId && botId !== String(GITHUB_ACTIONS_BOT_ID)) { - // Use custom bot_id - try to fetch user info - try { - const { data: userData } = await octokit.rest.users.getByUsername({ - username: context.actor, - }); - user = { - login: userData.login, - id: userData.id, - }; - console.log("yolo user", user); - } catch (error) { - console.log( - `Could not fetch user info for ${context.actor}, using bot_id ${botId}`, - ); - user = { - login: context.actor, - id: parseInt(botId), - }; - } - } else { - // Try to get authenticated user, but don't fail if using GitHub App token - try { - const { data: authenticatedUser } = - await octokit.rest.users.getAuthenticated(); - user = { - login: authenticatedUser.login, - id: authenticatedUser.id, - }; - console.log("yolo user auth", user); - } catch (error: any) { - // Check if this is a GitHub App token limitation - if ( - error?.status === 403 && - error?.message?.includes("Resource not accessible by integration") - ) { - console.log( - "Using GitHub App token - defaulting to github-actions[bot] for git operations", - ); - } else { - console.error( - "Failed to get authenticated user:", - error?.message || error, - ); - } - // User will remain null, which will trigger default behavior in configureGitAuth - } - } + // Use bot_id and bot_name from inputs directly + const user = { + login: context.inputs.botName, + id: parseInt(context.inputs.botId), + }; try { // Use the shared git configuration function diff --git a/src/modes/tag/index.ts b/src/modes/tag/index.ts index c8fc12a..4d997f2 100644 --- a/src/modes/tag/index.ts +++ b/src/modes/tag/index.ts @@ -89,8 +89,14 @@ export const tagMode: Mode = { // Configure git authentication if not using commit signing if (!context.inputs.useCommitSigning) { + // Use bot_id and bot_name from inputs directly + const user = { + login: context.inputs.botName, + id: parseInt(context.inputs.botId), + }; + try { - await configureGitAuth(githubToken, context, commentData.user); + await configureGitAuth(githubToken, context, user); } catch (error) { console.error("Failed to configure git authentication:", error); throw error; diff --git a/test/install-mcp-server.test.ts b/test/install-mcp-server.test.ts index bdeae97..1f8dbfc 100644 --- a/test/install-mcp-server.test.ts +++ b/test/install-mcp-server.test.ts @@ -2,7 +2,10 @@ import { describe, test, expect, beforeEach, afterEach, spyOn } from "bun:test"; import { prepareMcpConfig } from "../src/mcp/install-mcp-server"; import * as core from "@actions/core"; import type { ParsedGitHubContext } from "../src/github/context"; -import { GITHUB_ACTIONS_BOT_ID } from "../src/github/constants"; +import { + CLAUDE_APP_BOT_ID, + GITHUB_ACTIONS_BOT_LOGIN, +} from "../src/github/constants"; describe("prepareMcpConfig", () => { let consoleInfoSpy: any; @@ -32,7 +35,8 @@ describe("prepareMcpConfig", () => { branchPrefix: "", useStickyComment: false, useCommitSigning: false, - botId: String(GITHUB_ACTIONS_BOT_ID), + botId: String(CLAUDE_APP_BOT_ID), + botName: GITHUB_ACTIONS_BOT_LOGIN, allowedBots: "", trackProgress: false, }, diff --git a/test/mockContext.ts b/test/mockContext.ts index effc23b..d4f0698 100644 --- a/test/mockContext.ts +++ b/test/mockContext.ts @@ -9,7 +9,10 @@ import type { PullRequestReviewEvent, PullRequestReviewCommentEvent, } from "@octokit/webhooks-types"; -import { GITHUB_ACTIONS_BOT_ID } from "../src/github/constants"; +import { + CLAUDE_APP_BOT_ID, + GITHUB_ACTIONS_BOT_LOGIN, +} from "../src/github/constants"; const defaultInputs = { prompt: "", @@ -19,7 +22,8 @@ const defaultInputs = { branchPrefix: "claude/", useStickyComment: false, useCommitSigning: false, - botId: String(GITHUB_ACTIONS_BOT_ID), + botId: String(CLAUDE_APP_BOT_ID), + botName: GITHUB_ACTIONS_BOT_LOGIN, allowedBots: "", trackProgress: false, }; diff --git a/test/permissions.test.ts b/test/permissions.test.ts index f4d2ea0..1a2fae1 100644 --- a/test/permissions.test.ts +++ b/test/permissions.test.ts @@ -2,7 +2,10 @@ import { describe, expect, test, spyOn, beforeEach, afterEach } from "bun:test"; import * as core from "@actions/core"; import { checkWritePermissions } from "../src/github/validation/permissions"; import type { ParsedGitHubContext } from "../src/github/context"; -import { GITHUB_ACTIONS_BOT_ID } from "../src/github/constants"; +import { + CLAUDE_APP_BOT_ID, + GITHUB_ACTIONS_BOT_LOGIN, +} from "../src/github/constants"; describe("checkWritePermissions", () => { let coreInfoSpy: any; @@ -68,7 +71,8 @@ describe("checkWritePermissions", () => { branchPrefix: "claude/", useStickyComment: false, useCommitSigning: false, - botId: String(GITHUB_ACTIONS_BOT_ID), + botId: String(CLAUDE_APP_BOT_ID), + botName: GITHUB_ACTIONS_BOT_LOGIN, allowedBots: "", trackProgress: false, },