Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Claude

# Runs a Claude Code session when a collaborator mentions "@claude" on a pull
# request comment or review. Claude reads the triggering comment, works on the
# PR's current head, pushes a scoped fix to the PR branch, and replies in the
# thread. Unlike a subscribed chat session, this fires on the webhook every
# time, so it keeps working after the session that opened the PR has ended.

on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
pull_request_review:
types: [submitted]

# Least privilege by default; the job widens only what Claude needs.
permissions:
contents: read

jobs:
claude:
name: Respond to @claude
runs-on: ubuntu-24.04
# Only run when a human (not a bot) mentions @claude on a pull request, so
# ordinary comments — and Claude's own replies — never spin up a runner.
if: >
(github.event_name == 'issue_comment' &&
github.event.issue.pull_request != null &&
github.event.comment.user.type != 'Bot' &&
contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' &&
github.event.comment.user.type != 'Bot' &&
contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review' &&
github.event.review.user.type != 'Bot' &&
github.event.review.body != null &&
contains(github.event.review.body, '@claude'))
Comment on lines +27 to +38

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the workflow around the referenced lines.
wc -l .github/workflows/claude.yml
cat -n .github/workflows/claude.yml | sed -n '1,220p'

# Look for any authorization / collaborator / association checks in the workflow.
rg -n "association|OWNER|MEMBER|COLLABORATOR|trusted|collaborator|bot|`@claude`|permissions:|contents: write|pull-requests: write|issues: write|anthropic|api key|token" .github/workflows/claude.yml

Repository: BigSimmo/Database

Length of output: 4863


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for any collaborator/association checks or docs around the Claude workflow.
rg -n "claude-code-action|repository association|COLLABORATOR|MEMBER|OWNER|trusted collaborator|`@claude`|ANTHROPIC_API_KEY|claude_code_oauth_token" . -g '!**/node_modules/**' -g '!**/dist/**' -g '!**/build/**'

# Show any workflow/docs files that mention Claude integration.
git ls-files | rg '(^|/)(README|docs?|\.github/workflows/.*claude.*|.*claude.*)\.(md|yml|yaml)$'

Repository: BigSimmo/Database

Length of output: 28335


Require collaborator-only gating before invoking Claude .github/workflows/claude.yml:27-38

The job still accepts any non-bot @claude mention and then runs with write permissions plus ANTHROPIC_API_KEY. Restrict each trigger to trusted repository associations like OWNER, MEMBER, or COLLABORATOR before allowing it to run.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/claude.yml around lines 27 - 38, The Claude workflow
trigger condition currently allows any non-bot user to invoke the job. Update
the issue_comment, pull_request_review_comment, and pull_request_review branches
in the workflow if expression to require the corresponding user’s association to
be OWNER, MEMBER, or COLLABORATOR, while preserving the existing `@claude` and
event-specific checks.

permissions:
contents: write # push the scoped fix to the PR branch
pull-requests: write # comment back and update the PR
issues: write # comment on the PR conversation thread
id-token: write # OIDC used by the action
actions: read # read CI results for context
concurrency:
group: claude-${{ github.event.issue.number || github.event.pull_request.number }}
cancel-in-progress: false
timeout-minutes: 30
env:
# Assigned to job env so a step-level `if` can detect an unconfigured
# secret and skip gracefully instead of hard-failing the check.
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
steps:
- name: Warn when the API key is not configured
if: ${{ env.ANTHROPIC_API_KEY == '' }}
run: echo "::warning title=Claude::ANTHROPIC_API_KEY secret is not configured; skipping. Add ANTHROPIC_API_KEY (or switch the action input to claude_code_oauth_token) in repository secrets so @claude mentions are handled."
- name: Checkout repository
if: ${{ env.ANTHROPIC_API_KEY != '' }}
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 1
- name: Run Claude Code
if: ${{ env.ANTHROPIC_API_KEY != '' }}
uses: anthropics/claude-code-action@af0559ee4f514d1ef21826982bed13f7edc3c35e # v1.0.178
Comment on lines +57 to +64

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

file=".github/workflows/claude.yml"

echo "=== file listing ==="
git ls-files "$file"

echo
echo "=== line count ==="
wc -l "$file"

echo
echo "=== relevant excerpt ==="
sed -n '1,220p' "$file"

Repository: BigSimmo/Database

Length of output: 3354


🌐 Web query:

actions/checkout default ref issue_comment github.event.ref default branch documentation claude-code-action current PR head checkout

