Skip to content

Commit ec8524a

Browse files
authored
Add Claude Code GitHub Workflow (#59)
* chore(ci): add Claude PR assistant workflow Adds a GitHub Actions workflow that triggers Claude Code when @claude is mentioned in PR or issue comments. * chore(ci): add Claude Code review workflow Adds a GitHub Actions workflow that triggers Claude Code to review PRs when requested via the review-requested event. * fix(ci): address security and workflow review feedback - Add author_association check to restrict Claude triggers to OWNER, MEMBER, and COLLABORATOR (prevents unauthorized access) - Change issues event from 'assigned' to 'edited' (assigned was noise) - Add concurrency groups to both workflows (prevents overlapping runs) - Pin claude-code-action to SHA for supply-chain safety - Make claude-code-review opt-in via 'claude-review' label * fix(ci): add write permissions for review workflow The claude-code-action needs write permissions to post review comments. Changed `pull-requests` and `issues` from `read` to `write`. * fix(ci): skip review workflow for fork PRs Fork PRs don't receive repository secrets in `pull_request` workflows, so the job would fail. Added guard to skip when PR head repo differs from the base repository. * chore(ci): use harden runner * chore(ci): remove label gating of review
1 parent e9a3f7a commit ec8524a

2 files changed

Lines changed: 113 additions & 0 deletions

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Claude Code Review
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize, ready_for_review, reopened, labeled]
6+
7+
jobs:
8+
claude-review:
9+
# only run when PR is from this repository (fork PRs don't receive secrets)
10+
if: |
11+
github.event.pull_request.head.repo.full_name == github.repository
12+
concurrency:
13+
group: claude-review-${{ github.repository }}-${{ github.event.pull_request.number }}
14+
cancel-in-progress: true
15+
runs-on: ubuntu-latest
16+
permissions:
17+
contents: read
18+
pull-requests: write
19+
issues: write
20+
id-token: write
21+
22+
steps:
23+
- name: Checkout repository
24+
uses: actions/checkout@v4
25+
with:
26+
fetch-depth: 1
27+
28+
- name: Run Claude Code Review
29+
id: claude-review
30+
# Pinned to v1 for supply-chain safety
31+
uses: anthropics/claude-code-action@f2accb9a171bd71f4b5c93bcea23876aa5244edb
32+
with:
33+
allowed_bots: 'renovate[bot]'
34+
claude_args: |
35+
--max-turns 10
36+
track_progress: true
37+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
38+
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
39+
plugins: 'code-review@claude-code-plugins'
40+
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
41+
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
42+
# or https://code.claude.com/docs/en/cli-reference for available options
43+

.github/workflows/claude.yml

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
name: Claude Code
2+
3+
on:
4+
issue_comment:
5+
types: [created]
6+
pull_request_review_comment:
7+
types: [created]
8+
issues:
9+
types: [opened, edited]
10+
pull_request_review:
11+
types: [submitted]
12+
13+
jobs:
14+
claude:
15+
if: |
16+
(github.event_name == 'issue_comment' &&
17+
contains(github.event.comment.body, '@claude') &&
18+
contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)) ||
19+
(github.event_name == 'pull_request_review_comment' &&
20+
contains(github.event.comment.body, '@claude') &&
21+
contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)) ||
22+
(github.event_name == 'pull_request_review' &&
23+
contains(github.event.review.body, '@claude') &&
24+
contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.review.author_association)) ||
25+
(github.event_name == 'issues' &&
26+
(contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) &&
27+
contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.issue.author_association))
28+
concurrency:
29+
group: claude-${{ github.repository }}-${{ github.event.issue.number || github.event.pull_request.number || github.run_id }}
30+
cancel-in-progress: true
31+
runs-on: ubuntu-latest
32+
permissions:
33+
contents: read # TODO unclear if needed
34+
pull-requests: write # for progress tracking
35+
issues: write # for progress tracking
36+
id-token: write # needed for OAUTH token
37+
actions: read # Required for Claude to read CI results on PRs
38+
steps:
39+
- name: Harden-Runner
40+
uses: step-security/harden-runner@fe104658747b27e96e4f7e80cd0a94068e53901d # v2.16.1
41+
with:
42+
egress-policy: audit
43+
44+
- name: Checkout repository
45+
uses: actions/checkout@v4
46+
with:
47+
fetch-depth: 1
48+
49+
- name: Run Claude Code
50+
id: claude
51+
# Pinned to v1 for supply-chain safety
52+
uses: anthropics/claude-code-action@f2accb9a171bd71f4b5c93bcea23876aa5244edb
53+
with:
54+
claude_args: |
55+
--max-turns 10
56+
--allowed-tools 'Bash(gh pr:*),Bash(make:*),Bash(go test:*),Bash(gh stack:*)'
57+
track_progress: true
58+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
59+
allowed_bots: 'renovate[bot]'
60+
# This is an optional setting that allows Claude to read CI results on PRs
61+
additional_permissions: |
62+
actions: read
63+
64+
# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
65+
# prompt: 'Update the pull request description to include a summary of changes.'
66+
67+
# Optional: Add claude_args to customize behavior and configuration
68+
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
69+
# or https://code.claude.com/docs/en/cli-reference for available options
70+
# claude_args: '--allowed-tools Bash(gh pr:*)'

0 commit comments

Comments
 (0)