Skip to main content
Lesson 14 of 20 · Codex: AI-Assisted Development

CI/CD Integration

Lesson 14 of 20 Updated November 3, 2026 Developer
On this page
  1. Codex in Your Delivery Pipeline
  2. The Official GitHub Action
  3. Automate Review for Every PR
  4. Fill Missing Tests
  5. React to a CI Failure
  6. Call Codex from Your Own Scripts
  7. Map Integration Points
  8. Keep Control of Automation
  9. Key Takeaways

Updated November 3, 2026 based on the Codex GitHub Action and Non-interactive mode pages in the Codex documentation: the legacy inputs task, criteria, scope, framework, and api-key do not exist in openai/codex-action@v1 (replaced by openai-api-key, prompt/prompt-file, sandbox, output-file, etc.). The action does not post comments on its own. The expression == failure without quotes did not work. The --apply flag is replaced by codex exec --sandbox workspace-write. Sources: Codex GitHub Action · Non-interactive mode.

Codex in Your Delivery Pipeline

Codex isn’t limited to tasks a developer launches manually. It integrates into your CI/CD pipelines to automate development tasks at every stage of the delivery cycle. This shift goes beyond saving time: code review, test generation, and bug fixes stop depending on individual discipline and become pipeline steps triggered by events, not by Friday afternoon goodwill.

The Official GitHub Action

OpenAI publishes an action, openai/codex-action@v1, that installs the CLI, starts the Responses API proxy when you provide a key, and runs codex exec with the permissions you set. Its main inputs:

InputRole
openai-api-keyThe key, stored as a GitHub secret (for example OPENAI_API_KEY)
prompt or prompt-fileThe instruction inline, or a file in the repository—one or the other, not both
sandboxread-only, workspace-write, or danger-full-access: choose the narrowest scope that suffices
model, effortThe model and reasoning effort; if empty, default values apply
output-fileSaves Codex’s final message for downstream steps
codex-argsAdditional options for codex exec
safety-strategyDefaults to drop-sudo, which strips sudo before execution and protects secrets in memory

The action runs on Linux or macOS runners (on Windows, you need safety-strategy: unsafe) after an actions/checkout of the code. It posts nothing on its own: it exposes Codex’s last message in the final-message output, which a subsequent step can post.

Automate Review for Every PR

The workflow below follows the structure of the official example: a first job runs Codex in read-only mode, and a second, granted write permissions on PRs, posts the result as a comment. Your criteria go into the prompt.

# .github/workflows/codex-review.yml
name: Codex Review
on:
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  codex:
    runs-on: ubuntu-latest
    permissions:
      contents: read
    outputs:
      final_message: ${{ steps.run_codex.outputs.final-message }}
    steps:
      - uses: actions/checkout@v5
        with:
          ref: refs/pull/${{ github.event.pull_request.number }}/merge
          fetch-depth: 0
          persist-credentials: false
      - name: Run Codex
        id: run_codex
        uses: openai/codex-action@v1
        with:
          openai-api-key: ${{ secrets.OPENAI_API_KEY }}
          sandbox: read-only
          prompt: |
            Review the changes in this pull request against the base branch.
            Priorities: security (injections, missing authentication), performance
            (N+1 queries), types (no any), tests (coverage of changes).
            Cite the files and lines involved.

  post_feedback:
    runs-on: ubuntu-latest
    needs: codex
    if: needs.codex.outputs.final_message != ''
    permissions:
      issues: write
      pull-requests: write
    steps:
      - uses: actions/github-script@v7
        with:
          github-token: ${{ github.token }}
          script: |
            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,
            });
        env:
          CODEX_FINAL_MESSAGE: ${{ needs.codex.outputs.final_message }}

The prompt deserves more attention than the rest of the file: it transforms a generic review into one that matches your priorities. You can move it out of the YAML into a versioned file, for example .github/codex/prompts/review.md, referenced by prompt-file. For a simple PR review, the automatic review built into GitHub (Lesson 11) avoids writing a workflow altogether.

Fill Missing Tests

A second workflow tackles code delivered without tests. Codex needs to write to the workspace here (sandbox: workspace-write), but the result remains a proposal: the workflow turns it into a downloadable patch that the developer reviews and applies themselves.

# .github/workflows/codex-tests.yml
name: Codex Generate Tests
on:
  pull_request:
    types: [opened]

