feat(scripts): digest 把「无 changeset 的 commit」从计数升级为按 subject 逐条点名 (#6174) - #6358
Merged
Merged
Conversation
) console changeset 正文此前只把漏声明 changeset 的 commit 写成一个数字 (`omitted: N commits carrying no changeset`),具体是哪些 commit,发布记录 里读不出来。实测 pin bump 区间 `f995a452d2ca..7dfbeb704e1e`(#6159 / PR #6173)的 20 条里,19 条是 release commit / dependabot / docs·ci·scripts, 另有 1 条是 objectui#3518 `0e50440e8 fix(form): bind previous for field rules…` —— 26 个文件、5 个包、全部十个 locale pack 的用户可见表单行为变更。 在数字 20 里,它和 `Bump postcss` 无从分辨。 改动只在呈现层:把 `classifyRange` 已经产出的 `noChangesetCommits` 原样 渲染进正文,行格式沿用 `objectui-range.mjs --all` 的 `- _(no changeset)_ …` 词汇,使两个产物读起来是同一套。判据、收录集、分类、accounting 行一律未动 (实测两个真实区间的 diff 为纯插入,零删除)。 规模护栏:点名清单与 releasing 清单各自独立套用 `max`(默认 100),截断时 输出真实总数与取全量的命令,绝不静默截断(#4731)。零条时不打新行。 与 #6175 的 stderr 回落句是相邻但不同的事实——那句讲工具怎么读文件,这段 讲哪些 commit 进了 build 却没声明,故落点在正文。 self-test 新增 12 条独立成组的断言(45 → 57);#4731 一条既有断言的实现 方式(整体 body 子串)已不再表达其原意,改为在 releasing 集合与渲染行两层 断言,原意与精确计数均不变。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BDmDsu2575gDxeMCxXhDE3
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
hotlong
marked this pull request as ready for review
August 7, 2026 15:35
This was referenced Aug 7, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #6174
本 PR 只做分诊 07:51Z 钉死的选项 C:把 console changeset 正文里「无 changeset 的 commit」从一个计数升级为按 subject 逐条点名。
1. 前提复核(对
origin/maina5ca08d,#6289 / #6335 两棒落地之后)三条内容读数逐条复核,全部仍成立:
objectui-range.mjs的点名能力const SHOW_EXCLUDED = has('--all'),渲染- _(no changeset)_ …行,self-test 有`--all` itemizes the excluded commits by subjectobjectui-changeset-digest.mjs只计数不点名omitted: 20 commits carrying no changeset (they ship no package code).,再无别的痕迹classifyRange已产出所需数据noChangesetCommits({ sha, subject }数组),objectui-range.mjs正是从这里取数同文件前序两棒均已在 main 且未被本 PR 触碰:#6289(
hasBreakingAnnotation,破坏性判据扩到作者正文标注)、#6335(readAt回落静默,那句回落事实在 stderr)。为什么这不是「已经有了」:
--all的点名只存在于objectui-range.mjs产出的发布页 Console 段;写进平台发布记录的 console changeset 正文由buildDigest生成,它从未消费noChangesetCommits。两个产物,一个有名字一个只有数字。2. 这次漏掉的到底是什么(实测,不是推断)
区间
f995a452d2ca..7dfbeb704e1e(#6159 / PR #6173)的 20 条无 changeset commit,按内容归类:chore: release packages (#3248))0e50440e8 fix(form): bindpreviousfor field rules and stop resubmitting read-only fields (#3518)—— 26 个文件、5 个包、全部十个 locale pack,真实用户可见的表单行为变更在数字
20里,这一条和chore(deps-dev): Bump postcss from 8.5.25 to 8.5.26完全无从分辨。这就是「计数不可读、subject 可读」的全部理由。3. 设计决定与理由
(a) 落点 = changeset 正文,不是 stderr。 #6175 刚把回落事实放在 stderr 的 accounting 行旁边,理由是「工具怎么读到文件」不是关于这次发布的事实。本段是相邻但不同的事实:「哪些 commit 的代码进了 console build 却没有任何上游声明」恰恰是发布记录该有的内容,读者是读发布记录的人而不是看这次运行的操作员。故落正文。self-test 里有一条断言专门钉这条边界(见 §5)。
(b) 措辞。 正文段首为:
三点是刻意的:代码确实进了 build(不是「丢了」);没有任何上游声明,所以 objectui 自己的 CHANGELOG 里也没有;指向 objectui#3387 让读者知道根因闸门在哪。
(c) 行格式沿用
objectui-range.mjs --all的- _(no changeset)_ …词汇。 同一件事在两个产物里用同一套词汇,读者不必学两遍;这也正是「接进已有能力」而不是「另造一套」的含义。(d) 不分类、不筛选。
chore: release packages和那条 form fix 一起平铺列出。判断哪条「重要」等于对 subject 做推断 —— 正是 #4731 拆掉的那一步,而且会以同样方式失败:值得点名的那条挂着fix(form),和旁边的fix(ci)一样不特别。工具只负责停止隐藏,判断交给读者。(e) 规模护栏:点名清单与 releasing 清单各自独立套用同一个
max(默认 100)。 两个真实区间是 20 条和 33 条,默认下都完整列出、不触发截断。截断只作为病态区间的兜底存在,且必须响亮 —— 下面是 self-test 里max: 2/ 总数 3 时的实测输出:带真实总数,并给出取全量的命令。选独立配额而非共享配额的理由:共享时第二个清单的长度取决于第一个清单有多长,而读者无从推断这层耦合 —— 一次长发布就能把点名段挤成零条,那正好是本 PR 要消灭的形态。
(f) 零条不打。 无漏声明 commit 时不产生任何新行。这里的静默是安全的:计数非零时 accounting 行同时也在说这件事,本段从不是该事实的唯一载体,所以「没有这一段」只可能是「本区间每条 commit 都声明了」,不可能是「这段没实现」。
(g) ⛔ 不改判据。
noChangesetCommits原样渲染,不过滤、不重排、不新增谓词。判据、收录集、分类、计数、accounting 行一律未动 —— §4 的逐字节 diff 是证据。4. 真实区间重放 before / after
改前改后各跑一次,两个区间:
f995a452d2ca..7dfbeb704e1e(#6159 实测)f5bc4c78be76..f995a452d2ca(对照)diff -u0对区间 A 只有一个 hunk 头@@ -18,0 +19,23 @@—— 纯插入,accounting 行与 9 条 releasing 清单逐字节不变,objectui range:页脚仍在末尾。区间 B 同形(@@ -75,0 +76,36 @@,被删除行计数为 0)。两个区间的 stderr 逐字节相同(diff无输出),即 #6175 的回落句与 accounting 行都未受影响。新增段实测节选(区间 A):
issue 正文点名的那条,现在在平台发布记录里有名字了。
5. 反向验证:申报在先,实测在后
变异体:把点名段的生成条件短路(
if (false && noChangesetCommits.length > 0)),即删空功能、其余不动。事先申报:10 条转红(肯定式)、3 条保持绿(结构上不会红,已分别说明理由)。
实测结果:
10 failure(s),与申报逐条一致。转红的 10 条(肯定式,真覆盖):
rows=0 noChangeset=3indexOf为 -1,顺序断言失败the range has 3 in total)失败保持绿的 3 条 —— 申报为结构上不会红,不得当作覆盖度:
allDeclared.noChangeset === 0与releasing.length === 2,确保 fixture 确实是零漏声明的场景、且确实产出了 digest —— 没有它们,「无新增行」也会被空区间或根本没构建出 body 的情况满足。护栏防的是 fixture 退化,不能让这条在变异体下转红,故如实申报为否定式。空绿自查(逐条过了一遍新增断言的每个子句):发现两条断言各含一个在变异体下平凡为真的否定子句 ——
!named2.body.includes(SUBJECT_3518)与!digest.body.includes('- _(no changeset)_ fix(ci): hand the cross-repo token')。两条都已经各自配了肯定式子句(includes('the range has 3 in total');filter(...).length === 1)承载判定,实测也确实随变异转红,故不是空绿;此处如实记录,是因为若单独保留那个否定子句就会是空绿。除此之外未发现同类。#4731 一条既有断言的实现方式必须修复(不是改判据、不是改计数):
原断言
afix(ci)commit with no changeset at all is NOT represented用!digest.body.includes('budget FAIL')实现。它的原意始终是「判据没有把它收进 releasing」,而实现方式是「整段 body 里找不到这个 subject」—— 当 body 开始有意点名无 changeset commit 之后,这个代理就不再表达原意了。改为在两层直接断言原意:!digest.releasing.some(...)(分类集合)+ 渲染行不匹配 releasing 行的形状(渲染层)。fixture 与其精确计数一字未动;另在 #6174 组补了正向的另一半:它现在确实出现在点名段里。一并核对:
cross-repo token那条是 release-nothing(空 frontmatter,作者确实声明了),不属无 changeset 类,因此不会被点名 —— 依赖它的两条既有断言(#4731 组与端到端组)实测均未受影响。6. 门禁(均在
git add之后跑)pnpm check:objectui-changeset(digest 57 条 + objectui-range 自测)pnpm exec eslint scripts/objectui-changeset-digest.mjs --no-inline-configpnpm check:nul-bytes(自测 56 断言 + 扫描 6003 文件)grep -naP控制字节类)node scripts/check-objectui-pin-fresh.mjs --self-test(下游消费者,Console Pin Freshness)digest self-test 45 → 57(新增 12 条,独立成 #6174 组)。下游
check-objectui-pin-fresh.mjs只消费classifyRange,而classifyRange本 PR 一行未改。7. 不在本 PR 里
packages/*/src/**改动必须带 changeset 的闸门)—— 归 objectui#3387(该仓pm:queue,2026-08-05 转过去)。⛔ 本仓不开第二个入口,本 PR 不跨仓改 objectui。.objectui-sha未触碰。scripts/objectui-range.mjs、scripts/bump-objectui.sh、scripts/check-objectui-pin-fresh.mjs均未触碰。本 PR 不发布任何包(纯
scripts/工具链),故走skip-changeset路线,不建.changeset/文件。Generated by Claude Code