Skip to content

finding(bump-objectui): pin 范围跨过 objectui 的 release commit 时,digest 会先刷一屏 fatal: 再报成功 —— 一个完整的结果长得像一次失败 #6175

Description

@hotlong

#6159 的 pin bump(PR #6173)执行时观察到,产物完全正确,属 observation-class,按 Prime Directive #10 记录。

现象

scripts/bump-objectui.sh 在本次范围(f995a452..7dfbeb70)上的真实输出:

→ objectui pin: f995a452d2ca → 7dfbeb704e1e
fatal: path '.changeset/bulk-action-capability-gate.md' does not exist in '7dfbeb704e1eace5dc5eae1d6168c4ded805a32b'
fatal: path '.changeset/lookup-fields-in-predicates.md' does not exist in '7dfbeb704e1eace5dc5eae1d6168c4ded805a32b'
fatal: path '.changeset/predicate-eval-failures-warn-once.md' exists on disk, but not in '7dfbeb704e1eace5dc5eae1d6168c4ded805a32b'
... 共 9 行 ...
→ 9 releasing changeset(s), 0 breaking, 0 release-nothing, 20 commit(s) without a changeset
→ wrote changeset console-7dfbeb704e1e.md (@objectstack/console: patch)

九行 fatal:,然后成功。产物是对的 —— 9 条 releasing changeset 一条不少地进了 console changeset 正文,级别、范围、计数全部核对无误。

来源

scripts/objectui-changeset-digest.mjsreadAt():

function readAt(objectuiRoot, to, sha, path) {
  try {
    return git(objectuiRoot, ['show', `${to}:${path}`]);
  } catch {
    return git(objectuiRoot, ['show', `${sha}:${path}`]);
  }
}

第一次 git show 的失败被 catch 正确接住并回落到「添加它的那个 commit」,但 git 的诊断已经写进了继承来的 stderr,catch 拦不住。

触发条件是 to 端点是一个 release commit:本次目标 7dfbeb7 是 objectui 自己的 chore: release packages (#3248),它消费并删除了当时挂着的全部 88 个 changeset,于是范围内新增的 9 个在 to 处一个都不存在,回落路径逐个触发。这是本仓第一次让 pin 落在 objectui 的 release commit 上。

为什么值得记一笔,尽管它只是噪声

本仓在这个脚本上反复写下的原则是「a degraded list and a complete one must never look alike」(#4731,bump-objectui.sh 的注释与降级分支)。这里发生的是它的镜像:一个完整的列表长得像一次失败。对下一个执行 pin bump 的人(或 agent),九行 fatal: 的第一反应是「digest 挂了、要不要改用 --no-changeset 手写」,而正确的反应是「忽略它,产物是全的」。判断成本落在读者身上,而读者恰恰是最没有上下文的那个人。

而且它会复现:objectui 现在会定期跑 release,今后每一次跨过 release commit 的 pin bump 都会打这一屏。

备选修法(成本都很小,留给 triage 定)

  • A. 先探测再读:git cat-file -e ${to}:${path} 判断存在性,不存在就直接读 ${sha}:${path},不产生 fatal:。语义不变。
  • B. 静默第一次尝试:给 readAt 的第一次 git() 调用加 stdio: ['ignore', 'pipe', 'ignore'],只在两次都失败时才把诊断放出来。改动最小。
  • C. 把回落说成一句话:吞掉 git 的 stderr,改为在 digest 的 accounting 行旁边打一句「N 个 changeset 已被范围内的 release commit 消费,已从添加它们的 commit 读取」。信息量最大,也最贴合本仓「absence/degradation must be loud, but must be READABLE」的调子。

倾向 B + C:B 消掉误导,C 把「发生了回落」这件事从噪声变成一句可读的事实 —— 直接做 A 会把回落变得完全无声,而这件事本身是值得说一句的。

明确不在范围内

产物无误,#6159 / PR #6173 不受影响,也不需要因此重跑或改动 pin。这条纯粹是工具可读性。

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions