fix(docs): 构建前把 static/img 拷进 rspress 的 public 根,修 docs-deploy 连红 - #1334
Conversation
`docs-deploy` 自 #1194 起 8 次 run 全部失败,零成功。报错是 rspress 的 `Dead image found`:文档里 `` 会让 rspress 去 `docs-site/docs/public/img/` 找(`rspress.config.ts` 是 `root: 'docs'`), 而截图实际提交在 `docs-site/static/img/`,没有任何步骤把它们拷过去。 `markdown.link.checkDeadLinks` 开着,于是一张缺图就让整个站构建失败。 `docs/public` 本来就是「构建前生成」的目录(已在 .gitignore 里,`prebuild` 的 prepare-assets.mjs 会往里拷 logo),只是这个脚本只管了 logo。改成整个 `static/img/` 目录一起拷,以后加截图不用再动这个脚本——现存 4 张死图 (sessions-command-card、quota-fallback-dashboard、 quota-fallback-cycle-recovery-dashboard、streaming-card-button-settings, 分别由 #1194 / #1283 / #1323 引入)一并修好。 `static/img` 仍是唯一事实来源;生成出来的 `docs/public/img/` 加进 .gitignore, 避免同一批图在仓库里存两份。目录不存在时按 ENOENT 跳过而不是让 prebuild 崩掉: 没有截图的构建是合法的,该由 rspress 的 checkDeadLinks 去管「文档引用了但缺图」。 验证(本地无法跑 rspress:worktree 内不装依赖): - `node scripts/prepare-assets.mjs` rc=0,5 张图拷进 docs/public/img/,与源逐字节相同 - 文档里 4 个 `/img/` 引用全部解析到实际文件(unresolved=0) - 删掉 static/img 重跑 rc=0(不再 ENOENT 崩),恢复后仍拷齐 5 张 - 生成目录已被 .gitignore 忽略(`git check-ignore` 命中) 真正的绿要靠 CI 跑一次 docs-deploy 确认。 Co-Authored-By: Claude Code <noreply@anthropic.com>
补充:已在干净 checkout 上做完真实 A/B,不再是「本地无法验证」PR 描述里我写了「本地跑不了 rspress、真绿要靠 CI」。现在补上了真实构建验证 —— 做法是把 决定性 A/B(两棵同样干净的 master 树,唯一差异是这一个文件)
对照组报错的 4 个文件与 CI 上逐字一致: 不只是「不报错」,图真的进了产物
一个自我更正我最初跑的那组对照是哑弹:在同一个目录里先跑了带修复的构建、再把脚本换回 master 版重跑,结果照样绿( ⟹ 教训:验「去掉修复会不会转红」必须用未被前一次构建污染的树,同目录里前后跑两次是不够的。 环境差异(如实说明)本地 pnpm 是 9.15.9,CI 用
|
|
🚀 Released in v3.21.0 |
问题
docs-deployworkflow 连红 8 次、零成功,最早追到97233b1f2(#1194,2026-09-07 03:02),最新690e9967b(#1283)。因为它不在 ruleset 必需 check 里、且被paths: [docs-site/**]门控,所以从未挡过任何人合码,红着一直没人注意。根因
不是「图没提交」,是目录约定对不上。
rspress 报
Dead image found。文档里写,而rspress.config.ts是root: 'docs'⟹ rspress 的 public 根是docs-site/docs/public/,它就去那儿找(报错信息把期望路径逐字打出来了)。但截图实际提交在docs-site/static/img/,没有任何步骤把它们拷过去。而markdown.link.checkDeadLinks是开着的 ⟹ 一张缺图让整个站构建失败。docs/public本来就是「构建前生成」的目录——它已在docs-site/.gitignore里,prebuild钩子的scripts/prepare-assets.mjs会往里拷 logo。只是这个脚本只管了 logo。现存 4 张死图,由三个 PR 陆续引入:
sessions-command-card.png{zh,en}/slash-commands.mdquota-fallback-dashboard.png{zh,en}/bots-json.mdquota-fallback-cycle-recovery-dashboard.png{zh,en}/bots-json.mdstreaming-card-button-settings.pngzh/bots-json.md三个 PR 各自踩同一个坑 ⟹ 说明该结构性修掉,而不是逐张挪文件。
改法
prepare-assets.mjs改成把整个static/img/目录拷进docs/public/img/,以后加截图不用再动这个脚本。两个边界处理:
static/img是唯一事实来源;生成出来的docs/public/img/加进.gitignore,避免同一批图在仓库里存两份(与既有的docs/public/botmux-logo.png那行同一套路)ENOENT跳过、不让 prebuild 崩:没有截图的构建是合法的,「文档引用了但缺图」该由 rspress 的checkDeadLinks去管。(这一条是探针逼出来的:第一版会在static/img缺失时 ENOENT 退出 1,等于给构建加了一个它原本没有的失败模式。)影响面
只动 docs 站构建的前置脚本与其
.gitignore,不碰任何产品代码——与 daemon / worker / CLI 适配器 / 会话后端 / 飞书链路无关,不影响ci.yml的build与test。对妙搭发布链路无影响:
deploy.sh推的是doc_build/static(构建产物),与本 PR 动的源目录docs-site/static/img是两回事,同名但不相干。验证
docs-site/node_modules,而 CLAUDE.md 铁律是 worktree 内绝不跑 install。所以下面是脚本级 + 引用解析级验证,真正的绿要靠 CI 跑一次docs-deploy确认。node scripts/prepare-assets.mjsdocs/public/img//img/引用static/img重跑git check-ignore命中docs-site/.gitignore:5后续(本 PR 不做)
修绿之后可以考虑把
deploy加进 ruleset 必需 check,否则它以后照样会静默红着。但必须先修绿再加——否则会把所有产不出该 check 的在途 PR 卡死(#1288 刚踩过一次)。🤖 Generated with Claude Code