Triton RMSNorm Optimizations #35
Workflow file for this run
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 PR Action | |
| # Single workflow: PR review or summary, triggered by label, comment, or manually. | |
| # | |
| # Triggers: | |
| # - Label `claude-review` / `claude-summary` on a PR | |
| # - Comment `/claude review` / `/claude summary` from a writer on a PR | |
| # - Manual workflow_dispatch (re-runs) | |
| # | |
| # Auth model: | |
| # - Anthropic: subscription via CLAUDE_CODE_OAUTH_TOKEN. | |
| # - GitHub: workflow's GITHUB_TOKEN passed as `github_token` to | |
| # claude-code-action. This skips the Anthropic OIDC App-token | |
| # exchange (which rejects pull_request_target / issue_comment | |
| # subjects), so this workflow can run directly on those events | |
| # with no repository_dispatch indirection and no PAT. Cost: | |
| # comments post as `github-actions[bot]` instead of | |
| # `claude[bot]`. Dedup across runs uses an HTML marker | |
| # (`<!-- by:claude -->`) appended to every Claude-posted | |
| # comment, so the filter is login-agnostic. | |
| # | |
| # Migrating to a custom GitHub App later: replace `secrets.GITHUB_TOKEN` in | |
| # the two `github_token:` inputs (and the `GH_TOKEN` env on those steps) with | |
| # an installation token from `actions/create-github-app-token@v1`. No other | |
| # changes needed — the marker-based dedup keeps working across the swap. | |
| # | |
| # Note: We pin commits for all actions used here to avoid accidental breakage | |
| # from upstream changes. | |
| on: | |
| pull_request_target: | |
| types: [labeled] | |
| issue_comment: | |
| types: [created] | |
| workflow_dispatch: | |
| inputs: | |
| action: | |
| description: 'review or summary' | |
| required: true | |
| type: choice | |
| options: [review, summary] | |
| pr_number: | |
| description: 'PR number' | |
| required: true | |
| type: number | |
| base: | |
| description: 'PR base branch (default: repo default branch)' | |
| required: false | |
| type: string | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| issues: write | |
| jobs: | |
| resolve: | |
| # Fast dispatcher: parse the event, decide whether to act, ack the user. | |
| # Kept lightweight so PR label/comment churn doesn't queue heavy jobs. | |
| runs-on: ubuntu-latest | |
| if: > | |
| github.event_name == 'workflow_dispatch' || | |
| github.event_name == 'pull_request_target' || | |
| (github.event_name == 'issue_comment' && github.event.issue.pull_request != null) | |
| outputs: | |
| action: ${{ steps.resolve.outputs.action }} | |
| pr: ${{ steps.resolve.outputs.pr }} | |
| base: ${{ steps.resolve.outputs.base }} | |
| help: ${{ steps.resolve.outputs.help }} | |
| steps: | |
| - name: Resolve action, PR number, and base branch | |
| id: resolve | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| EVENT_NAME: ${{ github.event_name }} | |
| LABEL_NAME: ${{ github.event.label.name }} | |
| COMMENT_BODY: ${{ github.event.comment.body }} | |
| AUTHOR_ASSOC: ${{ github.event.comment.author_association }} | |
| PR_FROM_LABEL: ${{ github.event.pull_request.number }} | |
| PR_FROM_COMMENT: ${{ github.event.issue.number }} | |
| BASE_FROM_LABEL: ${{ github.event.pull_request.base.ref }} | |
| INPUT_ACTION: ${{ inputs.action }} | |
| INPUT_PR: ${{ inputs.pr_number }} | |
| INPUT_BASE: ${{ inputs.base }} | |
| run: | | |
| set -euo pipefail | |
| action=""; pr=""; base="" | |
| case "$EVENT_NAME" in | |
| pull_request_target) | |
| case "$LABEL_NAME" in | |
| claude-review) action="review" ;; | |
| claude-summary) action="summary" ;; | |
| esac | |
| pr="$PR_FROM_LABEL" | |
| base="$BASE_FROM_LABEL" | |
| ;; | |
| issue_comment) | |
| # Only writers can trigger — drop bots and outside contributors. | |
| case "$AUTHOR_ASSOC" in | |
| OWNER|MEMBER|COLLABORATOR) ;; | |
| *) echo "Ignoring comment from $AUTHOR_ASSOC"; exit 0 ;; | |
| esac | |
| # Look at the first whitespace-separated token. If it's not | |
| # `/claude`, this isn't addressed to us — stay silent. | |
| first=$(printf '%s' "$COMMENT_BODY" | awk 'NR==1 {print $1}') | |
| if [[ "$first" != "/claude" ]]; then | |
| echo "Not a /claude command; ignoring." | |
| exit 0 | |
| fi | |
| # Second token is the subcommand. Unknown/missing → post help. | |
| cmd=$(printf '%s' "$COMMENT_BODY" | awk 'NR==1 {print $2}') | |
| case "$cmd" in | |
| review) action="review" ;; | |
| summary) action="summary" ;; | |
| *) | |
| echo "Unknown /claude subcommand: '${cmd:-<empty>}'" | |
| echo "help=1" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| ;; | |
| esac | |
| pr="$PR_FROM_COMMENT" | |
| ;; | |
| workflow_dispatch) | |
| action="$INPUT_ACTION" | |
| pr="$INPUT_PR" | |
| base="$INPUT_BASE" | |
| ;; | |
| esac | |
| if [[ -z "$action" ]]; then | |
| echo "No matching action; nothing to do." | |
| exit 0 | |
| fi | |
| if [[ -z "$pr" ]]; then | |
| echo "::error::pr_number is required" >&2 | |
| exit 1 | |
| fi | |
| # Comment triggers (and workflow_dispatch w/o base) — look up the | |
| # PR's actual merge target so the worker diffs against it. | |
| if [[ -z "$base" ]]; then | |
| base=$(gh pr view "$pr" \ | |
| --repo "${{ github.repository }}" \ | |
| --json baseRefName -q .baseRefName) | |
| fi | |
| echo "action=$action" >> "$GITHUB_OUTPUT" | |
| echo "pr=$pr" >> "$GITHUB_OUTPUT" | |
| echo "base=$base" >> "$GITHUB_OUTPUT" | |
| - name: React to comment (acknowledge) | |
| if: steps.resolve.outputs.action != '' && github.event_name == 'issue_comment' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| gh api \ | |
| -H "Accept: application/vnd.github+json" \ | |
| --method POST \ | |
| "/repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions" \ | |
| -f content=eyes || true | |
| - name: Post help comment (invalid /claude command) | |
| if: steps.resolve.outputs.help == '1' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| # React with confused emoji so the user sees immediate feedback, | |
| # then post a one-shot usage reply. | |
| gh api \ | |
| -H "Accept: application/vnd.github+json" \ | |
| --method POST \ | |
| "/repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions" \ | |
| -f content=confused || true | |
| gh pr comment "${{ github.event.issue.number }}" \ | |
| --repo "${{ github.repository }}" \ | |
| --body-file - <<'EOF' | |
| **Claude PR commands** | |
| - `/claude review` — request a code review of this PR | |
| - `/claude summary` — generate (or update) a walkthrough comment | |
| You can also add a label to the PR: `claude-review` or `claude-summary`. | |
| <!-- by:claude --> | |
| EOF | |
| claude: | |
| needs: resolve | |
| if: needs.resolve.outputs.action != '' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| issues: write | |
| concurrency: | |
| # One Claude job per (PR, action) at a time; cancel superseded runs. | |
| group: claude-pr-${{ needs.resolve.outputs.pr }}-${{ needs.resolve.outputs.action }} | |
| cancel-in-progress: true | |
| env: | |
| ACTION: ${{ needs.resolve.outputs.action }} | |
| PR_NUMBER: ${{ needs.resolve.outputs.pr }} | |
| BASE_REF: ${{ needs.resolve.outputs.base }} | |
| steps: | |
| # SECURITY GATE — must run before any step that materializes PR code. | |
| # pull_request_target grants this job write-scoped GITHUB_TOKEN and the | |
| # CLAUDE_CODE_OAUTH_TOKEN secret. If we then check out the fork's tree | |
| # and let Claude run `git diff` etc. on it, a malicious PR can hijack | |
| # those credentials (e.g. via a `.gitattributes` textconv driver). | |
| # Restrict fork PRs to authors with write/maintain/admin on the base | |
| # repo; same-repo PRs and workflow_dispatch already require write perms | |
| # to reach this point. | |
| - name: Block fork PRs from non-collaborators | |
| if: github.event_name == 'pull_request_target' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }} | |
| PR_AUTHOR: ${{ github.event.pull_request.user.login }} | |
| run: | | |
| set -euo pipefail | |
| if [[ "$HEAD_REPO" == "${{ github.repository }}" ]]; then | |
| echo "Same-repo PR; collaborator check not required." | |
| exit 0 | |
| fi | |
| perm=$(gh api "repos/${{ github.repository }}/collaborators/$PR_AUTHOR/permission" \ | |
| --jq .permission 2>/dev/null || echo none) | |
| case "$perm" in | |
| admin|maintain|write) | |
| echo "Fork PR author $PR_AUTHOR has $perm; allowing." | |
| ;; | |
| *) | |
| echo "::error::Fork PR from $PR_AUTHOR ($HEAD_REPO) lacks write access (perm=$perm); refusing to run on untrusted code." | |
| exit 1 | |
| ;; | |
| esac | |
| # refs/pull/<n>/merge is GitHub's synthetic merge commit (base tip | |
| # merged with PR head). Checking it out gives us both parents in one | |
| # shot: HEAD^1 = base tip, HEAD^2 = PR head — no separate base fetch | |
| # needed. Caveat: the merge ref only exists when the PR is mergeable; | |
| # if it's missing/stale, the workflow will fail fast on checkout, which | |
| # is the right behavior for an unreviewable PR. | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| ref: refs/pull/${{ env.PR_NUMBER }}/merge | |
| # Skills live in .github/agent-skills/. | |
| # Stage them into .claude/skills/ at runtime so Claude Code discovers | |
| # them via its default `.claude/skills/<name>/SKILL.md` lookup. Source | |
| # from the repo default branch so a release-branch PR (which may not | |
| # carry the skills) still gets the latest set. | |
| - name: Stage Claude skills | |
| env: | |
| DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} | |
| run: | | |
| set -euo pipefail | |
| git fetch origin "$DEFAULT_BRANCH" | |
| mkdir -p .claude/skills | |
| # `git archive | tar -x` materializes the skills from the default | |
| # branch even if the PR branch deleted or doesn't carry them. | |
| if git cat-file -e "origin/$DEFAULT_BRANCH:.github/agent-skills" 2>/dev/null; then | |
| git archive "origin/$DEFAULT_BRANCH" .github/agent-skills \ | |
| | tar -x --strip-components=2 -C .claude/skills | |
| else | |
| echo "::warning::No .github/agent-skills/ on origin/$DEFAULT_BRANCH; review will run skill-less." | |
| fi | |
| ls -la .claude/skills/ || true | |
| # Workaround mirrored from ROCm/xla: pre-install Claude Code so the | |
| # action does not hang during first-run init. | |
| - name: Install and warm up Claude Code | |
| timeout-minutes: 2 | |
| env: | |
| CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} | |
| run: | | |
| curl -fsSL https://claude.ai/install.sh | bash | |
| export PATH="$HOME/.local/bin:$PATH" | |
| claude --version | |
| # Run the warmup in a clean directory so Claude Code does not | |
| # auto-discover CLAUDE.md / .claude/ from the (untrusted) PR tree | |
| # at $GITHUB_WORKSPACE. The OAUTH token is in env at this step, | |
| # and a malicious workspace CLAUDE.md could otherwise prompt-inject | |
| # the warmup invocation into echoing it. | |
| warmup_dir=$(mktemp -d) | |
| ( cd "$warmup_dir" && timeout 60 claude --print -p "Say OK" ) || echo "Warmup complete" | |
| rm -rf "$warmup_dir" | |
| # claude-code-action only auto-configures the inline-comment MCP server | |
| # for pull_request* events. Wire it up manually so it works regardless | |
| # of trigger event. | |
| - name: Configure inline-comment MCP | |
| id: mcp | |
| run: | | |
| set -euo pipefail | |
| server=$(find "$(dirname "$RUNNER_WORKSPACE")/_actions/anthropics/claude-code-action" \ | |
| -name "github-inline-comment-server.ts" 2>/dev/null | head -1) | |
| cat > /tmp/mcp-config.json <<EOF | |
| { | |
| "mcpServers": { | |
| "github_inline_comment": { | |
| "command": "bun", | |
| "args": ["run", "$server"], | |
| "env": { | |
| "REPO_OWNER": "${{ github.repository_owner }}", | |
| "REPO_NAME": "${{ github.event.repository.name }}", | |
| "PR_NUMBER": "${{ env.PR_NUMBER }}", | |
| "GITHUB_API_URL": "${{ github.api_url }}" | |
| } | |
| } | |
| } | |
| } | |
| EOF | |
| echo "file=/tmp/mcp-config.json" >> "$GITHUB_OUTPUT" | |
| # ---- REVIEW ---- | |
| - name: Run Claude — Code Review | |
| id: review | |
| if: env.ACTION == 'review' | |
| timeout-minutes: 30 | |
| uses: anthropics/claude-code-action@dde2242db6af13460b916652159b6ba19a598f30 # v1.0.120 | |
| env: | |
| # Same token is exposed to the model's `gh` subprocess so it can | |
| # comment on the PR. Mirrors the `github_token:` input below. | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} | |
| # Setting github_token short-circuits the Anthropic OIDC → App-token | |
| # exchange in claude-code-action (src/github/token.ts). Without this | |
| # the action would try to exchange the workflow's OIDC subject for | |
| # the official `claude[bot]` App token, which Anthropic rejects on | |
| # pull_request_target / issue_comment events. Trade-off: comments | |
| # post as github-actions[bot]. Dedup uses the HTML marker in the | |
| # prompt rather than the bot login, so this is identity-portable. | |
| github_token: ${{ secrets.GITHUB_TOKEN }} | |
| allowed_bots: "github-actions[bot]" | |
| show_full_output: true | |
| # Strict allowlist for Bash(...) and MCP tools (no disallowedTools). | |
| # The matcher splits chained commands on `;`/`&&`/`|` and checks | |
| # each segment, so `Bash(git diff *)` covers `BASE=…; git diff …` | |
| # but `Bash(echo *)` is still needed for the `echo "---"` segment. | |
| # Built-in tools (Read, Grep, Glob, Skill, TodoWrite, ToolSearch, | |
| # Write, Edit) bypass --allowedTools enforcement, but Read/Grep/ | |
| # Glob/Skill are listed for documentation. Patterns are verified | |
| # against past run transcripts; widen only when a transcript shows | |
| # a needed command being denied — never to `Bash(gh *)`/`Bash(git | |
| # *)`/`Bash(*)`. | |
| claude_args: | | |
| --model claude-opus-4-7 --effort xhigh --allowedTools "Skill,mcp__github_inline_comment__create_inline_comment,Bash(gh pr view *),Bash(gh pr comment *),Bash(gh pr diff *),Bash(gh api repos/*),Bash(gh api /repos/*),Bash(gh api --paginate repos/*),Bash(gh api --paginate /repos/*),Bash(git diff *),Bash(git log *),Bash(git show *),Bash(git cat-file *),Bash(git ls-files *),Bash(git rev-parse *),Bash(git rev-list *),Bash(git ls-remote *),Bash(git merge-base *),Bash(git fetch *),Bash(git status),Bash(git status *),Bash(jq *),Bash(head *),Bash(grep *),Bash(echo *),Bash(ls),Bash(ls *),Read,Grep,Glob" --mcp-config ${{ steps.mcp.outputs.file }} | |
| settings: | | |
| { "hasCompletedOnboarding": true } | |
| prompt: | | |
| REPO: ${{ github.repository }} | |
| PR: ${{ env.PR_NUMBER }} | |
| BASE: ${{ env.BASE_REF }} # PR's actual merge target (label only) | |
| The synthetic merge commit `refs/pull/${{ env.PR_NUMBER }}/merge` | |
| is checked out, so `HEAD^1` is the base tip (the PR's merge | |
| target) and `HEAD^2` is the PR head. Use `HEAD^1` for every | |
| diff/comparison — this works regardless of whether the merge | |
| target is the default branch or a release branch. | |
| ## Identity & dedup | |
| This workflow posts as `github-actions[bot]` (until a dedicated | |
| GitHub App is provisioned). To make prior-Claude lookups robust | |
| across that future swap, every Claude-posted comment carries the | |
| HTML marker `<!-- by:claude -->`. You MUST append that marker on | |
| its own line at the end of every comment you post in step 3. | |
| ## 1. Gather prior context | |
| Use `gh` to enumerate signals that should shape this review: | |
| a. Prior Claude inline comments (top-level only): | |
| ``` | |
| gh api --paginate "repos/${{ github.repository }}/pulls/${{ env.PR_NUMBER }}/comments" \ | |
| | jq -s 'add // [] | [.[] | select((.body | test("<!-- by:claude -->")) and .in_reply_to_id == null)]' | |
| ``` | |
| b. Prior human reviews and review comments — note any unresolved | |
| threads or themes already raised by reviewers; do not duplicate. | |
| c. Top-level PR comments containing `<!-- by:claude -->` (prior | |
| summaries / review verdicts). | |
| ## 2. Produce findings | |
| Run BOTH skills below and merge their findings before posting. Each | |
| covers a distinct concern; neither subsumes the other. | |
| **2a. Code review** — `/review-pr` (vendored in `.claude/skills/`). | |
| Pass the PR number and base ref so it scopes the diff correctly: | |
| `/review-pr ${{ env.PR_NUMBER }} --base HEAD^1` | |
| If a prior Claude review exists (step 1a returned non-empty), | |
| instruct the skill to focus on commits added since the most recent | |
| marker-tagged inline-comment timestamp — re-reading the entire | |
| diff is wasteful and produces duplicate noise. | |
| **2b. Copyright header audit** — `/copyright-check` (vendored in | |
| `.claude/skills/`). This is the AMD-side counterpart to | |
| `qa/L0_license/copyright_checker.py` and verifies that ROCm-modified | |
| and ROCm-introduced files carry correct AMD headers with up-to-date | |
| year ranges, without altering preserved NVIDIA copyrights: | |
| `/copyright-check HEAD^1` | |
| Run this on every review (initial and re-review). Copyright | |
| findings are typically actionable on a single line, so prefer | |
| inline comments on the offending header line for each finding. | |
| Do NOT post anything to GitHub yet; collect findings from both | |
| skills in memory and dedupe against step 1 before posting. | |
| ## 3. Post results | |
| - For each finding (from 2a or 2b), call | |
| `mcp__github_inline_comment__create_inline_comment` on the | |
| relevant diff line. End every comment body with a newline and | |
| `<!-- by:claude -->` so subsequent runs can identify it. | |
| Skip findings that duplicate any comment from step 1 | |
| (Claude's or a human reviewer's). | |
| - Post ONE short top-level summary via `gh pr comment` describing | |
| what was reviewed and the high-level verdict; end with | |
| `<!-- by:claude -->`. Mention the copyright audit result as a | |
| single line (e.g. "Copyright headers: OK" or "Copyright | |
| headers: 3 files need updates — see inline comments"). Do not | |
| repeat individual findings. | |
| - If this is a re-review and there are no new findings, post a | |
| brief top-level comment saying so (still with the marker). | |
| - Do NOT post intermediate analysis or thinking to the PR. | |
| # ---- SUMMARY / WALKTHROUGH ---- | |
| - name: Run Claude — Summary & Walkthrough | |
| id: summary | |
| if: env.ACTION == 'summary' | |
| timeout-minutes: 20 | |
| uses: anthropics/claude-code-action@dde2242db6af13460b916652159b6ba19a598f30 # v1.0.120 | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} | |
| # See the review step above for why github_token is set explicitly. | |
| github_token: ${{ secrets.GITHUB_TOKEN }} | |
| allowed_bots: "github-actions[bot]" | |
| show_full_output: true | |
| # Strict allowlist for Bash(...) and MCP (see review step for the | |
| # full rationale). Summary additionally needs: | |
| # - `gh api -X{POST,PATCH} repos/*/issues/*/comments` to create | |
| # or update the walkthrough top-level comment (past runs use | |
| # either `gh api -F body=@-` or `gh pr comment --body-file`); | |
| # - `cat *` for `cat > /tmp/walkthrough.md <<EOF` heredocs the | |
| # model uses to stage the body before posting; | |
| # - `git fetch *` / `git merge-base *` for shallow-clone deepening | |
| # when the synthetic merge commit's parents aren't reachable. | |
| # Review intentionally does NOT allow POST/PATCH against the issues | |
| # comments endpoint; it posts inline via the MCP tool instead. | |
| claude_args: | | |
| --model claude-opus-4-7 --effort xhigh --allowedTools "Skill,Bash(gh pr view *),Bash(gh pr comment *),Bash(gh pr diff *),Bash(gh api repos/*),Bash(gh api /repos/*),Bash(gh api --paginate repos/*),Bash(gh api --paginate /repos/*),Bash(gh api --method POST repos/*),Bash(gh api --method POST /repos/*),Bash(gh api -X POST repos/*),Bash(gh api -X POST /repos/*),Bash(gh api --method PATCH repos/*),Bash(gh api --method PATCH /repos/*),Bash(gh api -X PATCH repos/*),Bash(gh api -X PATCH /repos/*),Bash(git diff *),Bash(git log *),Bash(git show *),Bash(git cat-file *),Bash(git ls-files *),Bash(git rev-parse *),Bash(git rev-list *),Bash(git merge-base *),Bash(git fetch *),Bash(git status),Bash(git status *),Bash(jq *),Bash(echo *),Bash(cat *),Bash(ls),Bash(ls *),Read,Grep,Glob" | |
| settings: | | |
| { "hasCompletedOnboarding": true } | |
| prompt: | | |
| REPO: ${{ github.repository }} | |
| PR: ${{ env.PR_NUMBER }} | |
| BASE: ${{ env.BASE_REF }} # PR's actual merge target (label only) | |
| The synthetic merge commit `refs/pull/${{ env.PR_NUMBER }}/merge` | |
| is checked out, so `HEAD^1` is the base tip and `HEAD^2` is the | |
| PR head. Use `HEAD^1` for any diff or comparison. | |
| ## Goal | |
| Produce ONE top-level PR comment that helps a reader understand | |
| this change without reading every line of the diff. This is an | |
| explanatory artifact, NOT a review — do not flag issues here. | |
| ## 1. Check for prior summaries | |
| This workflow posts as `github-actions[bot]`; prior Claude | |
| artifacts are tagged with the HTML marker `<!-- by:claude -->`. | |
| ``` | |
| gh api --paginate "repos/${{ github.repository }}/issues/${{ env.PR_NUMBER }}/comments" \ | |
| | jq -s 'add // [] | [.[] | select(.body | test("<!-- by:claude -->")) | select(.body | test("Claude Walkthrough"))]' | |
| ``` | |
| If a prior summary exists, edit it (gh api PATCH on the comment | |
| id from the response above) instead of posting a new one — keep | |
| one canonical walkthrough that reflects the current state of the | |
| PR. Otherwise, post a new one. | |
| ## 2. Build the walkthrough | |
| Read the PR title/description and `git diff HEAD^1...HEAD^2`. | |
| Use `Grep`/`Read` to ground claims in the actual code. | |
| Format the comment exactly as: | |
| ```markdown | |
| ## Claude Walkthrough | |
| **Intent.** 1–3 sentences on what problem this PR solves and why, | |
| inferred from the description and the diff. | |
| **Key changes.** | |
| - Bullet per logically distinct change. Reference files as | |
| `path/to/file.py:LINE` when pointing to a specific construct. | |
| **Walkthrough.** | |
| File-by-file (or component-by-component) prose for the non-trivial | |
| changes. Skip pure renames, formatting, and generated files. | |
| Explain *why* a change was made when it is not self-evident. | |
| **Testing.** What tests were added/changed, and what behavior | |
| they cover. If no tests were added, say so. | |
| **Notes for reviewers.** Anything subtle: invariants relied on, | |
| backwards-compat concerns, perf implications, follow-ups deferred. | |
| --- | |
| _Generated by Claude. To request a code review, comment `/claude review`._ | |
| <!-- by:claude --> | |
| ``` | |
| Keep it tight. A reader should be able to skim it in under a minute | |
| and know whether they need to dive deeper. Do NOT post inline | |
| comments and do NOT post anything other than this single top-level | |
| comment. | |
| - name: Upload Claude execution log | |
| if: always() && (steps.review.outputs.execution_file != '' || steps.summary.outputs.execution_file != '') | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 | |
| with: | |
| name: claude-${{ env.ACTION }}-pr${{ env.PR_NUMBER }}-log | |
| path: ${{ steps.review.outputs.execution_file || steps.summary.outputs.execution_file }} | |
| - name: Remove trigger label | |
| if: always() && github.event_name == 'pull_request_target' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| label="claude-${{ env.ACTION }}" | |
| gh api --method DELETE \ | |
| "/repos/${{ github.repository }}/issues/${{ env.PR_NUMBER }}/labels/$label" \ | |
| || true |