Skip to content

feat(lc doctor): warn when local Codex version differs from Dockerfile pin - #9

Merged
github-actions[bot] merged 3 commits into
mainfrom
contrib/issue-2-codex-version
Aug 10, 2026
Merged

feat(lc doctor): warn when local Codex version differs from Dockerfile pin#9
github-actions[bot] merged 3 commits into
mainfrom
contrib/issue-2-codex-version

Conversation

@LouisDM

@LouisDM LouisDM commented Aug 10, 2026

Copy link
Copy Markdown
Owner

重开 #6。原 PR 由 @AshSgDe29071999 提交,commit 署名已保留(作者仍是原作者,我只是 cherry-pick 到新 main 上)。

为什么要重开

仓库属主对 main 做了一次历史重写并 force push。#6 是 fork PR,重写后所有旧 SHA 失效、merge base 消失,GitHub 自动关闭了它,且无法 reopen。

这是我们这边的操作导致的,不是贡献者的问题。 代码原样搬过来,避免让 @AshSgDe29071999 重做一遍。

内容

lc doctordocker/DockerfileARG CODEX_VERSION,与 codex --version 比对,不一致时给 warning 并附对齐命令。零第三方依赖。

Closes #2


⚠️ 合并前请先看 #2 里已有的 review 意见(版本比对的宽松匹配会漏报、_local_codex_version 解析失败时的降级、以及 cmd_doctor 尚无 CI 覆盖)。

…e pin

Closes #2

Compare `codex --version` with ARG CODEX_VERSION in docker/Dockerfile
so protocol skew between host and container is visible early.
claude Bot and others added 2 commits August 10, 2026 06:04
#2 的 review 意见修两处:

1. 前缀匹配会漏报。原判据里的 `pinned.startswith(local)`,在
   `codex --version` 只吐出 `0.14` 时会让 `"0.145.0".startswith("0.14")`
   成立,把不一致判成一致——正是这项检查要防的静默通过。改成补零到三段
   后按整数元组比:`0.145` == `0.145.0`,但 `0.14` != `0.145.0`。

2. `_local_codex_version` 解析失败时会返回一段非版本号的文本,然后被
   打进「本机 Codex xxx 与 ... 不一致」的 warning 里。改成返回 None,
   走已有的降级分支;并区分「没装」与「装了但版本读不出来」,前者上面
   的 tool 检查已经报过,不再重复刷一条。

另外给这项检查补了运行时门禁。scripts/test-doctor-probe.sh 已经在 CI 里
跑 `lc doctor`,但它的临时工作目录没有 docker/Dockerfile,版本比对分支
一行都执行不到。新增第 8 节:用假 Dockerfile 钉 pin、假 codex 钉本机版本,
断言一致 / 不一致 / 两段式不被前缀吞掉 / 解析失败降级 / 未安装不重复刷。
这样这个功能有了真实门禁,不需要改 .github/。
@github-actions

Copy link
Copy Markdown
Contributor