💡 Result:

The actions/checkout action has specific default behaviors regarding what it checks out depending on the triggering event, and navigating these defaults—particularly for issue_comment events or pull request contexts—often requires explicit configuration [1][2][3]. Default Behavior By default, actions/checkout checks out the reference or SHA that triggered the workflow [1][3]. For events that do not have a specific reference (or when the context is ambiguous), it falls back to the default branch [1][2][3]. Notably, for pull_request events, the default is to checkout the merge commit (refs/pull/PULL_REQUEST_NUMBER/merge), not the individual head branch of the pull request [4][5]. Issue Comment and Pull Request Contexts When a workflow is triggered by an issue_comment event, GitHub does not automatically checkout the pull request branch [6][2]. To checkout the source branch of a pull request from an issue_comment event, you must dynamically determine the PR head reference and pass it to the ref input [6]: 1. Use actions/github-script to retrieve the pull request head ref [6]. 2. Pass that reference to actions/checkout [6]. Example pattern to checkout the PR branch or fallback to default: - uses: actions/github-script@v7 id: pr if: ${{ github.event.issue.pull_request }} with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const { data: pr } = await github.rest.pulls.get({ owner: context.repo.owner, repo: context.repo.repo, pull_number: context.payload.issue.number }); core.setOutput('head_ref', pr.head.ref); - uses: actions/checkout@v4 with: ref: ${{ github.event.issue.pull_request && steps.pr.outputs.head_ref || github.ref }} Claude Code Action Configuration For users of anthropics/claude-code-action, the action expects a repository checkout to exist before it runs [7][8]. Standard practice is to run actions/checkout@v4 before the Claude step [7][8]. If you encounter failures related to branch setup (e.g., when using persist-credentials: false), it is often because the action attempts to fetch origin before configuring its own authentication; in such cases, ensure proper credential persistence or follow the maintainer-recommended workarounds for your specific environment [9].

Citations:


🌐 Web query:

anthropics claude-code-action README current PR head checkout issue_comment actions/checkout default ref

💡 Result:

In GitHub Actions workflows using anthropics/claude-code-action, the interaction between actions/checkout and the action itself is a critical security and functional consideration [1][2]. For workflows triggered by events like issue_comment or pull_request_target, it is recommended to check out the base repository's code at the workspace root by default [1][2]. Because claude-code-action performs actor permission checks and restores project configuration from the base ref, checking out an untrusted head ref (such as github.event.pull_request.head.sha) directly into the workspace root can pose security risks when running with the base repository's secrets [1][2]. To work safely with Pull Request files: 1. Preferred approach: Check out the base ref (the default) at the workspace root [1][2]. yaml - uses: actions/checkout@v6 # No ref specified → defaults to base branch - uses: anthropics/claude-code-action@v1 2. Accessing PR files: If the action needs access to the PR's specific files, check out the base branch at the root, then check out the head ref into a separate subdirectory and provide it to the action via the --add-dir argument [1][2]. yaml - uses: actions/checkout@v6 # Base branch at workspace root - uses: actions/checkout@v6 with: ref: ${{ github.event.pull_request.head.sha }} path: pr-head - uses: anthropics/claude-code-action@v1 with: claude_args: "--add-dir pr-head" Regarding branch selection, the claude-code-action maintains logic to determine the active branch [3]. While it previously defaulted to "main," recent updates ensure it falls back to the repository's default_branch if available [3]. Users can also explicitly specify a branch for operations using the base_branch input parameter if necessary [4].

Citations:


Check out the PR head before running Claude on issue_comment.
actions/checkout will otherwise use the event ref here, which is the base branch for issue comments, so Claude works from the wrong code. Resolve github.event.issue.pull_request and pass the PR’s repository plus head.ref/head.sha into checkout first.

🧰 Tools
🪛 zizmor (1.26.1)

[warning] 57-61: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/claude.yml around lines 57 - 64, Update the Checkout
repository step before Run Claude Code to resolve
github.event.issue.pull_request and configure actions/checkout with the pull
request’s repository, head.ref, and head.sha, ensuring Claude runs against the
PR head rather than the issue-comment event ref.

with:
# The action's default trigger phrase is "@claude"; it reads the
# triggering comment/review and acts on the current PR head.
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
Comment on lines +62 to +68

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== workflow file ==\n'
cat -n .github/workflows/claude.yml | sed -n '1,180p'

