Composite GitHub Action for running openai/codex-action as a PR reviewer with:
- Azure OpenAI support
- PR summary comment upsert
- inline review comments when findings can be anchored to the diff
/codex-reviewPR comment trigger for repository owners and organization members- maintainer-triggered, patch-only reviews for pull requests from forks
- reusable central review logic for multiple repositories
action.yml: composite action entrypoint.github/workflows/fork-review.yml: fork-safe reusable workflow with separate analysis and posting jobsexamples/codex-review-command.yml: standard slash-command caller workflowexamples/codex-review-command-arc-codemods.yml:arc-codemodsslash-command workflow with repository-specific review settings.github/codex/review-output-schema.json: reference copy of the structured Codex output schema.github/workflows/review.yml: legacy reusable workflow entrypoint
In the calling repository, configure:
- Secret:
AZURE_OPENAI_API_KEY - Secret:
AZURE_OPENAI_RESPONSES_ENDPOINT - A model/deployment name to pass as
codex_model
For Azure, the endpoint must be the full Responses API URL, for example:
https://centralus.api.cognitive.microsoft.com/openai/v1/responses
Use a thin caller workflow in each repository. Keep triggers and permissions in the caller repo, then delegate the review steps here.
name: Codex PR Review
on:
pull_request:
branches:
- main
types:
- opened
- synchronize
- reopened
- ready_for_review
workflow_dispatch:
inputs:
pr_number:
description: Pull request number to review manually
required: true
type: number
jobs:
codex-review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
issues: write
if: ${{ !github.event.pull_request.draft && github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- uses: codemod/codex-review-action@main
with:
github_token: ${{ github.token }}
pr_number: ${{ github.event.pull_request.number }}
codex_model: ${{ vars.AZURE_OPENAI_CODEX_MODEL }}
azure_openai_api_key: ${{ secrets.AZURE_OPENAI_API_KEY }}
azure_openai_responses_endpoint: ${{ secrets.AZURE_OPENAI_RESPONSES_ENDPOINT }}
node_version: "24"
pnpm_version: "10.19.0"
install_command: pnpm install --frozen-lockfile
working_directory: .
codex_effort: high
permission_profile: ":workspace"
review_focus: |
Focus on:
- correctness bugs
- behavioral regressions
- missing tests or missing edge-case coverage
- security issues
extra_prompt: |
Follow any repository-specific review guidance files when present.GitHub event triggers belong to the consumer repository, so a composite action cannot register a slash command by itself. The pin-sync workflow described below automatically adds .github/workflows/codex-review-command.yml to the three managed consumer repositories. For another consumer repository, copy examples/codex-review-command.yml there manually.
Once that workflow is present on the consumer repository's default branch, a repository owner or organization member can add this exact PR comment:
/codex-review
The workflow intentionally:
- listens only for newly created PR comments
- accepts only the exact
/codex-reviewcomment - accepts only GitHub
OWNERandMEMBERauthor associations - refuses draft PRs
- routes same-repository PRs through the existing full-checkout review
- routes fork PRs through the patch-only reusable workflow
- allows inline review comments for command-triggered reviews
- serializes reviews for the same PR so repeated commands do not overlap
The caller-level if avoids starting runners for unrelated comments. The composite action and fork reusable workflow repeat their applicable authorization and trust checks as defense in depth.
Pin codemod/codex-review-action to a full commit SHA in production rather than leaving the example's @main reference in place.
The composite action remains restricted to trusted same-repository pull requests whenever it checks out code, installs dependencies, and runs Codex with repository secrets.
The command workflow resolves the PR before selecting one of two paths:
- Same-repository PRs use the composite action and retain dependency installation plus full-checkout inspection.
- Fork PRs use
.github/workflows/fork-review.ymlonly after anOWNERorMEMBERposts the exact/codex-reviewcommand.
The fork workflow deliberately does not execute fork-controlled code:
- it checks out the trusted base commit, never the fork head
- it downloads the pull request diff through the GitHub API and stores it as read-only review data
- the diff, file list, and inline comment locations use the authorized base/head commit SHAs, never a moving PR ref
- it refuses comparisons with 300 or more files because GitHub may truncate their file list
- it does not install dependencies, run builds or tests, load fork-controlled Codex configuration, or execute repository scripts
- it runs Codex with
permission-profile: ":read-only"andsafety-strategy: "drop-sudo" - Codex is the final step in the Azure-secret-bearing job
- a fresh job with no Azure credential and no checkout validates the structured result and posts the review
- results claiming the diff could not be inspected without any anchored findings fail before posting
The fork workflow pins both the Codex CLI and Responses API proxy to 0.160.0 by default. Its codex_version override must be an exact stable version (X.Y.Z); empty values, tags, and version ranges are rejected.
Normal pull_request CI for forks can continue installing dependencies and running tests under GitHub's secure defaults, which withhold repository secrets and supply a read-only token. Do not pass those jobs secrets or a write-capable token, and do not reuse their runner or executable artifacts in the fork review workflow.
That means:
- automatic same-repository PR review: supported
- manual same-repository review through
/codex-review: supported - manual fork review through
/codex-review: supported through the patch-only path - automatic fork review: intentionally not configured
github_token: required token for GitHub API calls, checkout, and comment postingpr_number: required PR number to reviewcodex_model: required Azure deployment nameazure_openai_api_key: required Azure OpenAI API keyazure_openai_responses_endpoint: required Azure OpenAI Responses API endpointworking_directory: checkout subdirectory to run fromnode_version: Node.js version foractions/setup-nodepnpm_version: pnpm version forpnpm/action-setupinstall_command: dependency installation commandcodex_effort: Codex effort levelsandbox: legacy Codex sandbox mode, used only whenpermission_profileis emptypermission_profile: Codex permission profile, default:workspacecodex_version: optional Codex CLI version passed through toopenai/codex-action; the fork workflow defaults to0.160.0and requires an exact stable versionreview_focus: extra review criteria inserted into the promptextra_prompt: extra prompt text appended after the standard review instructions
- The action expects
pnpmby default, but the caller can overrideinstall_command,node_version,pnpm_version, andworking_directory. - Fork reviews ignore dependency-installation inputs because no fork-controlled code is executed in the secret-bearing workflow.
- The action generates its output schema at runtime so callers do not need to copy schema files into their own repositories.
- The action precomputes the PR diff stat, changed files, and a bounded patch snapshot before invoking Codex so the model has review context immediately and can still inspect the checkout for deeper analysis.
- If Codex returns a meta-response claiming it cannot inspect the PR diff, the action fails closed instead of posting that response as a PR review.
- The action emits inline comments in a single batched PR review when findings have a valid
pathand a line that GitHub can anchor on the right side of the PR diff. - The action posts inline comments for
/codex-reviewcommand runs, initial PR review events (opened,reopened,ready_for_review), and manualworkflow_dispatchreruns;synchronizereruns update only the summary comment to avoid repeated inline comment spam. - The action preserves existing inline comments across reruns so review threads can be resolved manually; only the summary comment is updated in place after the initial inline review.
- If Codex returns non-JSON output unexpectedly, the action falls back to treating that output as the summary comment body.
- The OpenAI action is pinned before the runner DNS regression tracked in
openai/codex-action#160, and transient GitHub API failures during review posting are retried up to three times.
This repository includes .github/workflows/sync-action-pins.yml to keep the Codex review integration updated in downstream repositories:
codemod/arc-codemodscodemod/codemodcodemod/codemod-app
It runs on pushes to main and on manual dispatch. For each target repository, it:
- updates the
codemod/codex-review-action@<sha>reference in.github/workflows/codex-pr-review.ymlwhen that workflow uses the central action - adds or updates
.github/workflows/codex-review-command.ymlfrom the appropriate template and pins both the composite action and fork reusable workflow to the same SHA - opens or updates one draft PR on branch
codex/update-codex-review-action-<short-sha>containing both changes
Required repository secrets for this workflow:
ACTION_SYNC_APP_IDACTION_SYNC_APP_PRIVATE_KEY
Those secrets should belong to a GitHub App installation that has contents: write, pull_requests: write, and workflows: write access to the three target repositories.