GPTMap

Codex CI 集成实战:把 Codex CLI 跑进 GitHub Actions

把 Codex CLI 接入 GitHub Actions 做自动 PR review / 自动补测试 / 自动文档。覆盖认证方式(API key vs OAuth)、缓存(npm store)、并发安全(每个 job 独立 worktree)、审计合规(log 留痕 + 人工 gate)。

TL;DR
Codex CLI 接入 GitHub Actions 是把 AI 代码能力从「本地玩具」升级为「团队基础设施」的关键一步。本指南覆盖四种典型场景(PR review / 补测试 / 文档同步 / 周报生成)、两种认证方式(API key vs OAuth)的取舍、并发隔离(每个 job 独立 worktree)、缓存策略(npm store + Codex config)、审计合规(log 留痕 + 人工 gate + token 计费上限)。文末给出可复用的 workflow 模板。
Codex CI 集成是把 Codex CLI 跑进 GitHub Actions / GitLab CI 等持续集成流水线,让 AI 自动完成 PR review、补测试、写文档等重复工作,并通过并发隔离、缓存、审计合规把这件事做成可托付的团队基础设施。

操作步骤

  1. 准备 OpenAI 认证

    在 OpenAI 控制台创建 OAuth credential(org-scoped),下 device flow client id + secret。把 client secret 存进 GitHub repo 的 secret `OPENAI_OAUTH_CLIENT_SECRET`。

  2. 写 workflow 文件

    在 `.github/workflows/codex-review.yml` 写 workflow:on pull_request 触发 → checkout 代码 → 装 Codex CLI → 用 device flow 拿 token → 跑 `codex exec --json review diff` → 把结果发 PR 评论。

  3. 加缓存与并发隔离

    在 workflow 里加 actions/cache(key: codex-npm-${{ hashFiles('package-lock.json') }}),并用 concurrency 字段限同 PR 同时只有一个 review job。

  4. 接审计与预算

    workflow 里设 `MAX_TOKENS=50000` 环境变量,把 Codex JSON 输出存成 artifact(保留 7 天),并在 OpenAI 控制台设月度 budget。

  5. 试跑 + 调 prompt

    开一个测试 PR 触发 workflow,看 Codex review 质量。常见的调整:(1) prompt 加 diff 上下文;(2) review scope 限 200 行;(3) 输出格式改 JSON 方便后续自动处理。

Codex CLI 跑在本地是「程序员的好帮手」,但跑在 CI 里才能成为「团队的基础设施」。本文教你把 Codex 接入 GitHub Actions,覆盖四种典型场景、两种认证方式、并发隔离、缓存、审计合规。文末附可复用 workflow。

为什么把 Codex 跑进 CI

本地跑 Codex 是 1 个人用,CI 跑 Codex 是整个团队用。三个关键差异:

  1. 一致性:所有 PR 都过同一道 AI review,避免「有的 PR 有人看、有的 PR 没人看」。
  2. 留痕:CI 输出自动存档到 artifact,方便事后审计、合规、复盘。
  3. 规模化:本地 Codex 受限于单机 CPU/GPU,CI 可以并发几十个 job 同时 review 几十个 PR。

代价是引入 CI 复杂度(认证、缓存、并发安全),下文逐项解决。

场景矩阵:先选你要解决的痛点

场景输入输出推荐模型平均 token
PR 自动 reviewdiff + PR descriptionreview 评论(行内 + 总结)gpt-5.6-terra20k-50k
自动补测试源码 + 接口契约新 test 文件 + 单测gpt-5.6-sol30k-80k
文档同步改动文件 + README更新文档(README/API doc)gpt-5.6-luna10k-30k
周报生成git log + Slack 消息周报 markdowngpt-5.6-luna5k-15k

新手建议从「PR 自动 review」入手——单文件、输入明确、效果好;周报生成最简单,但容易被忽略。

认证:API key vs OAuth

# ❌ 不推荐:API key
env:
  OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

# ✅ 推荐:OAuth 设备流
env:
  OPENAI_OAUTH_CLIENT_ID: ${{ secrets.OAUTH_CLIENT_ID }}
  OPENAI_OAUTH_CLIENT_SECRET: ${{ secrets.OAUTH_CLIENT_SECRET }}

API key 的问题:一旦 secret 泄漏,整个 OpenAI 账户都要换 key(key 是全局的)。 OAuth 设备流的优势:refresh token 短期(默认 1 小时),可单 repo 撤销,泄漏只影响一个 repo。

OAuth 首次配置稍复杂:在 OpenAI 控制台 → API Keys → OAuth 创建一个 org-scoped credential,记下 client id + secret。

并发隔离

CI 跑 Codex 最容易翻车的是「并发 job 改同一个 worktree」。三件事解决:

jobs:
  codex-review:
    runs-on: ubuntu-latest
    # 关键 1:同 PR 同时只跑一个 job
    concurrency:
      group: codex-review-${{ github.event.pull_request.number }}
      cancel-in-progress: true
    steps:
      - uses: actions/checkout@v4
        with:
          # 关键 2:每个 job 独立 worktree
          ref: ${{ github.event.pull_request.head.ref }}
          fetch-depth: 0

      - name: Install Codex CLI
        run: npm install -g @openai/codex
        env:
          # 关键 3:每个 job 独立 config 目录
          CODEX_HOME: /tmp/codex-${{ github.run_id }}

