ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Codex CLI 0.153.2 落地 CI 流水线:从认证失效到沙箱逃逸的三次排查实录

Codex CLI 0.153.2 落地 CI 流水线:从认证失效到沙箱逃逸的三次排查实录 Codex CLI 0.153.2 落地 CI 流水线从认证失效到沙箱逃逸的三次排查实录上周有个需求要把 Codex CLI 0.153.2 接入公司内部 GitLab CI目标是让它在合并请求里自动跑单元测试生成和代码风格修复。按官方文档装完npm i -g openai/codex0.153.2后本地跑codex --version显示0.153.2一切正常。可一推到 RunnerJob 直接挂在认证阶段日志只吐出一行Error: Invalid API key。这就开始了长达两天的排查。环境基线| 组件 | 版本 | 说明 ||------|------|------|| Node.js | 20.18.0 | Runner 镜像自带 || npm | 10.8.2 | 随 Node 安装 || Codex CLI | 0.153.2 |npm i -g openai/codex0.153.2|| GitLab Runner | 17.3.0 | Docker executor || 基础镜像 |node:20.18-slim| Alpine 衍生版 |本地开发机是 macOS 15.1Runner 跑在 Kubernetes 集群里的linux/amd64容器。两边 Node 版本一致但操作系统不同——这点后来成了关键线索。第一坑环境变量在 Runner 里「消失」了第一反应是OPENAI_API_KEY没注入进去。去 GitLab CI/CD Variables 确认过Variable Type 是Environment variableProtected 和 Masked 都勾了Value 也填对了sk-proj-xxxx。可 Job 日志里echo $OPENAI_API_KEY打印出来是空行。yaml.gitlab-ci.yml 片段codex-review:image: node:20.18-slimstage: testvariables:OPENAI_API_KEY: $CODEX_API_KEY # 这里引用了另一个变量script:echo Key length: ${#OPENAI_API_KEY}npm i -g openai/codex0.153.2codex --versioncodex exec 生成 UserService 单元测试 --json在 Runner 容器里跑env | grep OPENAI只有OPENAI_API_KEY空值。把variables块里的引用改成直接写死$CODEX_API_KEY去掉大括号问题解决。GitLab 对变量引用的解析顺序是先展开variables:里的值再注入容器环境。如果CODEX_API_KEY本身也是 CI 变量嵌套引用会在展开阶段失效。 这个方案虽然官方文档里写得清清楚楚但在我们场景下反而更糟——因为CODEX_API_KEY是在 Group 级别定义的Project 级别的variables:块拿不到上层变量。最后改用resource_group配合trigger传参才彻底绕开。第二坑沙箱模式下无法读取.git目录认证通了跑codex exec 重构 UserController --sandbox read-only报错Error: EACCES: permission denied, open /builds/group/project/.git/configCodex 0.153.2 引入了--sandbox参数三种模式read-only、workspace-write、danger-full-access。文档说read-only允许读取工作目录下所有文件但 Runner 容器里的工作目录/builds/group/project属于root:root权限drwxr-xr-x而 Codex 进程跑在node用户UID 1000下。.git目录权限是drwxr-x---组是rootnode用户既不在组里也没 others 读权限。dockerfile修复方案自定义镜像预置权限FROM node:20.18-slimRUN groupadd -g 1000 node \usermod -a -G root node \chmod 755 /builds 2/dev/null || trueUSER node重新构建镜像推到 RegistryCI 配置里image: registry.internal/codex-runner:20.18。再跑一次read-only模式能正常读.git了。但这引出第三个问题——沙箱写模式下生成的文件宿主机看不见。第三坑workspace-write生成文件 UID/GID 不匹配需求要求 Codex 在沙箱里直接改代码、写测试文件。改用--sandbox workspace-write后Job 成功但合并请求里看不到任何变更。进 Runner 容器ls -la发现新生成的UserControllerTest.java属于1000:1000而 GitLab Runner 默认用root提交变更。Git 里配置的user.email和user.name是 Runner 的但文件所有者是node用户导致git add时出现warning: unable to access ...: Permission denied。bashCI 脚本里补齐权限修正codex exec 为 UserService 生成单元测试 --sandbox workspace-write --jsonfind . -type f -newer .git/index -exec chown root:root {} \;git config --global user.email cicompany.comgit config --global user.name GitLab CIgit add -Agit commit -m chore: codex auto-generated tests [skip ci] || truegit push origin HEAD:$CI_MERGE_REQUEST_TARGET_BRANCH_NAMEfind . -newer .git/index只改 Codex 本次运行新增/修改的文件避免把整个工作目录 chown 一遍拖慢流水线。|| true防止无变更时 commit 失败把 Job 标红。验证与回归测试跑通后补了三组回归用例| 场景 | 预期 | 实测结果 ||------|------|----------|| MR 触发Codex 生成测试覆盖率 60% | Job 通过MR 自动更新 | ✅ 通过 || 代码冲突导致git push失败 | Job 失败并报警 | ✅ 失败退出码 1 ||OPENAI_API_KEY过期 | Job 失败日志不泄露 Key | ✅ 仅显示Error: 401 Unauthorized|关键验证命令bash本地模拟 Runner 环境docker run --rm -it \-v $(pwd):/builds/project \-w /builds/project \-e OPENAI_API_KEY$OPENAI_API_KEY \registry.internal/codex-runner:20.18 \bash -c codex exec 生成测试 --sandbox workspace-write --json用--json输出方便 CI 解析配合jq提取files_changed字段做门禁判断。避坑清单变量嵌套引用别信 GitLab 文档的展开顺序直接在 CI 里export OPENAI_API_KEY$CODEX_API_KEY再跑 Codex 最稳沙箱权限模型是容器级的不是项目级的——镜像里必须把工作目录权限、用户组处理好生成文件的 UID/GID 必须与 Git 提交者一致否则git add会静默失败只报 warningCodex 0.153.2 的--json输出格式里exit_code字段在沙箱报错时为null要改判断stderr非空别在生产流水线直接跑danger-full-access哪怕内网也要走workspace-write 显式chown总结Codex CLI 0.153.2 本身功能没毛病核心矛盾全在「容器环境里的用户身份、文件权限、GitLab 变量展开顺序」这三个工程细节上。把这三个坑填平流水线从「跑不通」变成「日均处理 40 MR测试覆盖率提升 18%」才算真正落地。#后端 #Java #SpringBoot #CI/CD #CodexCLI你在实际项目中有遇到类似问题吗欢迎在评论区分享你的经验和解决方案。
返回列表