blob: bd178b8c63e6e0bffaeeee0941020601245e7286 [file]
name: Claude Code
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
# only "opened" — an issue's author_association gates the summon below;
# "assigned" would gate on the issue author, not the assigner, so a
# maintainer assigning an outsider's issue would be wrongly skipped.
types: [opened]
pull_request_review:
types: [submitted]
jobs:
claude:
# Only trusted actors (repo owner/member/collaborator) may summon @claude, so the
# write-scoped token and OAuth secret are never issued for an outside contributor's
# comment on this public repo. Defense-in-depth on top of the action's own check.
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude') &&
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude') &&
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude') &&
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.review.author_association)) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) &&
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.issue.author_association))
runs-on: ubuntu-latest
permissions:
contents: write # allow Claude to push commits/branches when asked
pull-requests: write # allow Claude to comment on / update PRs
issues: write # allow Claude to comment on / update issues
id-token: write
actions: read # Required for Claude to read CI results on PRs
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 1
- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
# This is an optional setting that allows Claude to read CI results on PRs
additional_permissions: |
actions: read
# Sign the bot's commits so they show as "Verified". The action commits
# automatically — on a PR comment it pushes to that PR's branch; on an
# issue comment it opens a new claude/* branch + PR with the fix.
use_commit_signing: true
# No custom prompt: Claude performs the instructions in the @claude comment.
# Deliberately NO Bash in the tool allowlist. @claude can be summoned on a
# fork PR, and this job holds the OAuth secret + a write token. Any build
# or interpreter command (python -c, cmake/make custom targets, etc.) run
# against attacker-controlled PR content is arbitrary code + network
# execution, so no command allowlist can safely contain it. Claude edits
# files and the action commits/opens the PR; the resulting commit is
# verified by the repo's CircleCI matrix. --max-turns gives room to
# investigate + fix.
claude_args: '--max-turns 30 --model claude-opus-5'