Skip to content

Commit 8972918

Browse files
Dere-Wahcursoragent
andcommitted
[REA-3711] Review pull requests with Codex
Automated review runs on `openai/codex-action`, driven by one workflow that keeps the trigger gate, the model, and the review prompt in the same file. Review is limited to maintainers: it runs when an owner, member, or collaborator opens a pull request, and on demand when one of them comments `/review`. An outside contributor's pull request never reaches a runner, so untrusted code is never checked out and no review budget is spent on it. The action verifies that the actor has write access as well, which leaves the trigger gate as the cheap first barrier rather than the only one. The prompt carries the standards that ruff and ty cannot check: the rule against assuming infrastructure this package does not ship, tests arriving with the behaviour they cover, Google-style docstrings, and strict typing. Findings land as inline comments on the offending lines, and a review that finds nothing posts a single `lgtm` comment. The job runs in a `codex-review` environment, which scopes access to the `OPENAI_API_KEY` the review needs. Without that secret the review fails and reports nothing, which leaves merges unaffected. Signed-off-by: Dere-Wah <derexcontact@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent a45a737 commit 8972918

1 file changed

Lines changed: 71 additions & 24 deletions

File tree

Lines changed: 71 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,100 @@
1-
name: Claude Code Review
1+
# Copyright (c) 2026 Reactor Technologies, Inc. All rights reserved.
2+
name: Codex Code Review
23

34
on:
45
pull_request:
56
types: [opened, ready_for_review, reopened]
67
issue_comment:
78
types: [created]
9+
workflow_dispatch:
10+
inputs:
11+
pr_number:
12+
description: 'PR number to review'
13+
required: true
14+
type: string
815

916
jobs:
10-
claude-review:
17+
codex-review:
1118
# Token-burning is gated to maintainers: review runs automatically on a
1219
# maintainer-authored PR, or on demand when a maintainer comments `/review`.
13-
# Outside contributors never trigger it implicitly. The `claude-code-review`
14-
# environment scopes access to the ANTHROPIC_API_KEY.
20+
# Outside contributors never trigger it implicitly. codex-action re-checks
21+
# that the actor has write access, but gating here keeps an outsider's PR
22+
# from ever reaching a runner or being checked out. The `codex-review`
23+
# environment scopes access to the OPENAI_API_KEY.
1524
if: |
1625
(
1726
github.event_name == 'pull_request' &&
1827
!github.event.pull_request.draft &&
19-
!contains(github.event.pull_request.title, '[skip-claude]') &&
28+
!contains(github.event.pull_request.title, '[skip-codex]') &&
2029
github.event.pull_request.user.login != 'dependabot[bot]' &&
2130
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.pull_request.author_association)
2231
) || (
2332
github.event_name == 'issue_comment' &&
2433
github.event.issue.pull_request &&
2534
github.event.comment.body == '/review' &&
2635
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)
27-
)
36+
) || github.event_name == 'workflow_dispatch'
2837
runs-on: ubuntu-latest
29-
environment: claude-code-review
38+
environment: codex-review
3039
permissions:
3140
contents: read
3241
pull-requests: write
3342
issues: read
3443
id-token: write
3544

