Skip to content

check-i18n-en-drift 的显式 --base / OS_I18N_DRIFT_BASE 解析不出时会静默跌落到别的提交,拿错基准比对并报绿 #3766

Description

@yinlianghui

现象

scripts/check-i18n-en-drift.mjsresolveBaseRef()显式指定的基准仅当作候选链的第一环:

const candidates = [
  explicit ? () => attempt(`--base ${explicit}`, () => gitQuiet(root, ['rev-parse', '--verify', `${explicit}^{commit}`])) : null,
  env.OS_I18N_DRIFT_BASE ? ... : null,
  env.GITHUB_BASE_REF ? () => attempt(`merge-base with origin/${env.GITHUB_BASE_REF}`, ...) : null,
  () => attempt('merge-base with origin/main', ...),
  () => attempt('merge-base with main', ...),
].filter(Boolean);

for (const candidate of candidates) {
  const hit = candidate();
  if (hit) return hit;      // 第一环失败 -> 继续往下猜
}

于是 --base 某个本地 clone 里不存在的 sha(浅 clone、未 fetch 的 sha、拼错的 sha)不会失败,而是继续尝试 merge-base with main 之类的候选,拿另一个提交当基准把比对做完,并打印一行自信的绿灯 —— 输出里的 (--base …) 也被换成了实际用的那一环,读日志的人看不出自己指的基准被忽略了。

「你指的 base 不存在」和「你没指 base」是两件不同的事,只有后者可以靠猜回答。

实测

同族缺陷在新门禁 scripts/check-changeset-presence.mjs 上被它自己的测试抓到(PR #3762 / #3387),那里 base 解析链是照本文件抄的。修好前后在真实仓库上的测量:

# 缺陷版(= 本文件当前形状)
$ node scripts/check-changeset-presence.mjs --base 0123456789abcdef0123456789abcdef01234567
Compared the working tree with b1204af0a (merge-base with origin/main): 7 file(s) changed, 0 ...
✅  No source of a released package changed in this range, so no changeset is owed.
exit=0                       # 请求的 sha 被无声换掉,报绿

# 修好后
$ node scripts/check-changeset-presence.mjs --base 0123456789abcdef0123456789abcdef01234567
❌  Cannot resolve the commit to compare against, so there is nothing to diff.
    tried: --base 0123456789abcdef0123456789abcdef01234567 (unresolved)
    That base was named EXPLICITLY, so it is not guessed around: ...
exit=1

本 issue 只针对 check-i18n-en-drift.mjs —— 该文件自身没有修(PR #3762 的范围是 changeset 门禁,越界即停)。

影响面

CI 里 pnpm check:i18n-drift 不传 --base,走的是 GITHUB_BASE_REF 那一环,所以今天的 CI 路径不受影响;受影响的是该脚本对外声明支持的两个显式入口(--baseOS_I18N_DRIFT_BASE),它们正是复现历史提交、跨 worktree 比对、以及该门禁自身测试所用的入口。严重度请分诊评定 —— 提单时的自评在两个方向上都不可靠(objectstack#1004 / #897 的教训)。

建议修法

把显式来源提为权威:给出即只查它,解析不出直接 { ok: false, named: true } 并给一条针对性的提示("你指的 base 在这个 clone 里不存在",而不是"去 fetch base 分支")。scripts/check-changeset-presence.mjsresolveBaseRef 已经是这个形状,可以直接照抄,连同 scripts/__tests__/check-changeset-presence.test.ts 里那条钉住它的用例(用例注释记录了反向验证的方向:恢复跌落写法后 exit 0→1)。

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions