@@ -2,7 +2,7 @@ name: Claude Code Review
22
33on :
44 pull_request_target :
5- types : [opened, synchronize, ready_for_review, reopened, labeled]
5+ types : [opened, ready_for_review, reopened, labeled]
66 issue_comment :
77 types : [created]
88
1515 github.event.action == 'opened' ||
1616 github.event.action == 'ready_for_review' ||
1717 github.event.action == 'reopened' ||
18- github.event.action == 'synchronize' ||
1918 (
2019 github.event.action == 'labeled' &&
2120 github.event.label.name == 'claude-full-review'
@@ -47,42 +46,22 @@ jobs:
4746 with :
4847 fetch-depth : 1
4948
50- - name : Determine PR number and requested review mode
49+ - name : Determine PR number
5150 id : mode
5251 shell : bash
5352 run : |
5453 set -euo pipefail
5554
5655 if [[ "${{ github.event_name }}" == "pull_request_target" ]]; then
5756 PR_NUMBER="${{ github.event.pull_request.number }}"
58- case "${{ github.event.action }}" in
59- opened|ready_for_review|reopened)
60- REQUESTED_MODE="full"
61- ;;
62- synchronize)
63- REQUESTED_MODE="incremental"
64- ;;
65- labeled)
66- if [[ "${{ github.event.label.name }}" == "claude-full-review" ]]; then
67- REQUESTED_MODE="full"
68- else
69- REQUESTED_MODE="full"
70- fi
71- ;;
72- *)
73- REQUESTED_MODE="full"
74- ;;
75- esac
7657 elif [[ "${{ github.event_name }}" == "issue_comment" ]]; then
7758 PR_NUMBER="${{ github.event.issue.number }}"
78- REQUESTED_MODE="full"
7959 else
8060 echo "Unsupported event"
8161 exit 1
8262 fi
8363
8464 echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
85- echo "requested_mode=$REQUESTED_MODE" >> "$GITHUB_OUTPUT"
8665
8766 - name : Resolve review state
8867 id : state
9473
9574 PR_NUMBER="${{ steps.mode.outputs.pr_number }}"
9675 REPO="${{ github.repository }}"
97- REQUESTED_MODE="${{ steps.mode.outputs.requested_mode }}"
9876
9977 mkdir -p .claude-review/context
10078
@@ -108,23 +86,13 @@ jobs:
10886 )"
10987
11088 EXISTING_COMMENT_ID=""
111- PREVIOUS_REVIEWED_SHA=""
11289
11390 if [[ -n "${LAST_COMMENT_B64:-}" ]]; then
11491 LAST_COMMENT_JSON="$(printf '%s' "$LAST_COMMENT_B64" | base64 -d)"
11592 EXISTING_COMMENT_ID="$(printf '%s' "$LAST_COMMENT_JSON" | jq -r '.id // empty')"
116- COMMENT_BODY="$(printf '%s' "$LAST_COMMENT_JSON" | jq -r '.body // empty')"
117- PREVIOUS_REVIEWED_SHA="$(printf '%s' "$COMMENT_BODY" | sed -n 's/.*reviewed_sha=\([0-9a-fA-F]\{7,\}\).*/\1/p' | tail -n1)"
118- fi
119-
120- EFFECTIVE_MODE="$REQUESTED_MODE"
121- if [[ "$REQUESTED_MODE" == "incremental" && -z "${PREVIOUS_REVIEWED_SHA:-}" ]]; then
122- EFFECTIVE_MODE="full"
12393 fi
12494
12595 echo "existing_comment_id=${EXISTING_COMMENT_ID:-}" >> "$GITHUB_OUTPUT"
126- echo "previous_reviewed_sha=${PREVIOUS_REVIEWED_SHA:-}" >> "$GITHUB_OUTPUT"
127- echo "effective_mode=$EFFECTIVE_MODE" >> "$GITHUB_OUTPUT"
12896
12997 - name : Build review diff and changed-file list
13098 id : review_input
@@ -136,43 +104,23 @@ jobs:
136104
137105 PR_NUMBER="${{ steps.mode.outputs.pr_number }}"
138106 REPO="${{ github.repository }}"
139- MODE="${{ steps.state.outputs.effective_mode }}"
140- CURRENT_SHA="${{ steps.state.outputs.current_head_sha }}"
141- PREV_SHA="${{ steps.state.outputs.previous_reviewed_sha }}"
142107
143108 mkdir -p .claude-review
144- : > .claude-review/review.diff
145- : > .claude-review/changed_files.txt
146109
147- build_full() {
148- gh pr diff "$PR_NUMBER" --repo "$REPO" > .claude-review/review.diff
149- gh pr view "$PR_NUMBER" --repo "$REPO" --json files --jq '.files[].path' > .claude-review/changed_files.txt
150- echo "actual_mode=full" >> "$GITHUB_OUTPUT"
151- }
110+ gh pr diff "$PR_NUMBER" --repo "$REPO" > .claude-review/review.diff.raw
111+ gh pr view "$PR_NUMBER" --repo "$REPO" --json files --jq '.files[].path' > .claude-review/changed_files.txt.raw
152112
153- if [[ "$MODE" == "full" ]]; then
154- build_full
155- else
156- if gh api -H "Accept: application/vnd.github.diff" \
157- "repos/$REPO/compare/$PREV_SHA...$CURRENT_SHA" > .claude-review/review.diff.tmp 2>/dev/null \
158- && gh api "repos/$REPO/compare/$PREV_SHA...$CURRENT_SHA" --jq '.files[].filename' > .claude-review/changed_files.txt.tmp 2>/dev/null; then
159- mv .claude-review/review.diff.tmp .claude-review/review.diff
160- mv .claude-review/changed_files.txt.tmp .claude-review/changed_files.txt
161- echo "actual_mode=incremental" >> "$GITHUB_OUTPUT"
162- else
163- echo "Compare diff failed; falling back to full review."
164- build_full
165- fi
166- fi
113+ # Filter out tests/ directory — golden files don't need code review
114+ grep -v '^tests/' .claude-review/changed_files.txt.raw > .claude-review/changed_files.txt || true
115+ # Strip diff hunks for tests/ files
116+ awk '
117+ /^diff --git a\/tests\// { skip=1; next }
118+ /^diff --git / { skip=0 }
119+ !skip { print }
120+ ' .claude-review/review.diff.raw > .claude-review/review.diff
167121
168122 sed -i '/^[[:space:]]*$/d' .claude-review/changed_files.txt || true
169123
170- if [[ ! -s .claude-review/review.diff ]] || [[ ! -s .claude-review/changed_files.txt ]]; then
171- echo "Prepared diff or changed file list is empty; falling back to full review."
172- build_full
173- sed -i '/^[[:space:]]*$/d' .claude-review/changed_files.txt || true
174- fi
175-
176124 echo "review_diff_path=.claude-review/review.diff" >> "$GITHUB_OUTPUT"
177125 echo "changed_files_path=.claude-review/changed_files.txt" >> "$GITHUB_OUTPUT"
178126
@@ -190,6 +138,10 @@ jobs:
190138
191139 mkdir -p .claude-review/context
192140
141+ # Prioritize src/ files for context (most likely to need review)
142+ sort -t/ -k1,1 -s < "${{ steps.review_input.outputs.changed_files_path }}" | \
143+ awk '/^src\//{print; next} {rest[NR]=$0} END{for(i in rest) print rest[i]}' > .claude-review/sorted_files.txt
144+
193145 while IFS= read -r path; do
194146 [[ -z "$path" ]] && continue
195147 COUNT=$((COUNT + 1))
@@ -206,10 +158,10 @@ jobs:
206158 [[ -z "$CONTENT" ]] && continue
207159
208160 LINE_COUNT="$(printf '%s' "$CONTENT" | wc -l | tr -d ' ')"
209- if [[ "$LINE_COUNT" -le 400 ]]; then
161+ if [[ "$LINE_COUNT" -le 1500 ]]; then
210162 printf '%s' "$CONTENT" > ".claude-review/context/$SAFE_NAME"
211163 fi
212- done < "${{ steps.review_input.outputs.changed_files_path }}"
164+ done < .claude-review/sorted_files.txt
213165
214166 echo "context_dir=.claude-review/context" >> "$GITHUB_OUTPUT"
215167
@@ -221,6 +173,7 @@ jobs:
221173 : > .claude-review/output.md
222174
223175 - name : Run Claude Code Review
176+ continue-on-error : true
224177 uses : anthropics/claude-code-action@v1
225178 with :
226179 claude_code_oauth_token : ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
@@ -229,16 +182,13 @@ jobs:
229182 plugins : " code-review@claude-code-plugins"
230183 claude_args : >
231184 --dangerously-skip-permissions
232- --max-turns 90
185+ --max-turns 40
233186 --allowedTools
234187 "Bash"
235188 prompt : |
236189 You are running in GitHub Actions review automation.
237190
238- REQUESTED REVIEW MODE: ${{ steps.state.outputs.effective_mode }}
239- ACTUAL REVIEW MODE: ${{ steps.review_input.outputs.actual_mode }}
240191 PR NUMBER: ${{ steps.mode.outputs.pr_number }}
241- PREVIOUS REVIEWED SHA: ${{ steps.state.outputs.previous_reviewed_sha }}
242192 CURRENT HEAD SHA: ${{ steps.state.outputs.current_head_sha }}
243193
244194 Review ONLY the prepared inputs for this run.
@@ -278,23 +228,25 @@ jobs:
278228 8) Do NOT post, update, or create GitHub comments yourself
279229
280230 Review policy:
281- - In full mode, review the full PR diff.
282- - In incremental mode, review only the delta diff.
283- - In incremental mode, report only new issues introduced by that delta.
284- - Do NOT repeat earlier findings.
231+ - Review the full PR diff.
285232 - Do NOT restate the full PR summary.
286233 - If there are no high-confidence findings, leave .claude-review/output.md empty and STOP.
287234
288- Review standard:
289- - Prefer correctness, reliability, cleanup/finalization gaps, inconsistent behavior, edge cases, and meaningful test gaps.
235+ Review standard (in priority order per CLAUDE.md "Code Review Priorities"):
236+ 1. Correctness (logic bugs, numerical issues, array bounds)
237+ 2. Precision discipline (stp vs wp mixing)
238+ 3. Memory management (@:ALLOCATE/@:DEALLOCATE pairing, GPU pointer setup)
239+ 4. MPI correctness (halo exchange, buffer sizing, GPU_UPDATE calls)
240+ 5. GPU code (GPU_* Fypp macros only, no raw pragmas)
241+ 6. Physics consistency (pressure formula matches model_eqns)
242+ 7. Compiler portability (4 CI-gated compilers + AMD flang for GPU)
290243 - Avoid style nitpicks.
291244 - A finding is valid only if it is supported by changed lines, with changed-file context used only to confirm it.
292245
293246 Output rules:
294247 - Write markdown only to .claude-review/output.md
295- - If there are findings, use exactly one of these formats.
248+ - If there are findings, use exactly this format:
296249
297- For full mode:
298250 Claude Code Review
299251
300252 Head SHA: <sha>
@@ -308,17 +260,6 @@ jobs:
308260
309261 <!-- claude-review: thread=primary; reviewed_sha=<current_head_sha>; mode=full -->
310262
311- For incremental mode:
312- Claude Code Review
313-
314- Incremental review from: <previous_sha>
315- Head SHA: <current_sha>
316-
317- New findings since last Claude review:
318- - <only high-confidence issues grounded in changed hunks of the delta diff>
319-
320- <!-- claude-review: thread=primary; reviewed_sha=<current_head_sha>; mode=incremental -->
321-
322263 - Always include the hidden marker exactly once at the end of the file.
323264 - If there are no findings, write nothing.
324265
0 commit comments