用途
本技能定义了成批重新接受多个 golden 基线(golden rebaseline)的唯一合规流程。适用场景包括渲染器、字体、设计令牌或 Jest 升级后,或进行有意的重新设计后。它不适用于单个 golden 随改动一起移动的情况(那属于 golden-and-snapshot-tests 的单文件流程),也绝不用于 [contract] 约定条目或容差调整。
核心规则
- 必须先命名原因并进行完整 triage:执行
--start --reason "<cause>"后,先在禁用 -u 的情况下运行整个 golden 项目;每个失败都必须符合该原因所预期的情况。两个不相关的原因就属于两次 rebaseline。 - 真实断言必须先通过:在第一次更新之前,除 golden 项目外的每个 Jest 项目都必须完整且通过。
- rebaseline 开始后,除 golden 外不得有任何改动:代码、测试、配置、锁文件和冻结的 golden 路径都需要保持
--start记录的哈希;node_modules 必须与 package-lock.json 一致。 - 每次 -u 只更新一个文件:命令形如
jest <file> --selectProjects golden --ci -u,其中路径必须放在前面,并通过--listTests预览。禁止在 package.json 脚本、git 钩子、agent 钩子或 CI 中使用 -u。 - 只更新 triage 显示失败或含过期条目的文件。
- golden 只能通过有记录的更新运行来变更:不得手工编辑 .snap* 或 PNG,只有孤儿可以手工删除;Jest 大版本升级后仅重写头部是唯一例外。
- 每个变更的 golden 都必须检查并记录:逐行阅读 .snap diff,逐一打开 triage diff 合成图和每个新 PNG,并在 inspection.json 中为每个变更路径写入 verdict(intended 或 orphan)以及至少 15 个字符的说明。
- [contract] 条目永不重新接受:若 [contract] 断言失败,必须停止并询问评审者;运行器和检查器会拒绝或比对这类条目。
- 容差不属于本流程范围:像素匹配器与 contracts/goldens.json 必须逐字节保持原样,容差提升需要评审者单独提交。
- 孤儿须手工删除:在提交证明之前,于同一变更中删除,且整个流程中不得设置 JEST_IMAGE_SNAPSHOT_TRACK_OBSOLETE。
- 在禁用 -u 的情况下证明两次:使用
--ci,不写文件,没有过期条目,每个 golden 测试都运行过,且之后没有 golden 再变更(记录在 proof-goldens.json)。 - 两次暂停询问:在第一次更新前展示计划并等待批准;在提交前展示记录(含 PNG)并等待批准。提交只包含原因与 golden,命名每个重新接受的测试和删除的孤儿,并以
Gate-Change:结尾。
使用方式(工作流)
- 判断是否属于 rebaseline,阅读 references/rebaseline-ritual.md 中的判定说明。
- 准备:原因已在工作树中定稿,无关工作已提交或暂存,golden 已提交,执行 npm ci,且 JEST_IMAGE_SNAPSHOT_TRACK_OBSOLETE 未设置。
- 启动:
node ${CLAUDE_SKILL_DIR}/scripts/rebaseline.mjs . --start --reason "<cause>"(可先加 --dry-run)。 - 断言:
node ${CLAUDE_SKILL_DIR}/scripts/rebaseline.mjs . --assertions --max-workers 2;若失败则停止,修复后用--start --restart重来。 - Triage:
node ${CLAUDE_SKILL_DIR}/scripts/rebaseline.mjs . --triage,阅读每个失败,并打开 reports/rebaseline/triage-diffs/ 下的每张合成图。 - 在第一次更新前停下来询问开发者,展示计划(examples/approval-requests.md 第 1 部分)。
- 逐个更新:
node ${CLAUDE_SKILL_DIR}/scripts/rebaseline.mjs . --update <file>。 - 检查并记录:逐行查看 git diff,打开新 PNG,填写 reports/rebaseline/inspection.json。
- 删除孤儿:用 git rm 删除测试已不存在的快照和无人引用的 PNG,记录为 orphan。
- 证明:
node ${CLAUDE_SKILL_DIR}/scripts/rebaseline.mjs . --proof(运行两次)。 - 检查:
node ${CLAUDE_SKILL_DIR}/scripts/check-rebaseline.mjs .,修复每条 FAIL 直至出现 RESULT: PASS。 - 提交前停下来询问开发者,展示记录与 PNG。
- 提交:编写 reports/rebaseline/commit-message.txt,运行
node ${CLAUDE_SKILL_DIR}/scripts/check-rebaseline.mjs . --message reports/rebaseline/commit-message.txt,再执行git commit -F reports/rebaseline/commit-message.txt,最后删除 reports/rebaseline/。
完成标准
原因已记录在 before.json 中,且每个重新接受的 golden 都能由该原因解释;开发者在首次更新前和提交前均已批准;没有 [contract] 条目、像素匹配器或 contracts/goldens.json 发生变更,也没有容差被移动;每个变更的 golden 都有 intended 或 orphan 记录及真实说明,孤儿已删除;一个提交承载原因与 golden,列出全部重新接受文件,并以 Gate-Change: 结尾;运行 check-rebaseline.mjs . --message 输出 RESULT: PASS。
反模式(禁止)
- 用 npx jest -u 让失败的测试套件变绿。
- 使用
npx jest --selectProjects golden <file> -u(路径会被当成项目名,导致重写全部 golden)。 - 按 Jest 提示运行
npm test -- -u更新整个项目。 - 在 rebaseline 过程中修复 bug 后继续,从而把修复藏进重新接受的输出里。
- 只“暂时”重新接受部分失败。
- 只看 diffstat,不逐张查看 diff 和图片。
- 因升级噪声而提高 failureThreshold。
- 在 CI 或钩子中运行本流程。
- 提交证据文件或 diff 图片(reports/ 已被 git 忽略)。
文件组成
- references/rebaseline-ritual.md:何时 rebaseline、准备、每一步及原因、diff 解读、triage 表、两次暂停、提交、Jest 大版本、重命名测试、Skia 升级、截图基线等。
- references/jest-facts.md:经核验的 Jest 29.7 / jest-expo 57 / jest-image-snapshot 6.5.2 行为。
- references/evidence-and-checker.md:证据目录、格式、运行器模式与拒绝条件、检查器规则、配置、预期输出与排错。
- examples/:inspection.json、approval-requests.md、rebaseline-commit.txt 示例。
- scripts/rebaseline.mjs:分步执行(--start、--assertions、--triage、--update、--proof)并写入证据。
- scripts/check-rebaseline.mjs:依据证据与工作树校验 13 条规则,支持 --message。
- scripts/lib/rebaseline-lib.mjs、scripts/selftest.mjs、scripts/check-lib.mjs 及 tests/bases/、tests/fixtures/。
限制
资料未提供该技能的安装命令或兼容平台清单,具体以来源页面为准;运行依赖 Node 脚本环境及 Jest 项目配置。CI 中只应运行 jest --ci 进行证明,不执行本流程。