Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,4 @@ cce_*/
cce_*.log
run_cce_*.sh
.ffmt_cache/
**/.ffmt_cache/
330 changes: 330 additions & 0 deletions claude-code-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,330 @@
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
12 changes: 11 additions & 1 deletion docs/documentation/case.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,16 @@ Setup: Only requires specifying `init_dir` and filename pattern via `zeros_defau
Implementation: All variables and file handling are managed in `src/common/include/ExtrusionHardcodedIC.fpp` with no manual grid configuration needed.
Usage: Ideal for initializing simulations from lower-dimensional solutions, enabling users to add perturbations or modifications to the base extruded fields for flow instability studies.

The following parameters support hardcoded initial conditions that read interface data from files:

| Parameter | Type | Description |
| ---: | :---: | :--- |
| `interface_file` | String | Path to interface geometry data file |
| `normFac` | Real | Interface normalization factor |
| `normMag` | Real | Interface normal magnitude |
| `g0_ic` | Real | Initial gas volume fraction for interfacial IC |
| `p0_ic` | Real | Initial pressure for interfacial IC |

#### Parameter Descriptions

- `num_patches` defines the total number of patches defined in the domain.
Expand Down Expand Up @@ -349,7 +359,7 @@ Definitions for currently implemented immersed boundary patch types are listed i

- `c`, `t`, `p`, and `m` specify the parameters for a NACA airfoil.
`m` is the maximum camber, `p` is the location of maximum camber, `c` is the coord length, and `t` is the thickness.
Additional details on this specification can be found in [NACA airfoil](https://en.wikipedia.org/wiki/NACA_airfoil).
Additional details on this specification can be found in [The Naca Airfoil Series](https://web.stanford.edu/~cantwell/AA200_Course_Material/The%20NACA%20airfoil%20series.pdf)

- `slip` applies a slip boundary to the surface of the patch if true and a no-slip boundary condition to the surface if false.

Expand Down
Loading
Loading