jobs:
  generate-tests:
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@v5
        with:
          fetch-depth: 0
          persist-credentials: false
      - name: Generate missing tests
        uses: openai/codex-action@v1
        with:
          openai-api-key: ${{ secrets.OPENAI_API_KEY }}
          sandbox: workspace-write
          prompt: |
            For every file modified in this pull request that lacks a test,
            write the missing tests using Vitest, then run them.
      - name: Save the proposed tests as a patch
        run: git diff > codex-tests.patch
      - uses: actions/upload-artifact@v4
        with:
          name: codex-tests
          path: codex-tests.patch

The developer keeps control end-to-end: they fetch the patch, adapt it, or reject it. The action documentation recommends running Codex last in a job so downstream steps don’t inherit unexpected changes—here, the only next step just reads the diff.

React to a CI Failure

The third workflow hooks into the result of another workflow. When CI fails, Codex replays the tests on the relevant commit, hunts down the cause, and renders a diagnosis without pushing anything:

# .github/workflows/codex-diagnose.yml
name: Codex Diagnose CI
on:
  workflow_run:
    workflows: ["CI"]
    types: [completed]

jobs:
  diagnose:
    if: ${{ github.event.workflow_run.conclusion == 'failure' }}
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - uses: actions/checkout@v5
        with:
          ref: ${{ github.event.workflow_run.head_sha }}
          persist-credentials: false
      - name: Analyze the CI failure
        uses: openai/codex-action@v1
        with:
          openai-api-key: ${{ secrets.OPENAI_API_KEY }}
          sandbox: workspace-write
          output-file: codex-diagnostic.md
          prompt: |
            CI failed on this commit. Run the tests, identify the cause of the failure,
            and propose a fix without modifying the test logic.
      - uses: actions/upload-artifact@v4
        with:
          name: codex-diagnostic
          path: codex-diagnostic.md

This one demands the most caution. A failing test sometimes signals a design flaw, and a plausible automatic fix can make it disappear from the screen without solving it: CI turns green again, but the problem remains. Hence the choice of a diagnosis to review rather than an automatically pushed commit.

Call Codex from Your Own Scripts

Outside GitHub Actions, codex exec fits into any script. By default, it runs in a read-only sandbox; give it write permission with --sandbox workspace-write when the task requires it. The pre-commit hook below flags TypeScript files without tests and generates one on the fly:

#!/bin/bash
# Pre-commit hook script

# Check that modified files have tests
CHANGED=$(git diff --cached --name-only --diff-filter=ACM | grep '\.ts$' | grep -v '\.test\.ts$')
for file in $CHANGED; do
  test_file="${file%.ts}.test.ts"
  if [ ! -f "$test_file" ]; then
    echo "⚠️ File without test: $file"
    codex exec --sandbox workspace-write "Write tests for $file in $test_file"
    git add "$test_file"
  fi
done

In CI, codex exec reuses saved authentication by default; instead, provide credentials explicitly using a dedicated API key.

Map Integration Points

Once these building blocks are in place, think in terms of delivery cycle events rather than YAML files. The five scenarios below cover the most common cases:

CI/CD StageCodex TaskTrigger
PR openedAutomatic reviewpull_request opened
PR openedTest generationpull_request opened
CI failureAnalysis and fixworkflow_run failure
ReleaseAutomatic changelogtag push
Dependency updateCompatibility checkDependabot PR

Keep Control of Automation

A CI/CD integration runs unattended, which calls for some basic precautions. Limit who can trigger workflows—by default, only users with write permissions can run the action (use allow-users, allow-bots to explicitly broaden this). Sanitize input from PRs, commit messages, or issues before handing it to Codex: hidden text can contain a prompt injection. Use an API key dedicated to minimal permissions rather than a developer’s personal key, which they will take with them when they leave the company, breaking your pipelines. Never automatically merge a fix produced by Codex: human review remains the gate to the main branch. Set explicit limits on the number of tasks per day and maximum cost so a misconfigured correction loop doesn’t burn through your monthly budget overnight. Finally, keep a history of Codex tasks executed in CI: the day an unexpected behavior appears in production, these logs will be your only solid lead.

Key Takeaways

  • Codex integrates into GitHub Actions and other CI/CD systems
  • Automatic review on PRs is the most common use case
  • Codex can fix CI failures automatically
  • The CLI enables integration into custom scripts
  • Always keep a human in the loop to validate fixes