并发隔离的三道防线:concurrency 限同 PR 单 job + checkout 到独立 worktree + Codex config 走临时目录。

缓存:把 90s 降到 20s

- name: Cache Codex + npm
  uses: actions/cache@v4
  with:
    path: |
      ~/.npm
      ~/.codex
    key: codex-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
    restore-keys: |
      codex-${{ runner.os }}-
  • ~/.npm:npm 全局包缓存(Codex CLI 装在全局)
  • ~/.codex:Codex 配置缓存(OAuth token、缓存的 prompt)

效果:第二次跑 workflow 平均从 90s → 20s。

审计合规

Codex 在 CI 跑会有「AI 改坏代码」的合规风险。三道闸:

  1. Log 留痕:所有 Codex --json 输出存成 artifact(保留 7 天),出问题时回溯。
  2. 人工 gate:自动 PR 必须有人 approve(branch protection 设 required_approving_review_count: 1)。
  3. Token 预算:workflow 里设 MAX_TOKENS 上限,避免 prompt 异常导致烧 token。
- name: Run Codex review
  run: codex exec --json "review diff" > codex-output.json
  env:
    MAX_TOKENS: 50000

- name: Upload artifact
  uses: actions/upload-artifact@v4
  with:
    name: codex-review-${{ github.event.pull_request.number }}
    path: codex-output.json
    retention-days: 7

实战:PR review workflow 模板

name: Codex PR Review

on:
  pull_request:
    types: [opened, synchronize, reopened]

permissions:
  contents: read
  pull-requests: write

jobs:
  codex-review:
    runs-on: ubuntu-latest
    concurrency:
      group: codex-review-${{ github.event.pull_request.number }}
      cancel-in-progress: true

    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.ref }}
          fetch-depth: 0

      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install Codex CLI
        run: npm install -g @openai/codex

      - name: Cache
        uses: actions/cache@v4
        with:
          path: |
              ~/.npm
              ~/.codex
            key: codex-${{ runner.os }}-${{ hashFiles('package-lock.json') }}

      - name: Run Codex review
        id: review
        run: |
          codex exec --json \
            "Review the following PR diff. Focus on: bugs, edge cases, test coverage. Output as JSON with keys: summary, issues[]. Provide line-level comments." \
            < <(git diff origin/${{ github.base_ref }}...HEAD) \
            > codex-review.json
        env:
          MAX_TOKENS: 50000
          OPENAI_OAUTH_CLIENT_ID: ${{ secrets.OAUTH_CLIENT_ID }}
          OPENAI_OAUTH_CLIENT_SECRET: ${{ secrets.OAUTH_CLIENT_SECRET }}

      - name: Post review comment
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const review = JSON.parse(fs.readFileSync('codex-review.json', 'utf8'));
            const body = [
              '## Codex Review',
              '**Summary**: ' + review.summary,
              '',
              '**Issues**:',
              ...review.issues.map(i => `- ${i.file}:${i.line} - ${i.message}`)
            ].join('\n');
            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              body
            });

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: codex-review-${{ github.event.pull_request.number }}
          path: codex-review.json
          retention-days: 7

OAUTH_CLIENT_ID / OAUTH_CLIENT_SECRET 换成你自己的就能直接用。

常见坑

  1. OAuth token 在 job 之间复用:每个 job 重新走 device flow,不要用 actions/cache 缓存 refresh token。
  2. diff 太大撑爆 context:超过 500 行就拆成多轮 review,或用 git diff --unified=0 砍上下文。
  3. Codex 改动了非 review 文件:强制 Codex 只读不改(codex exec --readonly),避免 AI 越权。
  4. artifact 太大撑爆 storage:JSON 输出 gzip 压缩(codex-review.json.gz)。
  5. prompt 没指定输出格式:Codex 输出飘忽不定,prompt 必须要求 JSON / 表格 / 行内评论之一。

下一步

关键要点

  • 认证优先选 OAuth(设备流 + 短期 refresh token),而不是把 API key 写进 secret——前者每次 job 自动续期、可单 repo 撤销,泄露面小一个数量级
  • 并发安全靠 worktree:每个 job 用 `actions/checkout` 拉到独立 worktree(`ref: ${{ github.event.pull_request.head.ref }}`),Codex 改文件不会污染主分支
  • 缓存两层:actions/cache 缓存 npm store + Codex config,让 workflow 第二次起跑从 90s 降到 20s
  • 审计合规三件套:log 留痕(--verbose 输出到 artifact)+ 人工 gate(自动 PR 必须有人 approve)+ token 预算(设 MAX_TOKENS 防爆刷)
  • 四种典型场景的 prompt 模板:PR review 要带 diff、tests 要带源码 + 接口契约、docs 要带 README、weekly digest 要带 git log

常见问题

都要,但分工不同:本地开发用 Codex 做实时结对(响应 5-10s),CI 跑 Codex 做批量异步(响应 1-5 分钟)。CI 场景主要是 PR review / 自动补测试 / 文档同步 / 周报生成——这些场景本地做太分散,统一跑 CI 才能保证口径一致 + 留痕。

官方参考

相关文章

订阅 GPTMap Weekly

每周一封邮件,精选 OpenAI 重要更新、深度解读与最佳实践。无广告,可随时退订。

GPTMap Editorial发布于 2026-08-08 7 分钟阅读
测试环境(EEAT)
最后测试时间:2026-08-08
使用模型:gpt-5.6