Skip to content
Closed
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
76 changes: 76 additions & 0 deletions .github/workflows/claude-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Claude review

# Reviews a PR when it opens, is reopened or leaves draft, and again when a
# collaborator comments "@claude review". Not on every push, to save
# subscription usage. Fork PRs are skipped on both paths: the review runs with
# the subscription token and a write token, so it only reads same-repo code.

on:
pull_request:
types: [opened, ready_for_review, reopened]
issue_comment:
types: [created]

permissions:
contents: read

jobs:
review:
name: Claude review
if: |
(github.event_name == 'pull_request' &&
!github.event.pull_request.draft &&
github.event.pull_request.head.repo.full_name == github.repository &&
!startsWith(github.head_ref, 'mergify/')) ||
(github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
startsWith(github.event.comment.body, '@claude review') &&
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association))
runs-on: ubuntu-24.04
timeout-minutes: 30
# Job-level, so comments that don't match the condition above don't cancel a running review.
concurrency:
group: claude-review-${{ github.event.pull_request.number || github.event.issue.number }}
cancel-in-progress: true
permissions:
contents: read
pull-requests: write
issues: write
env:
PR_NUMBER: ${{ github.event.pull_request.number || github.event.issue.number }}
steps:
- name: Skip fork PRs
id: source
env:
GH_TOKEN: ${{ github.token }}
run: |
cross=$(gh pr view "$PR_NUMBER" -R "$GITHUB_REPOSITORY" --json isCrossRepository -q .isCrossRepository)
echo "same_repo=$([ "$cross" = false ] && echo true || echo false)" >> "$GITHUB_OUTPUT"

# Default ref: the PR's merge commit on pull_request, main on comments.
# The review reads the PR's changes with gh, so no PR head is checked out
# in the comment-triggered (secret-holding) context.
- if: steps.source.outputs.same_repo == 'true'
uses: actions/checkout@v7
with:
fetch-depth: 1
persist-credentials: false

- if: steps.source.outputs.same_repo == 'true'
uses: anthropics/claude-code-action@4fa93a88de49bbef68b10eb15aabedf28ca0e1ed # v1.0.271
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
github_token: ${{ github.token }}
plugin_marketplaces: 'https://github.com/anthropics/claude-plugins-official.git'
plugins: 'code-review@claude-plugins-official'
# The plugin stops when Claude already commented, which would make an
# "@claude review" re-run a no-op. It also reads CLAUDE.md, which this repo names AGENTS.md.
prompt: |
/code-review:code-review --comment ${{ github.repository }}/pull/${{ env.PR_NUMBER }}

Overrides for this repository:
- In step 1, skip the "Claude has already commented" check. Earlier review comments never stop this review; this may be a re-review after fixes, so review the current diff and do not repeat findings that earlier comments already raised and that are still unchanged.
- Treat every AGENTS.md file as a CLAUDE.md file.
claude_args: |
--model sonnet
--allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr comment:*)"
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ This repository is a pnpm/Turborepo workspace using TypeScript and React.
## Iteration and CI failures

- During development, run the changed tests and relevant package lint/type checks first. `pnpm run check-types` type-checks every package with TypeScript 7's native `tsc` in about 12 s, the same check CI runs. Run the local fast suite once the change is ready, plus affected files excluded from it. After rebasing or resolving conflicts, rerun affected checks and `pnpm run check-format` before pushing; a previous green run validates the previous tree.
- Review your diff with a subagent before opening a PR or pushing new commits to one, because every PR push runs CI. Give the reviewer the diff against `main` and the task, not your conclusions, and ask for correctness bugs, missing tests and leftover debug code. Fix what it confirms, rerun the affected checks, and say in the PR which findings you fixed and which you left. Backup pushes to a branch with no open PR run no CI and need no review.
- PR CI runs only the quick suites. The browser files and behaviour specs run in the merge queue, so run the ones your change touches locally before queueing, or label the PR `full-ci` to run them on the PR (docs/TESTING.md).
- Report only what ran: in PRs and replies, say which checks and tests you ran and which you couldn't. A local pass is not CI, and a test you didn't run is not evidence.
- Push coherent, validated milestones. Superseded PR commits cancel their CI, so avoid repeated pushes of incomplete fixes that discard useful validation.
Expand All @@ -73,6 +74,7 @@ This repository is a pnpm/Turborepo workspace using TypeScript and React.
- Title format: `feat/fix/chore/docs(<project_name>) <Title>`
- Open reviewable dependent PRs as soon as their work is ready; distinguish a dependency blocking merge from one blocking review or initial validation. State the dependency and base explicitly, and account for the workflow's target-branch triggers when deciding which checks can run before retargeting.
- Keep CI and workflow changes out of feature PRs. If a feature needs one, open a separate PR (or an issue) for it, so the change gets its own review and can be reverted alone.
- The `Claude review` workflow comments on a same-repo PR when it opens, is reopened or leaves draft. A collaborator's `@claude review` comment reviews it again after fixes. Address its findings, or reply why not, before queueing.
- When asked to merge, queue the PR in Mergify (see `docs/TESTING.md`): tick "Queue this pull request" in Mergify's comment on the PR, or comment `@mergifyio queue`, then check that the "Mergify Merge Queue" check shows it queued. Don't use GitHub auto-merge. Continue monitoring until it merges or a concrete blocker needs action. After a queue rejection, inspect the reason and current candidate, address it, and requeue when appropriate; a retry of an obsolete candidate does not validate a new one.
- Do not routinely rebase a healthy queued PR just because main advanced; the queue validates the combined candidate. Update the branch when resolving an actual conflict or incorporating a required fix, then validate the changed tree.

Expand Down