3645
steps:
46+
- name: Resolve PR metadata
47+
id: pr
48+
env:
49+
GH_TOKEN: ${{ github.token }}
50+
GH_REPO: ${{ github.repository }}
51+
EVENT_NAME: ${{ github.event_name }}
52+
PR_EVENT_NUMBER: ${{ github.event.pull_request.number }}
53+
PR_EVENT_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
54+
ISSUE_NUMBER: ${{ github.event.issue.number }}
55+
DISPATCH_PR_NUMBER: ${{ inputs.pr_number }}
56+
run: |
57+
set -euo pipefail
58+
if [ "$EVENT_NAME" = "pull_request" ]; then
59+
number="$PR_EVENT_NUMBER"
60+
head_sha="$PR_EVENT_HEAD_SHA"
61+
else
62+
if [ "$EVENT_NAME" = "issue_comment" ]; then
63+
number="$ISSUE_NUMBER"
64+
else
65+
number="$DISPATCH_PR_NUMBER"
66+
fi
67+
head_sha=$(gh pr view "$number" --json headRefOid --jq '.headRefOid')
68+
fi
69+
echo "number=$number" >> "$GITHUB_OUTPUT"
70+
echo "head_sha=$head_sha" >> "$GITHUB_OUTPUT"
71+
3772
- name: Checkout repository
3873
uses: actions/checkout@v7
3974
with:
4075
fetch-depth: 0
41-
42-
- name: Run Claude Code Review
43-
id: claude-review
44-
uses: anthropics/claude-code-action@v1
76+
ref: ${{ steps.pr.outputs.head_sha }}
77+
78+
- name: Run Codex Code Review
79+
id: codex-review
80+
uses: openai/codex-action@v1
81+
env:
82+
GH_TOKEN: ${{ github.token }}
83+
REPO: ${{ github.repository }}
84+
PR_NUMBER: ${{ steps.pr.outputs.number }}
85+
PR_HEAD_SHA: ${{ steps.pr.outputs.head_sha }}
4586
with:
46-
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
47-
allowed_bots: "graphite-app"
48-
track_progress: true
87+
openai-api-key: ${{ secrets.OPENAI_API_KEY }}
88+
model: gpt-5.6-sol
89+
sandbox: danger-full-access
90+
allow-bot-users: graphite-app
4991
prompt: |
5092
REPO: ${{ github.repository }}
51-
PR NUMBER: ${{ github.event.pull_request.number || github.event.issue.number }}
93+
PR NUMBER: ${{ steps.pr.outputs.number }}
5294
5395
You are a senior engineer reviewing this pull request. Act like a helpful team member who wants to improve code quality while being respectful of the author's work.
5496
55-
First, run `gh pr view <PR NUMBER> --json title,author` to get the PR title and author.
97+
First, run `gh pr view $PR_NUMBER --json title,author` to get the PR title and author.
5698
5799
## What this repository is
58100
@@ -63,10 +105,10 @@ jobs:
63105
## Instructions
64106
65107
1. **CRITICAL: Check for existing review comments BEFORE reviewing the code.**
66-
Run: `gh api repos/${{ github.repository }}/pulls/<PR NUMBER>/comments`
67-
Parse the JSON and note each comment's `path`, `line`/`original_line`, and `body`, and whether it is from a previous bot review (look for "claude" or "github-actions" in the user login). Build a mental map of issues that have ALREADY been flagged.
108+
Run: `gh api repos/$REPO/pulls/$PR_NUMBER/comments`
109+
Parse the JSON and note each comment's `path`, `line`/`original_line`, and `body`, and whether it is from a previous bot review (look for "github-actions" in the user login). Build a mental map of issues that have ALREADY been flagged.
68110
69-
2. Review the PR diff using `gh pr diff <PR NUMBER>`.
111+
2. Review the PR diff using `gh pr diff $PR_NUMBER`.
70112
71113
3. Focus your review on:
72114
- **Bugs & Logic Errors**: actual bugs, off-by-one, None handling, race conditions, async/await misuse
@@ -88,21 +130,26 @@ jobs:
88130
89131
5. For each NEW issue you find (not previously commented on):
90132
- Double-check the existing comments list — if a similar issue exists on the same file/line, SKIP IT
91-
- Use `mcp__github_inline_comment__create_inline_comment` to comment directly on the specific line of code
133+
- Comment directly on the specific line of code:
134+
```bash
135+
gh api repos/$REPO/pulls/$PR_NUMBER/comments \
136+
-f body="<your comment>" \
137+
-f commit_id="$PR_HEAD_SHA" \
138+
-f path="<file path>" \
139+
-F line=<line number> \
140+
-f side="RIGHT"
141+
```
92142
- Keep comments concise (2-4 sentences max)
93143
- Be specific about what's wrong and why
94144
- Suggest a concrete fix when possible
95145
96146
6. Decide how to close out the review based on what you found:
97147
- **If you found at least one new issue:** leave only the inline comments from step 5. Do not post a summary comment on top of them.
98-
- **If you found no new issues at all:** post exactly one summary comment whose body is the single word `lgtm` (lowercase, nothing else). Before creating it, re-read the body you are about to submit and confirm it contains only `lgtm` — no preamble, no summary of the diff, no caveats, no extra whitespace or formatting — then create the comment with `gh pr comment <PR NUMBER> --body "lgtm"`.
148+
- **If you found no new issues at all:** post exactly one summary comment whose body is the single word `lgtm` (lowercase, nothing else). Before creating it, re-read the body you are about to submit and confirm it contains only `lgtm` — no preamble, no summary of the diff, no caveats, no extra whitespace or formatting — then create the comment with `gh pr comment $PR_NUMBER --body "lgtm"`.
99149
100150
## Review Style
101151
102152
- Be constructive, not critical
103153
- Explain the "why" behind suggestions
104154
- Ask questions if intent is unclear rather than assuming it's wrong
105155
- NEVER repeat yourself — if you've commented on something before, trust that the author saw it
106-
107-
claude_args: |
108-
--allowedTools "Read,Glob,Grep,Bash(gh api:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr comment:*),mcp__github_inline_comment__create_inline_comment"

0 commit comments

Comments
 (0)