|
1 | 1 | name: Claude Code Review |
2 | 2 |
|
3 | 3 | on: |
4 | | - pull_request: |
5 | | - types: [opened, synchronize] |
6 | | - # Optional: Only run on specific file changes |
7 | | - # paths: |
8 | | - # - "src/**/*.ts" |
9 | | - # - "src/**/*.tsx" |
10 | | - # - "src/**/*.js" |
11 | | - # - "src/**/*.jsx" |
| 4 | + issue_comment: |
| 5 | + types: [created] |
| 6 | + |
| 7 | +concurrency: |
| 8 | + group: claude-review-${{ github.event.issue.number }} |
| 9 | + cancel-in-progress: true |
12 | 10 |
|
13 | 11 | jobs: |
14 | | - claude-review: |
15 | | - # Skip fork PRs to prevent prompt injection via malicious PR content |
16 | | - if: github.event.pull_request.head.repo.full_name == github.repository |
| 12 | + # Notify unauthorized users who try to use the command |
| 13 | + notify-unauthorized: |
| 14 | + if: | |
| 15 | + github.event.issue.pull_request && |
| 16 | + (github.event.comment.body == '/claude-review' || |
| 17 | + startsWith(github.event.comment.body, '/claude-review ')) && |
| 18 | + github.event.comment.author_association != 'OWNER' |
| 19 | + runs-on: ubuntu-latest |
| 20 | + permissions: |
| 21 | + issues: write |
| 22 | + steps: |
| 23 | + - name: React to indicate unauthorized |
| 24 | + env: |
| 25 | + GH_TOKEN: ${{ github.token }} |
| 26 | + run: | |
| 27 | + gh api repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions \ |
| 28 | + -f content='-1' |
17 | 29 |
|
| 30 | + # Acknowledge the command with a reaction |
| 31 | + acknowledge: |
| 32 | + if: | |
| 33 | + github.event.issue.pull_request && |
| 34 | + (github.event.comment.body == '/claude-review' || |
| 35 | + startsWith(github.event.comment.body, '/claude-review ')) && |
| 36 | + github.event.comment.author_association == 'OWNER' |
| 37 | + runs-on: ubuntu-latest |
| 38 | + permissions: |
| 39 | + issues: write |
| 40 | + steps: |
| 41 | + - name: React to acknowledge command |
| 42 | + env: |
| 43 | + GH_TOKEN: ${{ github.token }} |
| 44 | + run: | |
| 45 | + gh api repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions \ |
| 46 | + -f content='+1' |
| 47 | +
|
| 48 | + claude-review: |
| 49 | + needs: acknowledge |
18 | 50 | runs-on: ubuntu-latest |
19 | 51 | permissions: |
20 | 52 | contents: read |
|
23 | 55 | id-token: write |
24 | 56 |
|
25 | 57 | steps: |
| 58 | + - name: Check if PR is from fork |
| 59 | + env: |
| 60 | + GH_TOKEN: ${{ github.token }} |
| 61 | + run: | |
| 62 | + IS_FORK=$(gh pr view ${{ github.event.issue.number }} --repo ${{ github.repository }} --json isCrossRepository -q '.isCrossRepository') |
| 63 | + if [ "$IS_FORK" = "true" ]; then |
| 64 | + echo "::error::Cannot review PRs from forks due to security concerns" |
| 65 | + exit 1 |
| 66 | + fi |
| 67 | +
|
26 | 68 | - name: Checkout repository |
27 | 69 | uses: actions/checkout@v6 |
28 | 70 | with: |
|
35 | 77 | claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} |
36 | 78 | prompt: | |
37 | 79 | REPO: ${{ github.repository }} |
38 | | - PR NUMBER: ${{ github.event.pull_request.number }} |
| 80 | + PR NUMBER: ${{ github.event.issue.number }} |
39 | 81 |
|
40 | 82 | Please review this pull request and provide feedback on: |
41 | 83 | - Code quality and best practices |
|
0 commit comments