Ib collisions #1535
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Claude Code Review | |
| on: | |
| pull_request_target: | |
| types: [opened, ready_for_review, reopened, labeled] | |
| issue_comment: | |
| types: [created] | |
| jobs: | |
| claude-review: | |
| if: > | |
| ( | |
| github.event_name == 'pull_request_target' && | |
| ( | |
| github.event.action == 'opened' || | |
| github.event.action == 'ready_for_review' || | |
| github.event.action == 'reopened' || | |
| ( | |
| github.event.action == 'labeled' && | |
| github.event.label.name == 'claude-full-review' | |
| ) | |
| ) | |
| ) || | |
| ( | |
| github.event_name == 'issue_comment' && | |
| github.event.issue.pull_request != null && | |
| contains(github.event.comment.body, '@claude full review') | |
| ) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| issues: write | |
| actions: read | |
| steps: | |
| - name: Install dependencies | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| sudo apt-get update | |
| sudo apt-get install -y unzip jq | |
| - name: Determine PR number | |
| id: mode | |
| shell: bash | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| set -euo pipefail | |
| if [[ "${{ github.event_name }}" == "pull_request_target" ]]; then | |
| PR_NUMBER="${{ github.event.pull_request.number }}" | |
| elif [[ "${{ github.event_name }}" == "issue_comment" ]]; then | |
| PR_NUMBER="${{ github.event.issue.number }}" | |
| else | |
| echo "Unsupported event" | |
| exit 1 | |
| fi | |
| PR_HEAD_REF="$(gh pr view "$PR_NUMBER" --repo "${{ github.repository }}" --json headRefName --jq .headRefName)" | |
| echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT" | |
| echo "pr_head_ref=$PR_HEAD_REF" >> "$GITHUB_OUTPUT" | |
| - name: Checkout base repo | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Fetch PR head | |
| shell: bash | |
| env: | |
| PR_NUMBER: ${{ steps.mode.outputs.pr_number }} | |
| run: | | |
| set -euo pipefail | |
| # Fetch the PR merge ref — works for both same-repo and fork PRs | |
| # (fork branches don't exist on origin, but pull/<n>/head always does) | |
| git fetch origin "pull/${PR_NUMBER}/head" | |
| - name: Resolve review state | |
| id: state | |
| shell: bash | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| set -euo pipefail | |
| PR_NUMBER="${{ steps.mode.outputs.pr_number }}" | |
| REPO="${{ github.repository }}" | |
| mkdir -p .claude-review/context | |
| CURRENT_HEAD_SHA="$(gh pr view "$PR_NUMBER" --repo "$REPO" --json headRefOid --jq .headRefOid)" | |
| echo "current_head_sha=$CURRENT_HEAD_SHA" >> "$GITHUB_OUTPUT" | |
| LAST_COMMENT_B64="$( | |
| gh api --paginate "repos/$REPO/issues/$PR_NUMBER/comments?per_page=100" \ | |
| --jq '.[] | select(.body | contains("<!-- claude-review: thread=primary;")) | @base64' \ | |
| | tail -n1 || true | |
| )" | |
| EXISTING_COMMENT_ID="" | |
| if [[ -n "${LAST_COMMENT_B64:-}" ]]; then | |
| LAST_COMMENT_JSON="$(printf '%s' "$LAST_COMMENT_B64" | base64 -d)" | |
| EXISTING_COMMENT_ID="$(printf '%s' "$LAST_COMMENT_JSON" | jq -r '.id // empty')" | |
| fi | |
| echo "existing_comment_id=${EXISTING_COMMENT_ID:-}" >> "$GITHUB_OUTPUT" | |
| - name: Build review diff and changed-file list | |
| id: review_input | |
| shell: bash | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| set -euo pipefail | |
| PR_NUMBER="${{ steps.mode.outputs.pr_number }}" | |
| REPO="${{ github.repository }}" | |
| mkdir -p .claude-review | |
| gh pr diff "$PR_NUMBER" --repo "$REPO" > .claude-review/review.diff.raw | |
| gh pr view "$PR_NUMBER" --repo "$REPO" --json files --jq '.files[].path' > .claude-review/changed_files.txt.raw | |
| # Filter out tests/ directory — golden files don't need code review | |
| grep -v '^tests/' .claude-review/changed_files.txt.raw > .claude-review/changed_files.txt || true | |
| # Strip diff hunks for tests/ files | |
| awk ' | |
| /^diff --git a\/tests\// { skip=1; next } | |
| /^diff --git / { skip=0 } | |
| !skip { print } | |
| ' .claude-review/review.diff.raw > .claude-review/review.diff | |
| sed -i '/^[[:space:]]*$/d' .claude-review/changed_files.txt || true | |
| echo "review_diff_path=.claude-review/review.diff" >> "$GITHUB_OUTPUT" | |
| echo "changed_files_path=.claude-review/changed_files.txt" >> "$GITHUB_OUTPUT" | |
| - name: Prefetch bounded context for changed files only | |
| id: context | |
| shell: bash | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| set -euo pipefail | |
| REPO="${{ github.repository }}" | |
| HEAD_SHA="${{ steps.state.outputs.current_head_sha }}" | |
| COUNT=0 | |
| mkdir -p .claude-review/context | |
| # Prioritize src/ files for context (most likely to need review) | |
| sort -t/ -k1,1 -s < "${{ steps.review_input.outputs.changed_files_path }}" | \ | |
| awk '/^src\//{print; next} {rest[NR]=$0} END{for(i in rest) print rest[i]}' > .claude-review/sorted_files.txt | |
| while IFS= read -r path; do | |
| [[ -z "$path" ]] && continue | |
| COUNT=$((COUNT + 1)) | |
| [[ "$COUNT" -gt 10 ]] && break | |
| SAFE_NAME="$(printf '%s' "$path" | tr '/ ' '__')" | |
| RAW="$(gh api "repos/$REPO/contents/$path?ref=$HEAD_SHA" 2>/dev/null || true)" | |
| [[ -z "$RAW" ]] && continue | |
| ENCODING="$(printf '%s' "$RAW" | jq -r '.encoding // empty')" | |
| [[ "$ENCODING" != "base64" ]] && continue | |
| CONTENT="$(printf '%s' "$RAW" | jq -r '.content // empty' | tr -d '\n' | base64 -d 2>/dev/null || true)" | |
| [[ -z "$CONTENT" ]] && continue | |
| LINE_COUNT="$(printf '%s' "$CONTENT" | wc -l | tr -d ' ')" | |
| if [[ "$LINE_COUNT" -le 1500 ]]; then | |
| printf '%s' "$CONTENT" > ".claude-review/context/$SAFE_NAME" | |
| fi | |
| done < .claude-review/sorted_files.txt | |
| echo "context_dir=.claude-review/context" >> "$GITHUB_OUTPUT" | |
| - name: Initialize review output | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| mkdir -p .claude-review | |
| : > .claude-review/output.md | |
| - name: Run Claude Code Review | |
| continue-on-error: true | |
| uses: anthropics/claude-code-action@v1 | |
| with: | |
| claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} | |
| github_token: ${{ github.token }} | |
| plugin_marketplaces: "https://github.com/anthropics/claude-code.git" | |
| plugins: "code-review@claude-code-plugins" | |
| claude_args: > | |
| --dangerously-skip-permissions | |
| --max-turns 40 | |
| --allowedTools | |
| "Bash" | |
| prompt: | | |
| You are running in GitHub Actions review automation. | |
| PR NUMBER: ${{ steps.mode.outputs.pr_number }} | |
| CURRENT HEAD SHA: ${{ steps.state.outputs.current_head_sha }} | |
| Review ONLY the prepared inputs for this run. | |
| Prepared inputs: | |
| - Diff to review: ${{ steps.review_input.outputs.review_diff_path }} | |
| - Changed files list: ${{ steps.review_input.outputs.changed_files_path }} | |
| - Optional full-file context for small changed files: ${{ steps.context.outputs.context_dir }} | |
| Hard scope rules: | |
| - Do NOT inspect checked-out repository code except: | |
| - ./CLAUDE.md | |
| - ./.claude/rules/*.md (max 10 files) | |
| - ${{ steps.review_input.outputs.review_diff_path }} | |
| - ${{ steps.review_input.outputs.changed_files_path }} | |
| - files inside ${{ steps.context.outputs.context_dir }} | |
| - Do NOT fetch or inspect any other repository files. | |
| - Do NOT inspect unchanged files outside the reviewed diff. | |
| - Do NOT follow imports, includes, callers, callees, or related modules outside changed files. | |
| - Do NOT mention any file path not present in the changed files list. | |
| - Every finding must be grounded in at least one changed hunk from the reviewed diff. | |
| - Other changed files may be used as supporting context only. | |
| - Nearby unchanged lines in changed files may be used as supporting context only. | |
| - Do NOT raise findings about code outside changed files. | |
| - Do NOT provide general repo suggestions or unrelated improvement ideas. | |
| - Do NOT include positive confirmations like "No issues with X" | |
| - If confidence is low, omit the finding. | |
| Allowed workflow: | |
| 1) ls -1 .claude/rules 2>/dev/null || true | |
| 2) cat CLAUDE.md 2>/dev/null || true | |
| 3) find .claude/rules -maxdepth 1 -name "*.md" -print | head -n 10 | xargs -I{} cat "{}" 2>/dev/null || true | |
| 4) cat "${{ steps.review_input.outputs.changed_files_path }}" | |
| 5) cat "${{ steps.review_input.outputs.review_diff_path }}" | |
| 6) Optionally inspect files inside "${{ steps.context.outputs.context_dir }}" only | |
| 7) Write the final review markdown to .claude-review/output.md, then STOP | |
| 8) Do NOT post, update, or create GitHub comments yourself | |
| Review policy: | |
| - Review the full PR diff. | |
| - Do NOT restate the full PR summary. | |
| - If there are no high-confidence findings, leave .claude-review/output.md empty and STOP. | |
| Review standard (in priority order per CLAUDE.md "Code Review Priorities"): | |
| 1. Correctness (logic bugs, numerical issues, array bounds) | |
| 2. Precision discipline (stp vs wp mixing) | |
| 3. Memory management (@:ALLOCATE/@:DEALLOCATE pairing, GPU pointer setup) | |
| 4. MPI correctness (halo exchange, buffer sizing, GPU_UPDATE calls) | |
| 5. GPU code (GPU_* Fypp macros only, no raw pragmas) | |
| 6. Physics consistency (pressure formula matches model_eqns) | |
| 7. Compiler portability (4 CI-gated compilers + AMD flang for GPU) | |
| - Avoid style nitpicks. | |
| - A finding is valid only if it is supported by changed lines, with changed-file context used only to confirm it. | |
| Output rules: | |
| - Write markdown only to .claude-review/output.md | |
| - If there are findings, use exactly this format: | |
| Claude Code Review | |
| Head SHA: <sha> | |
| Files changed: | |
| - <count> | |
| - <up to 10 paths from changed_files.txt> | |
| Findings: | |
| - <only high-confidence issues grounded in changed hunks> | |
| <!-- claude-review: thread=primary; reviewed_sha=<current_head_sha>; mode=full --> | |
| - Always include the hidden marker exactly once at the end of the file. | |
| - If there are no findings, write nothing. | |
| - name: Publish review comment | |
| shell: bash | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| set -euo pipefail | |
| PR_NUMBER="${{ steps.mode.outputs.pr_number }}" | |
| REPO="${{ github.repository }}" | |
| COMMENT_ID="${{ steps.state.outputs.existing_comment_id }}" | |
| OUTPUT_FILE=".claude-review/output.md" | |
| if [[ ! -f "$OUTPUT_FILE" ]]; then | |
| echo "No output file; nothing to publish." | |
| exit 0 | |
| fi | |
| if [[ ! -s "$OUTPUT_FILE" ]] || [[ -z "$(tr -d '[:space:]' < "$OUTPUT_FILE")" ]]; then | |
| echo "Review output is empty; not posting a comment." | |
| exit 0 | |
| fi | |
| BODY_JSON="$(jq -Rs '{body: .}' < "$OUTPUT_FILE")" | |
| if [[ -n "${COMMENT_ID:-}" ]]; then | |
| gh api \ | |
| --method PATCH \ | |
| "repos/$REPO/issues/comments/$COMMENT_ID" \ | |
| --input - <<< "$BODY_JSON" >/dev/null | |
| echo "Updated existing primary review comment: $COMMENT_ID" | |
| else | |
| gh api \ | |
| --method POST \ | |
| "repos/$REPO/issues/$PR_NUMBER/comments" \ | |
| --input - <<< "$BODY_JSON" >/dev/null | |
| echo "Created new primary review comment." | |
| fi | |
| - name: Fallback job summary on failure | |
| if: failure() | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| if [[ -f .claude-review/output.md ]] && [[ -s .claude-review/output.md ]]; then | |
| { | |
| echo "## Claude Code Review" | |
| echo | |
| cat .claude-review/output.md | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| fi |