Review 结论:可以合了,两处 review 意见我直接推到本分支修掉了(f4715b4

先说结论:功能方向和实现手法都对——正则抓 ARG CODEX_VERSIONcodex --version 比对、零第三方依赖,完全按 #2 的实现提示走。原作者 @AshSgDe29071999 的 commit 保持原样没动,我的修改是独立一个 commit 叠在上面,合并时会带上 Co-authored-by

改了什么

1. 前缀匹配会漏报(原 bin/lc:617

if local == pinned or local.startswith(pinned + ".") or pinned.startswith(local):

第三个分支 pinned.startswith(local) 是有问题的:_local_codex_version 的正则 (\d+\.\d+(?:\.\d+)?) 允许两段式,一旦 codex --version 只被抓到 0.14"0.145.0".startswith("0.14")True,会打出「一致」。而这个检查存在的全部意义就是防这种静默通过。

改成补零到三段后按整数元组比:

def parts(v):
    seg = re.findall(r"\d+", v)[:3]
    return tuple(int(x) for x in seg) + (0,) * (3 - len(seg))

0.145 == 0.145.0(确实是同一版本),0.14 != 0.145.0

2. 解析失败时返回了非版本号文本(原 bin/lc:604

return m.group(1) if m else out.strip().splitlines()[0][:40]

codex --version 输出格式变了、或者进了报错分支时,这里会把一段任意文本当版本号返回,然后进比对逻辑,打出「本机 Codex codex-cli (unknown build) 与 Dockerfile 锁定的 0.145.0 不一致」这种怪话。改成返回 None,交给你已经写好的降级分支。

顺带分了一下「没装」和「装了但版本读不出来」:codex 没装的时候,上面的 tool 检查已经报过 ❌ codex 未安装,不该再刷一条「无法读取本机 codex --version」。

顺带解决了「这段代码没有 CI 门禁」

我在 #2 里说过这个 PR 卡在「cmd_doctor 从来没被 CI 跑过」。这一条现在部分过时了——#7 引入的 scripts/test-doctor-probe.sh 已经在 CI 里真跑 lc doctor 了。但它不够:那个脚本只把 bin/scripts/ 复制进临时目录,临时目录里没有 docker/Dockerfile,所以 _dockerfile_codex_version() 直接返回 None,版本比对那几行一行都执行不到。

于是给它加了第 8 节:假 Dockerfile 钉 pin、PATH 里塞假 codex 钉本机版本,断言 6 种情形——

  • 版本相同 → 判一致,且不误报「不一致」
  • 版本不同 → 给 warning,且附带 npm i -g @openai/codex@0.145.0
  • 0.14 vs 0.145.0 → 必须判不一致(钉死上面那个前缀匹配缺陷,回归就红)
  • 0.145 vs 0.145.0 → 判一致
  • 版本号解析不出来 → 降级提示,不拿文本去比对
  • codex 没装 → 如实报告,不重复刷版本提示

scripts/ 不在 .github/ 下,我推得动,所以这个功能现在有了真实的运行时门禁,不需要你手工改 ci.yml

验证

python3 -m py_compile bin/lc scripts/smoke.py scripts/probe.pybash -nbash scripts/test-doctor-probe.sh 全绿(8 节共 25 项)。另外在真实仓库根目录下核了 _dockerfile_codex_version() 返回 0.145.0

CI:static + docker 均 SUCCESS(分支已 merge 了最新 main)。

按绿灯即合的约定合并,Closes #2

@github-actions
github-actions Bot merged commit e84a447 into main Aug 10, 2026
4 checks passed
@github-actions
github-actions Bot deleted the contrib/issue-2-codex-version branch August 10, 2026 06:07
LouisDM added a commit that referenced this pull request Aug 10, 2026
仓库的 fork-pr-contributor-approval 策略是 first_time_contributors,
github-actions[bot] 被归到这一类,于是它开的每个 PR,pull_request 触发的
CI 都挂在 action_required 等批准;而 GITHUB_TOKEN 批不了自己触发的 run,
agent 只能干等到 45 分钟超时。实测一轮 64 turns / 15 分钟,大半耗在这里。

换成 secrets.AGENT_PAT(细粒度,只对本仓库,且不授予 Workflows 权限——
保持 agent 改不了 ci.yml 这条护栏)。未配置时回退到 GITHUB_TOKEN,
工作流不会因此挂掉,只是会继续卡审批。

同时收紧合并规则。PR #9 暴露了原规则的漏洞:agent 看到「CI 全绿」就合了,
但版本比对逻辑在 ci.yml 里零断言覆盖 —— 绿灯只证明没破坏既有断言,
不等于新代码被验证过。现在要求它显式自问「有断言会因这个行为出错而变红吗」。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

lc doctor 应校验本机 Codex 版本与 Dockerfile 锁定版本是否一致

2 participants