A GitHub Action that reviews pull requests with Claude or Cursor and posts severity-rated inline comments plus an Approval Verdict check run. It reviews only the lines a PR changes, caps nitpicks, and reconciles its own threads across pushes.
Add a workflow to your repo:
name: Code Review
on:
pull_request:
types: [opened, synchronize, ready_for_review]
issue_comment:
types: [created]
permissions:
contents: read
pull-requests: write
checks: write
jobs:
review:
name: Review
runs-on: ubuntu-latest
if: >-
(github.event_name == 'pull_request'
&& github.event.pull_request.head.repo.full_name == github.repository)
|| (github.event_name == 'issue_comment'
&& github.event.issue.pull_request
&& startsWith(github.event.comment.body, 'agent review'))
concurrency:
group: code-review-${{ github.event.pull_request.number || github.event.issue.number }}-${{ github.event_name == 'issue_comment' && 'comment' || 'review' }}
cancel-in-progress: true
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || format('refs/pull/{0}/head', github.event.issue.number) }}
- uses: julien777z/code-review-action@v0
with:
cursor-api-key: ${{ secrets.CURSOR_API_KEY }}Provide at least one backend credential (anthropic-api-key or cursor-api-key). Comment
agent review on a PR to trigger a manual review.
Each snippet is the with: block for the step in the Quick start workflow — swap it in.
Use Claude instead of Cursor:
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}Claude on the first review, Cursor on later pushes:
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
cursor-api-key: ${{ secrets.CURSOR_API_KEY }}
first-review-model: claude
review-model: cursorComment only, scoped to source files:
with:
cursor-api-key: ${{ secrets.CURSOR_API_KEY }}
approval-disable: "true"
include-paths: "src/**"
exclude-paths: "**/*.lock"Request changes only on critical or high findings:
with:
cursor-api-key: ${{ secrets.CURSOR_API_KEY }}
approval-include: "critical, high"review-model—auto(default),claude, orcursor.autoprefers Claude when an Anthropic key is set, otherwise uses Cursor.first-review-model— optional backend used for the PR's first review (opened / ready for review). When empty,review-modelis used for every event. Example:first-review-model: claudewithreview-model: cursorreviews the opened PR with Claude and later pushes with Cursor.
With enforce-project-rules on (the default), the review applies your repository's own coding rules
and reports a finding on any changed line that violates them. Each backend loads whatever rule files it
understands (for example .cursor/rules or CLAUDE.md / .claude/rules).
Cursor backend. Cursor runs a local agent that loads your .cursor/rules from the checked-out
repository's working directory. Check out the repo before this action so those files are present:
steps:
- uses: actions/checkout@v4
- uses: julien777z/code-review-action@v0
with:
cursor-api-key: ${{ secrets.CURSOR_API_KEY }}Claude backend. Claude reviews through a Managed
Agents session that mounts the repository at the
PR's head commit, so Claude Code loads CLAUDE.md / .claude/rules natively. The repository is cloned
with the run's github-token (which needs contents: read), so no extra GitHub connection is required.
When enforce-project-rules is false, the session runs without the repository mounted and reviews
from the diff alone.
enforce-project-rules— set tofalseto skip loading and enforcing the repo's rules (defaulttrue).project-rules-severity— pin every rule violation to a fixed severity (critical,high,medium, orlow). Empty lets the review rate each violation itself (default empty). Set this abovelowwhen rule violations are being crowded out bylow-findings-cap.
Off by default, the review can also suggest code simplifications (optional suggestions that never block).
simplify-suggest— apply the agent'scode-simplifyskill to the changed code and suggest simplifications (defaultfalse).simplify-suggest-severity— severity to report those suggestions at (critical,high,medium, orlow). Empty defaults tolow; raise it so suggestions are not crowded out bylow-findings-cap.simplify-nearby-code— extend those suggestions to weigh the nearby and related code the change touches, not just the changed lines in isolation (defaultfalse). Findings still anchor on changed lines.
approval-include— severities that request changes when left open (defaultcritical). Other open findings post as a comment; zero open findings approves.approval-disable— post comments only and skip the verdict and check run.
As the PR evolves the action resolves the review threads whose findings no longer apply. The default
GITHUB_TOKEN cannot resolve review threads — GitHub rejects resolveReviewThread with "Resource
not accessible by integration" — so by default stale threads stay open even though the verdict count is
correct.
To enable auto-resolution, give the action a token with pull-request write via resolve-token. It is
used only to resolve threads, so review comments stay authored by github-actions[bot].
A GitHub App is the best fit across several repos: create it once, install it on each repo, and the same workflow snippet below mints a per-repo token automatically. The minted token is short-lived — it expires after an hour and is revoked when the job ends — so nothing long-lived is stored. The App is yours and lives in your account; no server to run.
- Create a GitHub App (Settings → Developer settings → GitHub Apps → New GitHub App). Under Permissions → Repository → Pull requests select Read and write; leave everything else off.
- Install the App on every repository whose threads it should resolve.
- On the App's settings page, note its Client ID and Generate a private key (downloads a
.pem). - Expose the credentials to those repos' workflows:
- Organization repos: add an organization variable
CODE_REVIEW_APP_CLIENT_IDand organization secretCODE_REVIEW_APP_PRIVATE_KEYonce, scoped to the repos that use the action. - Personal repos: add the same variable and secret to each repo (personal accounts have no secrets shared across repos).
- Organization repos: add an organization variable
- Mint a token in the workflow and pass it to
resolve-token:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || format('refs/pull/{0}/head', github.event.issue.number) }}
- uses: actions/create-github-app-token@v3
id: app-token
with:
client-id: ${{ vars.CODE_REVIEW_APP_CLIENT_ID }}
private-key: ${{ secrets.CODE_REVIEW_APP_PRIVATE_KEY }}
- uses: julien777z/code-review-action@v0
with:
cursor-api-key: ${{ secrets.CURSOR_API_KEY }}
resolve-token: ${{ steps.app-token.outputs.token }}For a single repository, a fine-grained PAT with Pull requests: write stored as the
CODE_REVIEW_TOKEN secret also works (resolve-token: ${{ secrets.CODE_REVIEW_TOKEN }}), but it is
tied to your account and expires, so the App scales better.
| Input | Default | Description |
|---|---|---|
github-token |
${{ github.token }} |
Token to read the diff and post reviews/checks |
resolve-token |
— | Token with pull-request write to resolve the action's own threads (e.g. a GitHub App token) |
anthropic-api-key |
— | Anthropic key for Claude reviews and PR-summary generation |
cursor-api-key |
— | Cursor key for the Cursor backend |
review-model |
auto |
auto | claude | cursor |
first-review-model |
— | Backend for the first review; empty uses review-model |
claude-model |
claude-opus-4-8 |
Anthropic model id for Claude reviews and summaries |
cursor-model |
composer-2.5 |
Cursor model id |
additional-context |
— | Extra context for the review |
approval-include |
critical |
Severities that request changes when open |
approval-disable |
false |
Comments only; skip the verdict |
pr-review-summary |
true |
Append an AI summary to the PR description on the first review |
enforce-project-rules |
true |
Enforce the repository's own coding rules; no-op when it defines none |
project-rules-severity |
— | Fixed severity for rule violations; empty lets the review rate each |
simplify-suggest |
false |
Suggest code simplifications via the code-simplify skill |
simplify-suggest-severity |
— | Severity for simplification suggestions; empty defaults to low |
simplify-nearby-code |
false |
Extend simplification suggestions to weigh nearby/related code |
min-severity |
low |
Lowest severity worth posting |
low-findings-cap |
3 |
Max low-severity findings per review; the runner selects the most important lows once the review stream ends |
max-findings |
— | Overall inline-comment cap (empty = uncapped) |
include-paths |
— | Globs to restrict the review to |
exclude-paths |
— | Globs to skip |
trigger-phrase |
agent review |
Comment phrase for a manual review |
review-drafts |
true |
Review draft PRs |
pr-number |
— | PR number for workflow_dispatch runs |
review-timeout-minutes |
15 |
Cap on the review agent's runtime; shortly before the cap the runner interrupts the agent and asks it to emit any findings it has not yet reported, so a cut-off still posts what was found. 0 disables |
Pin the moving major tag for automatic patches:
- uses: julien777z/code-review-action@v0MIT