From 6e2bd52842c65e914eba5c8badd17560bd26b5de Mon Sep 17 00:00:00 2001 From: Ashwin Bhat Date: Sun, 5 Apr 2026 07:42:02 -0700 Subject: [PATCH] fix: pin bun runtime config and improve log hygiene (#1174) * fix: pin bun runtime config and improve log hygiene * snapshot all SENSITIVE_PATHS to .claude-pr/, not just .claude/ --- action.yml | 15 ++++++++++++--- base-action/src/run-claude-sdk.ts | 2 +- bunfig.toml | 2 ++ src/github/operations/restore-config.ts | 20 +++++++++++++------- src/github/token.ts | 1 + 5 files changed, 29 insertions(+), 11 deletions(-) create mode 100644 bunfig.toml diff --git a/action.yml b/action.yml index 0bbe537..28eca07 100644 --- a/action.yml +++ b/action.yml @@ -227,7 +227,10 @@ runs: id: run shell: bash run: | - bun run ${GITHUB_ACTION_PATH}/src/entrypoints/run.ts + bun --no-env-file \ + --config="${GITHUB_ACTION_PATH}/bunfig.toml" \ + --tsconfig-override="${GITHUB_ACTION_PATH}/tsconfig.json" \ + run ${GITHUB_ACTION_PATH}/src/entrypoints/run.ts env: # Prepare inputs MODE: ${{ inputs.mode }} @@ -324,7 +327,10 @@ runs: if: always() && inputs.ssh_signing_key != '' shell: bash run: | - bun run ${GITHUB_ACTION_PATH}/src/entrypoints/cleanup-ssh-signing.ts + bun --no-env-file \ + --config="${GITHUB_ACTION_PATH}/bunfig.toml" \ + --tsconfig-override="${GITHUB_ACTION_PATH}/tsconfig.json" \ + run ${GITHUB_ACTION_PATH}/src/entrypoints/cleanup-ssh-signing.ts - name: Post buffered inline comments if: always() && inputs.classify_inline_comments != 'false' @@ -336,7 +342,10 @@ runs: PR_NUMBER: ${{ github.event.pull_request.number || github.event.issue.number }} ANTHROPIC_API_KEY: ${{ inputs.anthropic_api_key }} run: | - bun run ${GITHUB_ACTION_PATH}/src/entrypoints/post-buffered-inline-comments.ts + bun --no-env-file \ + --config="${GITHUB_ACTION_PATH}/bunfig.toml" \ + --tsconfig-override="${GITHUB_ACTION_PATH}/tsconfig.json" \ + run ${GITHUB_ACTION_PATH}/src/entrypoints/post-buffered-inline-comments.ts - name: Revoke app token if: always() && inputs.github_token == '' && steps.run.outputs.github_token != '' && steps.run.outputs.skipped_due_to_workflow_validation_mismatch != 'true' diff --git a/base-action/src/run-claude-sdk.ts b/base-action/src/run-claude-sdk.ts index d032f93..e37184a 100644 --- a/base-action/src/run-claude-sdk.ts +++ b/base-action/src/run-claude-sdk.ts @@ -151,7 +151,7 @@ export async function runClaudeWithSdk( console.log(`Running Claude with prompt from file: ${promptPath}`); // Log SDK options without env (which could contain sensitive data) - const { env, ...optionsToLog } = sdkOptions; + const { env, extraArgs, ...optionsToLog } = sdkOptions; console.log("SDK options:", JSON.stringify(optionsToLog, null, 2)); const messages: SDKMessage[] = []; diff --git a/bunfig.toml b/bunfig.toml new file mode 100644 index 0000000..1b21ab2 --- /dev/null +++ b/bunfig.toml @@ -0,0 +1,2 @@ +# Intentionally minimal. action.yml pins --config to this file so bun resolves +# its runtime config from the action directory rather than the workspace. diff --git a/src/github/operations/restore-config.ts b/src/github/operations/restore-config.ts index c1ff004..f4fffe6 100644 --- a/src/github/operations/restore-config.ts +++ b/src/github/operations/restore-config.ts @@ -15,6 +15,9 @@ const SENSITIVE_PATHS = [ ".claude.json", ".gitmodules", ".ripgreprc", + "CLAUDE.md", + "CLAUDE.local.md", + ".husky", ]; /** @@ -44,16 +47,19 @@ export function restoreConfigFromBase(baseBranch: string): void { `Restoring ${SENSITIVE_PATHS.join(", ")} from origin/${baseBranch} (PR head is untrusted)`, ); - // Snapshot the PR's .claude/ tree to .claude-pr/ before deleting it. - // This lets review agents inspect what the PR actually changes (CLAUDE.md, - // settings, hooks, MCP configs) without those files ever being executed. - // The snapshot is taken before the security delete so it captures the + // Snapshot every PR-authored sensitive path into .claude-pr/ before deletion + // so review agents can inspect what the PR changes without those files ever + // being executed. Captured before the security delete so it reflects the // PR-authored version. rmSync(".claude-pr", { recursive: true, force: true }); - if (existsSync(".claude")) { - cpSync(".claude", ".claude-pr", { recursive: true }); + for (const p of SENSITIVE_PATHS) { + if (existsSync(p)) { + cpSync(p, `.claude-pr/${p}`, { recursive: true }); + } + } + if (existsSync(".claude-pr")) { console.log( - "Preserved PR's .claude/ → .claude-pr/ for review agents (not executed)", + "Preserved PR's sensitive paths → .claude-pr/ for review agents (not executed)", ); } diff --git a/src/github/token.ts b/src/github/token.ts index 51dd795..ddf8eee 100644 --- a/src/github/token.ts +++ b/src/github/token.ts @@ -148,6 +148,7 @@ export async function setupGitHubToken(): Promise { }, ); console.log("App token successfully obtained"); + core.setSecret(appToken); console.log("Using GITHUB_TOKEN from OIDC"); return appToken;