printf '\n== references to claude-code-action ==\n'
rg -n "claude-code-action|ANTHROPIC_API_KEY|`@claude`|claude/" .github/workflows . -g '*.yml' -g '*.yaml' -g '*.md' -g '*.txt' || true

Repository: BigSimmo/Database

Length of output: 50374


🏁 Script executed:

#!/bin/bash
set -euo pipefail
cat -n .github/workflows/claude.yml | sed -n '1,180p'

Repository: BigSimmo/Database

Length of output: 3702


🌐 Web query:

anthropics/claude-code-action docs security default @claude creates branch PR-creation link direct update flow

💡 Result:

Claude Code and its associated GitHub Action provide automated workflows for branch management and pull request (PR) creation, supported by specific security configurations [1][2]. Security and Default Behaviors: For the Claude Code Action on GitHub, bot user control is enabled by default for security, meaning bots cannot trigger the action unless explicitly configured via the allowed_bots parameter [3][4]. Caution is advised when using wildcards ('*') for allowed bots, as this can allow external, uninstalled apps to trigger workflows on public repositories [3][4]. Claude Code itself enforces strict read-only permissions by default, requiring explicit user approval for any operations that modify files, execute shell commands, or perform network requests [5][6]. Branch and PR Creation Flow: Claude Code automates the Git lifecycle through natural language instructions [2][7]. Users can request branch creation and PR generation directly within the conversational interface [8][2]. 1. Branch Creation: When asked to create a branch, Claude Code typically handles the naming based on project conventions (e.g., CLAUDE.md) or defaults to patterns like feature/ or fix/ [9][7]. It executes the necessary git checkout commands automatically [2]. 2. PR Creation: Claude uses the GitHub CLI (gh) tool under the hood to manage pull requests [2][7]. A single command like "create a PR" triggers a process where Claude analyzes commits, generates a title and summary, and creates the PR via gh pr create [2][7]. 3. Session Linking: When a PR is created through this flow, the active conversational session is automatically linked to that PR [8][9]. This allows users to resume the session later using the PR number or URL to continue working on feedback or CI results [8][10]. For direct update flows, Claude Code performs background checks for updates on startup, with native installations updating automatically by default [11][12]. Users can configure release channels or disable these updates depending on their installation method (e.g., Homebrew/WinGet vs. native) [11][12].

Citations:


🌐 Web query:

site:github.com/anthropics/claude-code-action/docs/security.md "@claude" branch PR current PR head anthropic_api_key claude_code_oauth_token

💡 Result:

Key points from security.md:

  • If you use pull_request_target or workflow_run, don’t check out the PR head into the workspace root before claude-code-action; if you do, Claude runs on that untrusted checkout. Use the base branch at the root, or check out the PR head into a subdirectory and pass it via --add-dir. The doc specifically references github.event.pull_request.head.sha and github.event.workflow_run.head_sha. [1]
  • Never hardcode anthropic_api_key or claude_code_oauth_token in workflow files; store them in GitHub Secrets instead. [1]
  • In the default @claude flow, Claude does not auto-create PRs; it commits to a new branch and gives you a PR link to open manually. [1]

If you want, I can extract the exact YAML-safe pattern from that doc.


Update .github/workflows/claude.yml:62-68 to match the actual flow. The default @claude path creates a new claude/ branch and returns a PR link, so this does not push fixes to the triggering PR branch.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/claude.yml around lines 62 - 68, Update the “Run Claude
Code” workflow step and its action configuration to use the flow that applies
fixes directly to the triggering pull request branch instead of creating a new
claude/ branch and returning a separate PR link. Preserve the existing API-key
condition and secret wiring.

1 change: 1 addition & 0 deletions scripts/github-action-pins.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const reviewedActionPins = new Map([
]),
],
["actions/github-script", new Map([["3a2844b7e9c422d3c10d287c895573f7108da1b3", "v9.0.0"]])],
["anthropics/claude-code-action", new Map([["af0559ee4f514d1ef21826982bed13f7edc3c35e", "v1.0.178"]])],
["actions/cache", new Map([["55cc8345863c7cc4c66a329aec7e433d2d1c52a9", "v6"]])],
["actions/upload-artifact", new Map([["043fb46d1a93c77aae656e7c1c64a875d1fc6a0a", "v7"]])],
["denoland/setup-deno", new Map([["22d081ff2d3a40755e97629de92e3bcbfa7cf2ed", "v2.0.5"]])],
Expand Down