Skip to content

CONTRIBUTING.md 的 Documentation 一节有两处与仓库现状不符:门禁描述指错工具/触发条件,"✅ 正确链接示例" 里 3 条路由是死的 #3570

Description

@yinlianghui

#3545(PR 见该单)时在同一节的相邻散文里读到的,按 Prime Directive #10 未在那个 PR 里改(越界),另立本单。两处都不是死链(#3545 的那一类),所以 #3545 的修复不覆盖它们。

1. CONTRIBUTING.md:467 — 门禁描述把工具和触发条件都说反了

现文:

Link validation runs automatically via GitHub Actions on all PRs using lychee-action. This checks for broken internal and external links.

与现状对不上:

  • .github/workflows/check-links.yml(lychee)的触发器只有 workflow_dispatch + 每周 cron 17 4 * * 0,不在 PR 上跑。该文件自己的头注释还明确写了 "⛔ Do NOT enable the two triggers below — pnpm docs:check-links 在 main 上就退出 1,但没有任何工作流跑它(两个链接检查器都不拦 PR) #3213's ruling B still stands",即 PR 触发是被有意排除的;
  • 真正 gate PR 的是 scripts/check-doc-links.mjs,由 .github/workflows/docs-links.ymlpull_request: [main, develop] 上跑。check-links.yml 的头注释也是这么写的:"Site-internal routes (/docs/...) are a different problem with a different tool — scripts/check-doc-links.mjs, run by docs-links.yml, which ... is therefore the one that gates pull requests."

也就是说这一句把周扫的外链检查说成了PR 门禁,又把真正的 PR 门禁完全略去了。贡献者据此会以为外链坏了会拦住自己的 PR(不会),也不知道 pnpm docs:check-links 才是本地要跑的那个。

2. CONTRIBUTING.md:441-445 — 标着 "✅ Correct Link Patterns" 的示例里有 3 条路由不存在

那个代码块里 5 条示例,用仓库自己的判定器(scripts/check-doc-links.mjsrouteExists() + collectSiteRoutes())跑一遍:

OK   /docs/guide/quick-start
OK   /docs/components
DEAD /docs/reference/api/core
DEAD /docs/reference/protocol/overview
DEAD /docs/architecture/component

content/docs/ 下没有 reference/、也没有 architecture/ 目录(实有:api、blocks、components、core、fields、guide、layout、plugins、rfcs、utilities)。更尴尬的是紧接着的 "❌ Incorrect Link Patterns" 块里,把 /spec/component 的"正确写法"注成 /docs/architecture/component、把 /api/core 注成 /docs/reference/api/core —— 教的是同样不存在的路由。

为什么门禁抓不到: 这些示例在 ```markdown 围栏里,而 check-doc-links.mjs 在扫描前会 `stripCode()` 掉围栏块(这是必需的,见该文件 "Code spans are stripped before scanning" 一节)。所以即便第 2 步把 `CONTRIBUTING.md` 纳入 `SCAN_ROOTS`(#3545 提的),这 3 条也仍然扫不到 —— 它们落在围栏这个结构性盲区里。这一点值得记一笔:文档里"举例说明正确写法"的链接天然免疫链接门禁,而它们恰恰是最容易被照抄的。

复现(只读,离线)

node -e '
import("./scripts/check-doc-links.mjs").then(async (m) => {
  const path = await import("node:path");
  const site = m.collectSiteRoutes(path.join(process.cwd(), "apps", "site"));
  const ctx = { fromFile: path.join(process.cwd(), "CONTRIBUTING.md"), docsRoot: path.join(process.cwd(), "content", "docs"), site };
  for (const h of ["/docs/guide/quick-start","/docs/components","/docs/reference/api/core","/docs/reference/protocol/overview","/docs/architecture/component"])
    console.log(m.routeExists(h, ctx) ? "OK  " : "DEAD", h);
});'

建议

  1. 第 1 处:把这句改成如实描述 —— PR 上跑的是 docs/check-doc-links(docs-links.yml),lychee 是周扫的外链检查、不 gate PR;顺带给出本地命令 pnpm docs:check-links
  2. 第 2 处:把 3 条死路由换成真实存在的等价页面,或直接换成两条已验证 OK 的示例。改之前建议先确认 /docs/reference/*/docs/architecture/*曾经存在后来搬走还是从来就是虚构的 —— 如果是前者,别处可能还有同样的引用。

关联

#3545(同一节相邻的 3 条死链,已修)、#3536 / PR #3542(扫描面扩展)、#3213(lychee 不 gate PR 的裁定)、#3543(另一份文档的过期陈述,不同文件)。

⚠️ 本单未认领,留给 PM 分诊。

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdocumentationImprovements or additions to documentationpm:dispatched

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions