From 234cec5d1ccf6ad7503ff074f7403e79454c382a Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 7 Aug 2026 14:40:51 +0000 Subject: [PATCH] =?UTF-8?q?docs(contributing):=20=E6=8C=89=E7=8E=B0?= =?UTF-8?q?=E7=8A=B6=E6=94=B9=E5=86=99=E9=93=BE=E6=8E=A5=E9=97=A8=E7=A6=81?= =?UTF-8?q?=E5=88=86=E5=B7=A5,=E6=8D=A2=E6=8E=89=E4=B8=89=E6=9D=A1?= =?UTF-8?q?=E6=AD=BB=E7=9A=84"=E6=AD=A3=E7=A1=AE=E7=A4=BA=E4=BE=8B"?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=20(#3570)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Documentation 一节两处与仓库现状不符: 1. "Validating Links" 把周扫的外链检查说成了 PR 门禁,又完全略去真正的 门禁。改写为如实的分工:PR 门禁是 check-doc-links.mjs(docs-links.yml, pull_request → main/develop,离线读 checkout,无 paths 过滤所以纯文档 PR 也被检查),lychee(check-links.yml)只挂周 cron + workflow_dispatch, 从不上 PR —— #3213 的有意取舍。按机制描述、不枚举扫描面,免得 #3572 合并后又过期。 2. "✅ Correct Link Patterns" 里三条路由被 routeExists() 判死 (/docs/reference/api/core、/docs/reference/protocol/overview、 /docs/architecture/component),换成逐条验证过的真实路由。紧邻的 "❌ Incorrect" 块原先把"正确写法"注成同样不存在的路由,一并改正 —— 不改它,新的 ✅ 块会和它自相矛盾。那三条死路由现在改作反面例子: /reference/、/architecture/、/spec/ 这三个顶层段确实不存在。 这些示例落在 stripCode() 的结构性盲区里(围栏内代码在扫描前被抹成空格), 任何门禁都看不见,故加一句诚实提示要求改动时手工核对,不为它造新门禁。 Fixes #3570 --- CONTRIBUTING.md | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 360998d250..e72bfcb17a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -440,31 +440,43 @@ pnpm site:build [Quick Start](/docs/guide/quick-start) [Components](/docs/components) -[API Reference](/docs/reference/api/core) -[Protocol Specs](/docs/reference/protocol/overview) -[Architecture](/docs/architecture/component) +[API Reference](/docs/api/schema-reference) +[App Schema](/docs/core/app-schema) +[Architecture](/docs/guide/architecture) ``` #### ❌ Incorrect Link Patterns ```markdown -[Quick Start](/guide/quick-start) -[Components](/components) +[Quick Start](/guide/quick-start) +[Components](/components) - -[API Reference](/api/core) -[Spec](/spec/component) -[Protocol](/protocol/form) + +[API Reference](/reference/api/core) +[Architecture](/architecture/component) +[Spec](/spec/app) ``` +The example links in the two fenced blocks above are invisible to the link gate — `check-doc-links.mjs` blanks fenced code and inline code spans before it scans (it has to: markdown link syntax quoted inside code is not a link), so whenever you edit these examples, verify each route by hand against the pages actually present in `content/docs/`. + #### Why? Fumadocs is configured with `baseUrl: '/docs'`, which means all documentation pages are served under the `/docs` route in Next.js. Internal links must include the `/docs/` prefix to match the actual URL structure where the pages are accessible. #### Validating Links -Link validation runs automatically via GitHub Actions on all PRs using lychee-action. This checks for broken internal and external links. +Two separate checks with two different jobs — knowing which is which saves a wasted debugging round: + +- **Internal links are the PR gate.** `scripts/check-doc-links.mjs`, run by `.github/workflows/docs-links.yml` on every pull request to `main` / `develop` (and on pushes to them). It resolves each `/docs/...` route and each relative path against the files in the checkout — reading the tree and nothing else, no network — so it is deterministic, and a failure blocks the merge. The workflow deliberately carries no `paths` filter, so a docs-only PR is checked too. Run the same script locally before you push: + + ```bash + pnpm docs:check-links + ``` + +- **External URLs are swept out of band, and gate nothing.** lychee, run by `.github/workflows/check-links.yml`, makes real network requests and is wired to a weekly cron plus manual `workflow_dispatch` only — never to `pull_request`. That is a deliberate tradeoff (#3213): one third-party 502, rate-limit or anti-scraping response would otherwise turn an unrelated PR red with nothing its author could do about it. The job does fail its own scheduled run on a broken external link; it just never fails yours. + +Which files each check reads is declared in the tools themselves — the `SCAN_ROOTS` table at the top of `scripts/check-doc-links.mjs`, and the `args` list in `check-links.yml`. Both surfaces get extended over time, so read them there instead of trusting a list copied into prose. ## Versioning and Releases