Skip to content

feat(ci): PR 防呆——docs rename/delete 时自动校验 redirect 覆盖#353

Merged
longsizhuo merged 1 commit into
mainfrom
feat/ci-doc-path-check
May 24, 2026
Merged

feat(ci): PR 防呆——docs rename/delete 时自动校验 redirect 覆盖#353
longsizhuo merged 1 commit into
mainfrom
feat/ci-doc-path-check

Conversation

@longsizhuo
Copy link
Copy Markdown
Member

Summary

  • 新增 scripts/check-doc-paths.mjs:当 PR 中 content/docs/** 有文件被 rename 或 delete 时,CI 自动检查旧 URL 是否已在 next.config.mjs 的 redirects 里有 source 覆盖
  • 更新 .github/workflows/content-check.yml:在 frontmatter 检查后追加 Check doc path coverage (301 redirect) step(拦截性,exit 1 阻断合并)

算法

  1. git diff origin/BASE_REF...HEAD --diff-filter=RD --name-status 提取所有被 rename/delete 的 content/docs/** 旧路径
  2. 旧路径归一化为 URL(去 content/ 前缀、去 .en.mdx/.mdx 后缀、去 /index 结尾)
  3. 双语文件(.en.md / .en.mdx)归一化后去重,只检查一次
  4. 对每个旧 URL,检查 next.config.mjs 里是否有精确匹配的 source 或 :path* wildcard 前缀覆盖
  5. 未覆盖 → 打印具体旧文件路径和补救指引 → exit 1

豁免

next.config.mjs 里写注释 # no-redirect-needed: <path> 可跳过对应路径(用于确认不需要兜底的场景)。

Smoke test 结果

# 无 redirect 时(exit 1)
❌ 缺少 redirect 覆盖:/docs/learn/cs/dev-tips/git101
   旧文件:content/docs/learn/cs/dev-tips/git101.mdx
   请在 next.config.mjs 加 redirect,或确认此路径无需兜底(加注释 # no-redirect-needed: docs/learn/cs/dev-tips/git101)
❌ check:doc-paths 未通过,请补充 redirect 后重提 PR

# 加上 redirect 后(exit 0)
✅ redirect 已覆盖:/docs/learn/cs/dev-tips/git101
✅ check:doc-paths 通过,所有旧路径均有 redirect 覆盖

Test plan

  • 本地 smoke test:无 redirect → exit 1;加 redirect → exit 0
  • pnpm test 51 个测试全绿
  • PR 无 docs 文件变更时直接 exit 0(不干扰无关 PR)
  • CI 跑完确认 Check doc path coverage step 出现在 Actions 里

🤖 Generated with Claude Code

PR 中 content/docs/** 文件被 rename/delete 时,CI 自动校验旧 URL
是否已在 next.config.mjs 的 redirects 里有 source 覆盖(精确匹配或
:path* wildcard)。未覆盖则 exit 1 阻断合并,避免搜索引擎收录链接变 404。

- scripts/check-doc-paths.mjs:核心校验脚本(算法:git diff --name-status
  提取旧路径 → URL 归一化 → source 覆盖检查 → 报错输出)
- .github/workflows/content-check.yml:追加 Check doc path coverage step

豁免机制:在 next.config.mjs 里写 "# no-redirect-needed: <path>" 注释可跳过
对应路径的检查。双语文件(.en.md / .en.mdx)去重到同一 URL 只检查一次。
Copilot AI review requested due to automatic review settings May 24, 2026 17:52
@vercel
Copy link
Copy Markdown

vercel Bot commented May 24, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
involutionhell-github-io Building Building Preview, Comment May 24, 2026 5:56pm
website-preview Ready Ready Preview, Comment May 24, 2026 5:56pm

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a CI guard to prevent accidental SEO-breaking 404s when docs under content/docs/** are renamed or deleted, by requiring that the old URLs are covered by a 301 redirect rule in next.config.mjs.

Changes:

  • Add scripts/check-doc-paths.mjs to detect renamed/deleted doc pages in a PR and validate redirect source coverage (including /:path* prefix rules).
  • Extend content-check.yml to run the new redirect-coverage check after the existing frontmatter validation.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.

File Description
scripts/check-doc-paths.mjs New script that derives old doc URLs from git diff and verifies they are covered by next.config.mjs redirect sources (with an exemption mechanism).
.github/workflows/content-check.yml Adds a blocking CI step to execute the new doc redirect coverage check on PRs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +19 to +21
* 豁免
* 如果文件注释里含有 # no-redirect-needed,该路径跳过检查(用于确认不需要兜底的场景)。
* 在 next.config.mjs 的 redirects 块里写这个注释即可豁免对应旧路径。
Comment on lines +39 to +46
try {
// --diff-filter=RD:只取 Renamed 和 Deleted
// --name-status:输出 "R100\told\tnew" 或 "D\tpath",这样 rename 时能拿到旧路径
// --name-only 对 rename 只给新路径,无法检查旧 URL,必须用 --name-status
output = execSync(
`git diff origin/${BASE_REF}...HEAD --diff-filter=RD --name-status -- 'content/docs/**'`,
{ cwd: ROOT, encoding: "utf-8" },
).trim();
Comment on lines +55 to +56
console.log("⚠️ 无法获取 git diff,跳过 doc path 检查");
process.exit(0);
Comment on lines +78 to +79
return oldPaths.filter((f) => f.startsWith("content/docs/"));
}
Comment on lines +89 to +92
- name: Check doc path coverage (301 redirect)
run: node scripts/check-doc-paths.mjs
env:
GITHUB_BASE_REF: ${{ github.base_ref }}
Comment on lines +147 to +150
/**
* 如果 next.config.mjs 里存在注释 "# no-redirect-needed: <url>"(或包含该 URL 的行),
* 则该 URL 豁免检查。格式宽松:只要注释行包含 no-redirect-needed 和该 url 片段即算豁免。
*/
Comment on lines +200 to +202
console.error(
` 请在 next.config.mjs 加 redirect,或确认此路径无需兜底(加注释 # no-redirect-needed: ${url.replace(/^\//, "")})`,
);
@longsizhuo longsizhuo merged commit a4199db into main May 24, 2026
7 of 8 checks passed
@longsizhuo longsizhuo deleted the feat/ci-doc-path-check branch May 24, 2026 17:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants