Skip to content

[No QA] Skip AI reviews when they already ran for the PR head commit - #98016

Merged
Julesssss merged 7 commits into
mainfrom
neil-skip-ai-review-same-commit
Oct 2, 2026
Merged

Julesssss merged 7 commits into
mainfrom
neil-skip-ai-review-same-commit

Conversation

@neil-marcellini

@neil-marcellini neil-marcellini commented Aug 7, 2026 •

Copy link
Copy Markdown
Contributor

Explanation of Change

(Neil's AI agent)

Today, marking a PR ready for review runs the Claude reviewer again on the exact same commit it already reviewed, reposting identical findings. This gates the reviewer on whether it has already completed for the PR's current head commit.

The Codex review workflow is left unchanged because it is disabled in this repository and is being deleted in #102445.

The marker is a commit status on the head SHA — ai-review-completed/claude/pr-<number> — which is the only durable record keyed by commit. The PR number is part of the name because two PRs can share a head SHA. Reactions and comments are not tied to a commit, and workflow-run history is not either (comment-triggered runs record github.sha as the base branch head, not the PR head). The workflow gains two steps around the existing ones:

  • Check for an existing review of this commit resolves the head SHA and sets skip=true if a success status with that context is already on it. Every step that costs money or posts to the PR is gated on skip != 'true'.
  • Record review completion sets that status once the review finishes, against the SHA captured before the review started. If the author pushed mid-review, the status lands on the commit that was actually reviewed, so the next event correctly triggers a fresh review.

The status is named ai-review-completed/* rather than ai-review/* because it sits directly beside the review job in the PR's checks list. A neighbouring green row called ai-review/claude reads like a second review verdict; ai-review-completed/claude reads as the record of a past run, which is what it is.

The status is recorded whether or not the review found anything — re-running on an unchanged commit would only repost identical comments, so "already completed" is the right skip condition rather than "already passed".

Three knock-on changes in claude-review.yml, all required by the new comment trigger:

  • Added the @claude review comment trigger. Auth and Web-Expensify already have it; App did not. A skip with no manual override would leave no way to force a re-review, so this is a prerequisite rather than a nice-to-have. It also closes the on-demand inconsistency called out in the issue. A comment-triggered run never skips, since asking for a review by comment is a deliberate request to repeat it.
  • Moved the authorization check into its own authorize job. Anyone can comment @claude review, so the concurrency group (with cancel-in-progress) now sits on the review job, which only runs once the commenter is authorized. An unauthorized comment can't cancel a running review.
  • Replaced dorny/paths-filter with a paginated gh api .../pulls/<number>/files filter. paths-filter reads the pull_request event payload and has no PR context on an issue_comment event, so it cannot survive the new trigger without being handed an explicit base and ref (which in turn needs a full fetch of the PR head that pull_request_target deliberately does not do). One API call gives the same file list for both event types.

The shared scripts live in the toolkit action so Auth and Web-Expensify use the same implementation: Expensify/GitHub-Actions#97.

Sibling PRs: https://github.com/Expensify/Auth/pull/23558, https://github.com/Expensify/Web-Expensify/pull/55193

Fixed Issues

$ https://github.com/Expensify/Expensify/issues/669298
PROPOSAL: N/A

Tests

(Neil's AI agent)

pull_request_target and issue_comment workflows always run from the default branch, so this can't be tested on a PR in this repository before it merges. I tested it on a fork (neil-marcellini/App) instead, set up like this:

  • The fork's main is App's main with this PR merged in at ded2c3a. Later commits on this PR restore codex-review.yml and move the authorization check into its own job; the fork run below predates that second change.
  • In the fork's setup commit, both "Run Claude Code" steps are replaced with run: echo stub, keeping their id and if, so the steps around them behave as in production without an API key. "Post code review results" and "Setup Node" are removed because the stub needs neither. runs-on is ubuntu-latest because the fork has no Blacksmith runners. All other workflows are deleted.
  • OS_BOTIFY_TOKEN is set to a dummy value. The fork owner passes the authorization check as OWNER, and the team-membership lookup only logs a warning when the token can't read the org.

Steps, run on two draft PRs in the fork: #1 changes a file under src/, and #2 only changes a docs/**/*.md file.

  1. Open PR #1 as a draft.
  2. Confirm the review job is skipped, because the PR is a draft.
  3. Comment @claude review.
  4. Confirm the review runs and records an ai-review-completed/claude/pr-1 status with state success on the head commit, linking to the run.
  5. Mark the PR ready for review.
  6. Confirm the run logs ai-review-completed/claude/pr-1 already completed for <sha>, skipping review and that every step after "Check for an existing review of this commit" is skipped.
  7. Convert the PR back to draft, push a new commit, and mark it ready again.
  8. Confirm the review runs and records the status on the new head commit.
  9. Comment @claude review on that already-reviewed commit.
  10. Confirm the run logs Review requested by comment, running it even if ... and runs the review.
  11. Comment /codex-review.
  12. Confirm the Claude review job is skipped, because the comment doesn't contain @claude review.
  13. Mark PR #2 ready for review.
  14. Confirm the HelpDot docs reviewer ("Run Claude Code (docs)") runs and the coding-standards reviewer ("Run Claude Code (code)") is skipped, because the PR changes no file under src/. This checks that the new path filter picks the same reviewer as dorny/paths-filter did.
Results (all passed)
Step Event Run Result
2 PR opened as draft 36467130358 Job skipped
3–4 @claude review on 75a3f41 36467194114 Review ran, status recorded
5–6 Ready for review, still 75a3f41 36468155221 Review skipped
7–8 Ready for review on new commit 5796811 36468303309 Review ran, status recorded
9–10 @claude review on 5796811 36468430817 Review ran again, status replaced
11–12 /codex-review comment 36468432664 Job skipped
13–14 PR #2 ready for review 36470374202 Docs review ran, code review skipped

Step 6, ready for review on an already-reviewed commit:

success  Check for an existing review of this commit
skipped  Filter paths
skipped  Mark review as in progress
skipped  Run Claude Code (code)
skipped  Run Claude Code (docs)
skipped  Record review completion
skipped  Remove in-progress indicator
LOG: ai-review-completed/claude/pr-1 already completed for 75a3f410b57c8703bd93f84819ac0f825180722b, skipping review

Steps 8 and 10, a new commit and a manual re-request, both run the full review:

success  Check for an existing review of this commit
success  Filter paths
success  Mark review as in progress
success  Run Claude Code (code)
skipped  Run Claude Code (docs)
success  Record review completion
success  Remove in-progress indicator
LOG (step 10 only): Review requested by comment, running it even if ai-review-completed/claude/pr-1 already completed for 57968119aee4ea776720ea439eaf7d9d5cb2da78

Step 14, docs-only PR:

success  Filter paths
skipped  Run Claude Code (code)
success  Run Claude Code (docs)
success  Record review completion

Commit statuses at the end:

PR #1  75a3f41  ai-review-completed/claude/pr-1  success  -> run 36467194114
PR #1  5796811  ai-review-completed/claude/pr-1  success  -> run 36468430817
PR #2  d51855c  ai-review-completed/claude/pr-2  success  -> run 36470374202

On 5796811, the status first pointed to run 36468303309 and was replaced by the step 10 run, because GitHub keeps one status per context per commit.

  • Verify that no errors appear in the JS console

Offline tests

N/A — CI configuration only.

QA Steps

No QA — this changes GitHub Actions workflows only and has no staging or production surface.

  • Verify that no errors appear in the JS console

@neil-marcellini neil-marcellini changed the title [No QA] Skip AI reviews when they already ran for the PR head commit [HOLD Github-Actions 97] [No QA] Skip AI reviews when they already ran for the PR head commit Aug 7, 2026
Julesssss
Julesssss previously approved these changes Aug 21, 2026
@neil-marcellini neil-marcellini changed the title [HOLD Github-Actions 97] [No QA] Skip AI reviews when they already ran for the PR head commit [No QA] Skip AI reviews when they already ran for the PR head commit Sep 22, 2026
Resolves the claude-review.yml conflict by keeping the skip gate and the
gh-based path filter alongside main's rules_directory input, and points both
workflows at the toolkit commit that carries the merged scripts.

shouldSkipReview.sh builds the status context by appending the PR number, so
recordReviewComplete.sh is now handed that step's context output instead of the
bare reviewer name.

codex-review.yml passes rules_directory because the toolkit's default path does
not exist in this repo.
gh pr view --json files runs a GraphQL query capped at 100 files and does not
paginate, so on a PR with more changed files the paths that decide whether the
code or docs review runs could fall outside the list and the review would be
skipped with no error. The REST files endpoint under gh api --paginate returns
the full list.

Also writes the list to RUNNER_TEMP instead of the checked-out working tree.
@neil-marcellini

This comment has been minimized.

@neil-marcellini
neil-marcellini marked this pull request as ready for review September 28, 2026 21:04
@neil-marcellini
neil-marcellini requested a review from a team as a code owner September 28, 2026 21:04
@melvin-bot
melvin-bot Bot requested review from FitseTLT and removed request for a team September 28, 2026 21:04
@melvin-bot

melvin-bot Bot commented Sep 28, 2026

Copy link
Copy Markdown

@FitseTLT Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button]

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-29T17:57:07.800977Z bcb7674 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@neil-marcellini

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 477efcfa00

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/claude-review.yml Outdated
Comment thread .github/workflows/claude-review.yml Outdated
@neil-marcellini

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bcb7674660

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/claude-review.yml
@neil-marcellini
neil-marcellini requested review from a team and Julesssss September 29, 2026 18:11
@melvin-bot
melvin-bot Bot requested review from aimane-chnaif and removed request for a team September 30, 2026 13:41
@melvin-bot

melvin-bot Bot commented Sep 30, 2026

Copy link
Copy Markdown

@aimane-chnaif Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button]

@neil-marcellini
neil-marcellini removed the request for review from aimane-chnaif September 30, 2026 14:03
Comment thread .github/workflows/claude-review.yml Outdated

@Julesssss Julesssss left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@neil-marcellini

Copy link
Copy Markdown
Contributor Author

@Julesssss I updated this based on your non-blocking comment, but it was actually kind of blocking because you did not approve it last time 😄

@Julesssss
Julesssss merged commit 824cb2c into main Oct 2, 2026
14 of 17 checks passed
@Julesssss
Julesssss deleted the neil-skip-ai-review-same-commit branch October 2, 2026 21:00
@OSBotify

OSBotify commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

@OSBotify OSBotify mentioned this pull request Oct 4, 2026
59 tasks done
@OSBotify

OSBotify commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

🚀 Deployed to staging by https://github.com/Julesssss in version: 9.5.2-0 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

@OSBotify

OSBotify commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

🚀 Deployed to production by https://github.com/Julesssss in version: 9.5.2-4 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

Bundle Size Analysis (Sentry):

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants