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- reusable central review logic for multiple repositories
action.yml: composite action entrypointexamples/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
- refuses fork PRs before checking out or running code with repository secrets
- 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 action repeats the authorization, draft, and same-repository 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 shared action is meant to run only in caller jobs that already enforce same-repo execution when secrets are present.
For issue_comment events, the action also enforces the exact /codex-review command, OWNER or MEMBER association, non-draft status, and same-repository head before checkout.
Recommended caller guard:
- check whether
pr.head.repo.full_name == github.repository - skip secret-bearing review jobs for fork PRs
That means:
- automatic same-repo PR review: supported
- manual same-repo PR rerun by PR number: supported
- manual fork review with repository secrets: intentionally blocked
This is deliberate. Running fork code in a secret-bearing job is a real secret-exfiltration risk.
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-actionreview_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. - 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.
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 it 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.