fix(ci): Lychee 扫站点文档 content/docs,并加上每周 cron (#3449) - #3477
Merged
Conversation
…y cron (#3449) check-links.yml scanned `docs/**` (15 internal ADR/audit files) and README, but the site publishes `content/docs/**` (183 files, per apps/site/source.config.ts `dir: '../../content/docs'`). No published page had ever been link-checked; the workflow was green about a tree nobody reads. - args now sweep both trees: content/docs/**/*.{md,mdx} plus the existing docs/**/*.{md,mdx} and README.md (the internal tree's external links are worth sweeping and cost nothing). - schedule: weekly cron '17 4 * * 0'. #3213's PR withheld the cron on purpose — a schedule over the wrong tree only produces a false-green report on a timer. With the scope corrected, ruling B's periodic-sweep intent becomes real. push/pull_request stay commented out: #3213 ruling B stands. - lychee.toml: the scope fix alone would have shipped 316 hard errors. content/docs carries ~297 site-absolute links (/docs/...), which Lychee fails while CONSTRUCTING the URI — before `exclude` is consulted, so an `^/docs` exclude pattern cannot suppress them (measured). `root_dir` now resolves them into a sentinel namespace that the exclude list skips wholesale. Judging those routes stays scripts/check-doc-links.mjs's job. The old `remap = ["^/docs/(.*)$ file://./docs/$1"]` is removed: it had never fired (remap operates on a parsed URL; `/docs/x` fails to parse first) and pointed at the internal docs/ tree without an extension besides. - scripts/__tests__/check-links-workflow.test.ts derives the expected scope from apps/site/source.config.ts rather than hard-coding content/docs, and pins the root_dir/exclude pair, the schedule, and the absence of a PR trigger. - ci-cd-pipeline.md documented the gap as open (#3449) and the removed remap as live; docs-links.yml's comment said Lychee was dispatch-only on docs/. Both updated.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
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 #3449
前提复核(origin/main)
issue 的前提成立,三条都当场复核过:
args只扫docs/**+ READMEworkflow_dispatchlychee --dump-inputs实测:content/docs183、docs/15、README 1改了什么
1. 扫描范围:两棵树都扫(PM 裁决 ①)
args增加content/docs/**/*.md与content/docs/**/*.mdx,保留原有的docs/**与README.md。输入文件数 16 → 199。2. 每周 cron(PM 裁决 ②)
schedule: - cron: '17 4 * * 0'。避开整点(GitHub 的 schedule 队列在 :00 最挤、延迟最久),周日仓库最安静。workflow_dispatch保留;push / pull_request 继续注释掉 —— #3213 裁决 B 依然有效,注释块和理由一并留在文件里(理由原本没写,这次补上了)。3.
lychee.toml:这一步是必须的,不是顺手改的只改范围会得到一个从第一次运行起就全红的 workflow。实测(新 args + origin/main 的 lychee.toml):
content/docs里有 297 处站内绝对链接(/docs/...)。Lychee 在构造 URI 的阶段就把它们判成硬错误,这早于exclude过滤 —— 所以往exclude里加^/docs或^/实测完全无效(错误照报、退出码照样是 2)。处理方式:
root_dir先把站内绝对路由解析进一个磁盘上不存在的哨兵命名空间,再由exclude整段跳过。root_dir必须是绝对路径,而仓库在本地和 runner 上的绝对路径不同,所以它只能是一个与仓库无关的常量 —— 哨兵是被这条约束逼出来的。没有让 Lychee 去解析这些路由:fumadocs 路由没有扩展名(
/docs/guide/data-source→content/docs/guide/data-source.md),判它需要一份真正的 路由→文件 映射,而那份映射已经存在 ——scripts/check-doc-links.mjs。在lychee.toml里再抄一份,只是多一份会各自漂移的副本。顺带删掉了
remap = ["^/docs/(.*)$ file://./docs/$1"]:它从未生效过(remap 作用在已解析的 URL 上,而/docs/x在解析阶段就失败,压根走不到 remap),而且替换目标既少扩展名、指的又是内部的docs/而不是content/docs/。4. Pin 测试
scripts/__tests__/check-links-workflow.test.ts:范围不是硬编码content/docs,而是从apps/site/source.config.ts的dir读出来,再要求 workflow 覆盖该目录下每一个 md/mdx。硬编码等于把站点布局又抄一份 —— 这个 bug 本来就是这么来的。content 再搬家一次,测试当天变红。同时钉住root_dir/exclude这一对(拆掉任何一半都会重新弄坏)、schedule存在、以及pull_request/push不存在。5. 文档
content/docs/guide/ci-cd-pipeline.md原本把这件事写成"已知缺口,追踪在 #3449",还把已删除的 remap 写成现行配置;docs-links.yml的注释说 Lychee "dispatch-only 且扫 docs/"。都已更新。验证
本地下载了真的 lychee 0.24.2 跑的,不是纸面推演。
范围(
--dump-inputs,精确计数)反向验证 —— 方向是先预测再跑的,四条都按预测变红
× scans every markdown file the site is built fromlychee.toml× resolves site-absolute routes …× carries no remap …schedule× runs on a schedule as well as on demandpull_request× does not gate pull requests全部恢复后
Tests 7 passed (7)。测试 / 门禁
scripts/不在任何 tsconfig 的include里(root tsconfig 只含packages/examples/apps),所以仓库的type-check本来就不覆盖它 —— 上面那条 tsc 是我单独跑的,如实说明。修好范围后离线跑一遍,还剩 37 个错误,全部是仓库内相对文件链接失效,与外链无关:
plugins/plugin-*.md但文件其实叫.mdx;另有concepts/lazy-loading、guide/lazy-loading.md、guide/examples/server三个目标根本不存在。examples/crm、examples/todo、examples/kitchen-sink、examples/msw-todo—— 这四个 example 应用在仓库里不存在。这些是既有的内容缺陷,不是本 PR 引入的,按 Prime Directive #10 另开 issue、不夹带进这个 PR 修。顺带暴露出一个门禁洞:
scripts/check-doc-links.mjs只校验/docs/...开头的 href,相对链接一律直接 return true —— 所以这 16 个失效链接一直没人管。同样另开 issue。我特意没有加
--fallback-extensions md,mdx:它能把错误从 33 降到 6,但降下去的那 13 个正是.md写成.mdx的真缺陷(fumadocs 路由无扩展名,.md后缀在站点上就是 404),等于用宽容的消费端把生产端的错误盖住。宁可报得难看,也不要报得好看但不真。Generated by Claude Code