|
1 | | -name: Claude Code Review |
| 1 | +# .github/workflows/claude-code-review.yml |
| 2 | +name: Claude code review (strict) |
2 | 3 |
|
3 | 4 | on: |
4 | 5 | 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" |
| 6 | + types: [opened, synchronize, reopened, ready_for_review] |
| 7 | + |
| 8 | +concurrency: |
| 9 | + group: claude-review-${{ github.event.pull_request.number }} |
| 10 | + cancel-in-progress: true |
12 | 11 |
|
13 | 12 | jobs: |
14 | 13 | claude-review: |
15 | | - # Optional: Filter by PR author |
16 | | - # if: | |
17 | | - # github.event.pull_request.user.login == 'external-contributor' || |
18 | | - # github.event.pull_request.user.login == 'new-developer' || |
19 | | - # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' |
20 | | - |
21 | 14 | runs-on: ubuntu-latest |
22 | 15 | permissions: |
23 | 16 | contents: read |
24 | | - pull-requests: read |
25 | | - issues: read |
| 17 | + pull-requests: write |
26 | 18 | id-token: write |
27 | 19 |
|
28 | 20 | steps: |
29 | 21 | - name: Checkout repository |
30 | 22 | uses: actions/checkout@v4 |
31 | 23 | with: |
32 | | - fetch-depth: 1 |
| 24 | + fetch-depth: 0 |
| 25 | + |
| 26 | + - name: Load CLAUDE.md rules |
| 27 | + id: rules |
| 28 | + shell: bash |
| 29 | + run: | |
| 30 | + echo 'guidelines<<EOF' >> "$GITHUB_OUTPUT" |
| 31 | + sed -n '1,6000p' CLAUDE.md >> "$GITHUB_OUTPUT" |
| 32 | + echo 'EOF' >> "$GITHUB_OUTPUT" |
33 | 33 |
|
34 | | - - name: Run Claude Code Review |
35 | | - id: claude-review |
| 34 | + - name: Run Claude (repo-wide checklist, file-by-file) |
| 35 | + id: claude |
36 | 36 | uses: anthropics/claude-code-action@v1 |
37 | 37 | with: |
38 | 38 | claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} |
39 | 39 | prompt: | |
40 | | - Please review this pull request and provide feedback on: |
41 | | - - Code quality and best practices |
42 | | - - Use the repository's CLAUDE.md for more detail instructions |
43 | | - - Potential bugs or issues |
44 | | - - Performance considerations |
45 | | - - Security concerns |
46 | | - - Test coverage |
47 | | -
|
48 | | - Use `gh pr comment` with your Bash tool to leave your review as a comment on the PR. |
49 | | -
|
50 | | - # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md |
51 | | - # or https://docs.anthropic.com/en/docs/claude-code/sdk#command-line for available options |
52 | | - 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:*)"' |
| 40 | + You are a STRICT reviewer. Enforce every rule in CLAUDE.md across the entire repo. |
| 41 | + Build a YES/NO checklist for each rule per file. Include focused patch suggestions. |
| 42 | +
|
| 43 | + Scope: |
| 44 | + - Enumerate Scala/SBT files: git ls-files '*.scala' '*.sbt' |
| 45 | + - Also consider configs affecting Scala builds: git ls-files '.scalafmt.conf' 'build.sbt' 'project/*.scala' 'project/*.sbt' 'project/build.properties' |
| 46 | + - Apply ALL rules from CLAUDE.md to each discovered file (not just PR diffs). |
| 47 | +
|
| 48 | + Output: |
| 49 | + - One markdown report grouped by file |
| 50 | + - For each rule: ✅ PASS or ❌ FAIL with a minimal diff/patch |
| 51 | + - A short "Top 10 Fixes" summary |
| 52 | + - Final line MUST be exactly: |
| 53 | + CLAUDE_RULES_STATUS: PASS # or FAIL |
| 54 | +
|
| 55 | + Rules to enforce: |
| 56 | + --- |
| 57 | + ${{ steps.rules.outputs.guidelines }} |
| 58 | + --- |
| 59 | +
|
| 60 | + # Use GA-style CLI flags; give Claude deterministic tools for repo-wide scans. |
| 61 | + claude_args: >- |
| 62 | + --allowedTools |
| 63 | + "Read" |
| 64 | + "Edit" |
| 65 | + "MultiEdit" |
| 66 | + "Bash(git ls-files:*)" |
| 67 | + "Bash(rg:*)" |
| 68 | + "Bash(find:*)" |
| 69 | + "Bash(sed:*)" |
| 70 | + "Bash(xargs:*)" |
| 71 | + "Bash(gh pr view:*)" |
| 72 | + "Bash(gh pr comment:*)" |
| 73 | + --max-turns 10 |
| 74 | + --verbose |
| 75 | +
|
| 76 | + env: |
| 77 | + GH_TOKEN: ${{ github.token }} |
| 78 | + |
| 79 | + - name: Fail the job unless all rules passed |
| 80 | + if: always() |
| 81 | + shell: bash |
| 82 | + env: |
| 83 | + GH_TOKEN: ${{ github.token }} |
| 84 | + run: | |
| 85 | + pr="${{ github.event.pull_request.number }}" |
| 86 | + # Aggregate all comments and look for the sentinel line. |
| 87 | + body="$(gh pr view "$pr" --json comments -q '.comments[].body' || true)" |
| 88 | + echo "=== Tail of PR comments ===" |
| 89 | + echo "$body" | tail -n 40 || true |
| 90 | + echo "$body" | grep -q 'CLAUDE_RULES_STATUS: PASS' |
0 commit comments