Skip to content

Commit ee3d9ae

Browse files
authored
Merge pull request #28 from DecaturMakers/claude/unify-review-workflows
Move the Claude workflows to the shared composite actions
2 parents b680353 + c1ade3e commit ee3d9ae

2 files changed

Lines changed: 118 additions & 0 deletions

File tree

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
name: Claude Code
2+
3+
# Reactive: does nothing until someone writes @claude. Pairs with claude-pr-review.yml.
4+
#
5+
# >>> DO NOT MERGE THESE TWO INTO ONE JOB. <<<
6+
# They look redundant and are not. The shared action for THIS file supplies no `prompt`,
7+
# which is what keeps claude-code-action in TAG mode. Supplying one -- as the review
8+
# action does -- puts it in AGENT mode for every event it sees, where an @claude comment
9+
# gets no PR context, no tracking comment, and nothing posted back.
10+
#
11+
# NOTE: `issue_comment` workflows always run from the default branch, so edits to this
12+
# file do nothing until they are merged.
13+
14+
on:
15+
issue_comment:
16+
types: [created]
17+
pull_request_review_comment:
18+
types: [created]
19+
issues:
20+
types: [opened, assigned]
21+
pull_request_review:
22+
types: [submitted]
23+
24+
jobs:
25+
claude:
26+
# >>> THIS GUARD IS LOAD-BEARING ON A PUBLIC REPOSITORY. <<<
27+
# Two conditions, both required, both checked per-event.
28+
#
29+
# 1. author_association of the person who ACTUALLY TRIGGERED IT. This job has
30+
# `contents: write` and blanket `Bash`, so without this check any passer-by who
31+
# types @claude gets an arbitrary-code-execution agent run on the maintainer's
32+
# OAuth token. The pairing matters: on `issue_comment`,
33+
# `github.event.issue.author_association` is the issue's *opener*, not the
34+
# commenter, so checking that field here would let a stranger trigger a run
35+
# merely by commenting on a maintainer's own issue. OWNER covers the repository
36+
# owner; COLLABORATOR/MEMBER cover anyone later given push access.
37+
# 2. the @claude mention itself.
38+
#
39+
# The guard cannot live in the shared action: by the time a composite action runs,
40+
# the runner is already up and the token already minted.
41+
if: |
42+
(github.event_name == 'issue_comment' &&
43+
contains(github.event.comment.body, '@claude') &&
44+
contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)) ||
45+
(github.event_name == 'pull_request_review_comment' &&
46+
contains(github.event.comment.body, '@claude') &&
47+
contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)) ||
48+
(github.event_name == 'pull_request_review' &&
49+
contains(github.event.review.body, '@claude') &&
50+
contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.review.author_association)) ||
51+
(github.event_name == 'issues' &&
52+
(contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) &&
53+
contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.issue.author_association))
54+
runs-on: ubuntu-latest
55+
permissions:
56+
contents: write
57+
pull-requests: write
58+
issues: write
59+
id-token: write
60+
actions: read # Required for Claude to read CI results on PRs
61+
62+
steps:
63+
- name: Checkout repository
64+
uses: actions/checkout@v7
65+
with:
66+
fetch-depth: 1
67+
68+
- uses: jantman/github-actions-workflows/claude-mention@v1
69+
with:
70+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Claude PR Review
2+
3+
# Proactive: reviews every PR without being asked. Pairs with claude-mention.yml, the
4+
# reactive half. Both are thin: the logic lives in
5+
# jantman/github-actions-workflows/claude-pr-review.
6+
#
7+
# >>> A CHANGE TO *THIS FILE* CANNOT BE TESTED BY THE PR THAT MAKES IT. <<<
8+
# claude-code-action refuses to run when this file differs from the copy on the default
9+
# branch -- that is what stops a pull request from rewriting it to steal the OAuth
10+
# token. It exits 0 when it skips, so such a PR goes green having reviewed nothing.
11+
# Look for "Exiting due to workflow validation skip". Merge first, then the next PR
12+
# gets a real review. A change to the shared ACTION has no such problem, because this
13+
# file does not change.
14+
15+
on:
16+
pull_request:
17+
types: [opened, synchronize, ready_for_review, reopened]
18+
19+
# A new push supersedes the review it interrupted. Reviewing a commit that has already
20+
# been replaced burns a full agent run on code that no longer exists.
21+
concurrency:
22+
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
23+
cancel-in-progress: true
24+
25+
jobs:
26+
claude-review:
27+
# A pull request from a fork gets no secrets, so CLAUDE_CODE_OAUTH_TOKEN is empty
28+
# and the action fails red rather than skipping -- a confusing failure on somebody
29+
# else's contribution. Skip cleanly instead. Always true on a repository that takes
30+
# no fork pull requests.
31+
if: github.event.pull_request.head.repo.full_name == github.repository
32+
runs-on: ubuntu-latest
33+
permissions:
34+
contents: read
35+
pull-requests: write # POST /pulls/N/reviews, and the agent reads the PR
36+
issues: write # the action's own tracking/error comments, not the review
37+
id-token: write
38+
actions: read # lets the reviewer read this commit's CI results
39+
40+
steps:
41+
- name: Checkout repository
42+
uses: actions/checkout@v7
43+
with:
44+
fetch-depth: 1
45+
46+
- uses: jantman/github-actions-workflows/claude-pr-review@v1
47+
with:
48+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}

0 commit comments

Comments
 (0)