/ .github / workflows / claude-code-review.yml
claude-code-review.yml
 1  name: Claude Code Review
 2  
 3  on:
 4    pull_request:
 5      types: [opened]  # Only on PR creation, not every push. Use /claude-review for re-reviews.
 6    issue_comment:
 7      types: [created]
 8  
 9  # Keyed per-PR so a rapid re-review comment doesn't stack parallel runs.
10  concurrency:
11    group: claude-review-${{ github.event.issue.number || github.event.pull_request.number || github.run_id }}
12    cancel-in-progress: false
13  
14  jobs:
15    claude-review:
16      # Automatic reviews: Only run on PRs from the same repository (not forks)
17      # Manual reviews: Allow fork PRs when triggered by /claude-review command from authorized users
18      if: |
19        (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) ||
20        (github.event_name == 'issue_comment' &&
21         github.event.issue.pull_request &&
22         contains(github.event.comment.body, '/claude-review') &&
23         (github.event.comment.author_association == 'OWNER' ||
24          github.event.comment.author_association == 'MEMBER' ||
25          github.event.comment.author_association == 'COLLABORATOR'))
26  
27      runs-on: ubuntu-latest
28      timeout-minutes: 20
29      permissions:
30        contents: read
31        pull-requests: write  # Changed to 'write' so Claude can comment on PRs
32        issues: read
33        id-token: write
34  
35      steps:
36        - name: Get PR details
37          id: pr
38          env:
39            GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40            EVENT_NAME: ${{ github.event_name }}
41            ISSUE_NUMBER: ${{ github.event.issue.number }}
42            REPOSITORY: ${{ github.repository }}
43            PR_HEAD_REF: ${{ github.event.pull_request.head.ref }}
44            PR_HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }}
45          run: |
46            if [ "$EVENT_NAME" = "issue_comment" ]; then
47              PR_DATA=$(gh pr view "$ISSUE_NUMBER" --json headRefName,headRepository --repo "$REPOSITORY")
48              echo "ref=$(echo "$PR_DATA" | jq -r '.headRefName')" >> "$GITHUB_OUTPUT"
49              echo "repo=$(echo "$PR_DATA" | jq -r '.headRepository.nameWithOwner')" >> "$GITHUB_OUTPUT"
50            else
51              echo "ref=$PR_HEAD_REF" >> "$GITHUB_OUTPUT"
52              echo "repo=$PR_HEAD_REPO" >> "$GITHUB_OUTPUT"
53            fi
54  
55        - name: Checkout repository
56          uses: actions/checkout@v4
57          with:
58            fetch-depth: 1
59            ref: ${{ steps.pr.outputs.ref }}
60            repository: ${{ steps.pr.outputs.repo }}
61  
62        - name: Run Claude Code Review
63          id: claude-review
64          uses: anthropics/claude-code-action@v1
65          with:
66            anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
67            prompt: |
68              Please review this pull request and provide feedback on:
69              - Code quality and best practices
70              - Potential bugs or issues
71              - Performance considerations
72              - Security concerns
73              - Test coverage
74  
75              Use the repository's CLAUDE.md for guidance on style and conventions. Be constructive and helpful in your feedback.
76  
77              Use `gh pr comment` with your Bash tool to leave your review as a comment on the PR.
78  
79            # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
80            # or https://docs.anthropic.com/en/docs/claude-code/sdk#command-line for available options
81            claude_args: '--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"'