@@ -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'
@@ -42,47 +41,40 @@ jobs:
4241 sudo apt-get update
4342 sudo apt-get install -y unzip jq
4443
45- - name : Checkout base repo
46- uses : actions/checkout@v4
47- with :
48- fetch-depth : 1
49-
50- - name : Determine PR number and requested review mode
44+ - name : Determine PR number
5145 id : mode
5246 shell : bash
47+ env :
48+ GH_TOKEN : ${{ github.token }}
5349 run : |
5450 set -euo pipefail
5551
5652 if [[ "${{ github.event_name }}" == "pull_request_target" ]]; then
5753 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
7654 elif [[ "${{ github.event_name }}" == "issue_comment" ]]; then
7755 PR_NUMBER="${{ github.event.issue.number }}"
78- REQUESTED_MODE="full"
7956 else
8057 echo "Unsupported event"
8158 exit 1
8259 fi
8360
61+ PR_HEAD_REF="$(gh pr view "$PR_NUMBER" --repo "${{ github.repository }}" --json headRefName --jq .headRefName)"
62+
8463 echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
85- echo "requested_mode=$REQUESTED_MODE" >> "$GITHUB_OUTPUT"
64+ echo "pr_head_ref=$PR_HEAD_REF" >> "$GITHUB_OUTPUT"
65+
66+ - name : Checkout base repo
67+ uses : actions/checkout@v4
68+ with :
69+ fetch-depth : 0
70+
71+ - name : Fetch PR branch
72+ shell : bash
73+ env :
74+ PR_HEAD_REF : ${{ steps.mode.outputs.pr_head_ref }}
75+ run : |
76+ set -euo pipefail
77+ git fetch origin "$PR_HEAD_REF"
8678
8779 - name : Resolve review state
8880 id : state
9486
9587 PR_NUMBER="${{ steps.mode.outputs.pr_number }}"
9688 REPO="${{ github.repository }}"
97- REQUESTED_MODE="${{ steps.mode.outputs.requested_mode }}"
9889
9990 mkdir -p .claude-review/context
10091
@@ -108,23 +99,13 @@ jobs:
10899 )"
109100
110101 EXISTING_COMMENT_ID=""
111- PREVIOUS_REVIEWED_SHA=""
112102
113103 if [[ -n "${LAST_COMMENT_B64:-}" ]]; then
114104 LAST_COMMENT_JSON="$(printf '%s' "$LAST_COMMENT_B64" | base64 -d)"
115105 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"
123106 fi
124107
125108 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"
128109
129110 - name : Build review diff and changed-file list
130111 id : review_input
@@ -136,43 +117,23 @@ jobs:
136117
137118 PR_NUMBER="${{ steps.mode.outputs.pr_number }}"
138119 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 }}"
142120
143121 mkdir -p .claude-review
144- : > .claude-review/review.diff
145- : > .claude-review/changed_files.txt
146122
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- }
123+ gh pr diff "$PR_NUMBER" --repo "$REPO" > .claude-review/review.diff.raw
124+ gh pr view "$PR_NUMBER" --repo "$REPO" --json files --jq '.files[].path' > .claude-review/changed_files.txt.raw
152125
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
126+ # Filter out tests/ directory — golden files don't need code review
127+ grep -v '^tests/' .claude-review/changed_files.txt.raw > .claude-review/changed_files.txt || true
128+ # Strip diff hunks for tests/ files
129+ awk '
130+ /^diff --git a\/tests\// { skip=1; next }
131+ /^diff --git / { skip=0 }
132+ !skip { print }
133+ ' .claude-review/review.diff.raw > .claude-review/review.diff
167134
168135 sed -i '/^[[:space:]]*$/d' .claude-review/changed_files.txt || true
169136
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-
176137 echo "review_diff_path=.claude-review/review.diff" >> "$GITHUB_OUTPUT"
177138 echo "changed_files_path=.claude-review/changed_files.txt" >> "$GITHUB_OUTPUT"
178139
@@ -190,6 +151,10 @@ jobs:
190151
191152 mkdir -p .claude-review/context
192153
154+ # Prioritize src/ files for context (most likely to need review)
155+ sort -t/ -k1,1 -s < "${{ steps.review_input.outputs.changed_files_path }}" | \
156+ awk '/^src\//{print; next} {rest[NR]=$0} END{for(i in rest) print rest[i]}' > .claude-review/sorted_files.txt
157+
193158 while IFS= read -r path; do
194159 [[ -z "$path" ]] && continue
195160 COUNT=$((COUNT + 1))
@@ -206,10 +171,10 @@ jobs:
206171 [[ -z "$CONTENT" ]] && continue
207172
208173 LINE_COUNT="$(printf '%s' "$CONTENT" | wc -l | tr -d ' ')"
209- if [[ "$LINE_COUNT" -le 400 ]]; then
174+ if [[ "$LINE_COUNT" -le 1500 ]]; then
210175 printf '%s' "$CONTENT" > ".claude-review/context/$SAFE_NAME"
211176 fi
212- done < "${{ steps.review_input.outputs.changed_files_path }}"
177+ done < .claude-review/sorted_files.txt
213178
214179 echo "context_dir=.claude-review/context" >> "$GITHUB_OUTPUT"
215180
@@ -221,6 +186,7 @@ jobs:
221186 : > .claude-review/output.md
222187
223188 - name : Run Claude Code Review
189+ continue-on-error : true
224190 uses : anthropics/claude-code-action@v1
225191 with :
226192 claude_code_oauth_token : ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
@@ -229,16 +195,13 @@ jobs:
229195 plugins : " code-review@claude-code-plugins"
230196 claude_args : >
231197 --dangerously-skip-permissions
232- --max-turns 90
198+ --max-turns 40
233199 --allowedTools
234200 "Bash"
235201 prompt : |
236202 You are running in GitHub Actions review automation.
237203
238- REQUESTED REVIEW MODE: ${{ steps.state.outputs.effective_mode }}
239- ACTUAL REVIEW MODE: ${{ steps.review_input.outputs.actual_mode }}
240204 PR NUMBER: ${{ steps.mode.outputs.pr_number }}
241- PREVIOUS REVIEWED SHA: ${{ steps.state.outputs.previous_reviewed_sha }}
242205 CURRENT HEAD SHA: ${{ steps.state.outputs.current_head_sha }}
243206
244207 Review ONLY the prepared inputs for this run.
@@ -264,7 +227,7 @@ jobs:
264227 - Nearby unchanged lines in changed files may be used as supporting context only.
265228 - Do NOT raise findings about code outside changed files.
266229 - Do NOT provide general repo suggestions or unrelated improvement ideas.
267- - Do NOT include positive confirmations like "No issues with X".
230+ - Do NOT include positive confirmations like "No issues with X"
268231 - If confidence is low, omit the finding.
269232
270233 Allowed workflow:
@@ -278,23 +241,25 @@ jobs:
278241 8) Do NOT post, update, or create GitHub comments yourself
279242
280243 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.
244+ - Review the full PR diff.
285245 - Do NOT restate the full PR summary.
286246 - If there are no high-confidence findings, leave .claude-review/output.md empty and STOP.
287247
288- Review standard:
289- - Prefer correctness, reliability, cleanup/finalization gaps, inconsistent behavior, edge cases, and meaningful test gaps.
248+ Review standard (in priority order per CLAUDE.md "Code Review Priorities"):
249+ 1. Correctness (logic bugs, numerical issues, array bounds)
250+ 2. Precision discipline (stp vs wp mixing)
251+ 3. Memory management (@:ALLOCATE/@:DEALLOCATE pairing, GPU pointer setup)
252+ 4. MPI correctness (halo exchange, buffer sizing, GPU_UPDATE calls)
253+ 5. GPU code (GPU_* Fypp macros only, no raw pragmas)
254+ 6. Physics consistency (pressure formula matches model_eqns)
255+ 7. Compiler portability (4 CI-gated compilers + AMD flang for GPU)
290256 - Avoid style nitpicks.
291257 - A finding is valid only if it is supported by changed lines, with changed-file context used only to confirm it.
292258
293259 Output rules:
294260 - Write markdown only to .claude-review/output.md
295- - If there are findings, use exactly one of these formats.
261+ - If there are findings, use exactly this format:
296262
297- For full mode:
298263 Claude Code Review
299264
300265 Head SHA: <sha>
@@ -308,17 +273,6 @@ jobs:
308273
309274 <!-- claude-review: thread=primary; reviewed_sha=<current_head_sha>; mode=full -->
310275
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-
322276 - Always include the hidden marker exactly once at the end of the file.
323277 - If there are no findings, write nothing.
324278
0 commit comments