diff --git a/.github/workflows/codex-pr-review.yml b/.github/workflows/codex-pr-review.yml index d0ca5aa59c..e945f5fd45 100644 --- a/.github/workflows/codex-pr-review.yml +++ b/.github/workflows/codex-pr-review.yml @@ -20,13 +20,13 @@ jobs: - name: Check Codex configuration id: codex_config env: - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + CODEX_AUTH_JSON: ${{ secrets.CODEX_AUTH_JSON }} run: | - if [ -n "$OPENAI_API_KEY" ]; then + if [ -n "$CODEX_AUTH_JSON" ]; then echo "enabled=true" >> "$GITHUB_OUTPUT" else echo "enabled=false" >> "$GITHUB_OUTPUT" - echo "OPENAI_API_KEY is not configured; skipping Codex review." + echo "CODEX_AUTH_JSON is not configured; skipping Codex review." fi - name: Checkout repository @@ -36,6 +36,32 @@ jobs: ref: refs/pull/${{ github.event.pull_request.number }}/merge fetch-depth: 1 + - name: Set up Node.js + if: steps.codex_config.outputs.enabled == 'true' + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Install Codex CLI + if: steps.codex_config.outputs.enabled == 'true' + run: npm install --global @openai/codex@0.117.0 + + - name: Configure file-backed Codex auth + if: steps.codex_config.outputs.enabled == 'true' + env: + CODEX_AUTH_JSON: ${{ secrets.CODEX_AUTH_JSON }} + run: | + CODEX_HOME="$HOME/.codex" + echo "CODEX_HOME=$CODEX_HOME" >> "$GITHUB_ENV" + mkdir -p "$CODEX_HOME" + chmod 700 "$CODEX_HOME" + cat > "$CODEX_HOME/config.toml" <<'EOF' + cli_auth_credentials_store = "file" + EOF + printf '%s' "$CODEX_AUTH_JSON" > "$CODEX_HOME/auth.json" + chmod 600 "$CODEX_HOME/auth.json" + node -e 'JSON.parse(require("fs").readFileSync(process.argv[1], "utf8"))' "$CODEX_HOME/auth.json" + - name: Pre-fetch base and head refs for the PR if: steps.codex_config.outputs.enabled == 'true' env: @@ -85,27 +111,35 @@ jobs: - name: Run Codex review if: steps.codex_config.outputs.enabled == 'true' - id: run_codex - uses: openai/codex-action@v1 - with: - openai-api-key: ${{ secrets.OPENAI_API_KEY }} - prompt-file: .github/codex/pr-review.prompt.md - model: gpt-5.4 - effort: xhigh - sandbox: read-only - safety-strategy: drop-sudo + run: | + codex exec \ + -C "$GITHUB_WORKSPACE" \ + -m gpt-5.4 \ + -c 'model_reasoning_effort="xhigh"' \ + -s read-only \ + -o codex-final-message.md \ + - < .github/codex/pr-review.prompt.md - name: Post Codex review comment - if: steps.codex_config.outputs.enabled == 'true' && steps.run_codex.outputs.final-message != '' + if: steps.codex_config.outputs.enabled == 'true' uses: actions/github-script@v7 - env: - CODEX_FINAL_MESSAGE: ${{ steps.run_codex.outputs.final-message }} with: github-token: ${{ github.token }} script: | + const fs = require('fs'); + const path = `${process.env.GITHUB_WORKSPACE}/codex-final-message.md`; + if (!fs.existsSync(path)) { + core.info('Codex did not produce a final message; skipping PR comment.'); + return; + } + const body = fs.readFileSync(path, 'utf8').trim(); + if (!body) { + core.info('Codex final message was empty; skipping PR comment.'); + return; + } await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.payload.pull_request.number, - body: process.env.CODEX_FINAL_MESSAGE, + body, });