深入解析:质量门禁

质量门禁

质量门禁是本项目交付闭环的最后一道防线。它由本地门禁make test)和 CI 门禁(GitHub Actions)两层构成,共 8 项自动化检查,确保每一次提交都满足文档结构、链接完整性、元数据一致性和 AI 引用准确性四类约束。对于高级开发者而言,理解门禁的分层架构和每项检查的内部逻辑,是高效通过 CI 并在本地快速定位问题的前提。

架构总览

质量门禁采用本地优先、CI 兜底 的双层策略。开发者在提交前通过 make test 在本地执行全部 7 项同步检查;推送后 GitHub Actions 在**markdown-lint** job 中复现同样的 7 项检查,并在 link-checker job 中补充外部链接验证。两层共享同一套脚本和配置,消除了"本地通过但 CI 失败"的环境差异问题。

门禁检查项详解

1. Markdown 格式检查(make lint

npx --yes markdownlint-cli@0.48.0 执行,固定版本号以避免跨环境行为差异。规则配置集中管理于 .github/lint_config.json,CI 和本地共享同一份配置文件。当前配置采用白名单策略------default: true 启用所有规则,随后逐项禁用不适用的规则(如 MD001/MD013/MD025 等),保留项目实际需要的子集。检查范围覆盖全仓库 **/*.md ,但排除 .historytools/external 目录。

💡:lint 规则的增删必须同时修改 .github/lint_config.json,因为 Makefile 和 CI 都引用该文件。不要在命令行通过 --rule 参数覆盖,否则会导致本地/CI 行为不一致。

2. 本地链接与锚点检查(check-links

脚本 check-local-links.py 遍历仓库内所有 Markdown 文件,提取两种模式的链接:标准 Markdown 链接 ![...](...) 和 HTML 属性 href="..." / src="..."。对于每个非外部链接,执行两项验证:

  • 文件存在性:解析目标路径,确认文件在仓库内存在
  • 锚点存在性:如果目标包含 #fragment,提取目标文件的全部锚点集合(包括 <a id="..."> 手动锚点和通过 github_slug() 算法从标题自动生成的锚点),确认 fragment 在集合中

脚本内置了代码围栏感知(strip_fenced_code),避免误报代码块内的链接。跳过目录包括 .git.historynode_modules.github/wikitools/externaltools/chat-vault

3. 折叠块结构检查(check-details

脚本 check-markdown-details.py 验证所有 <details> 块的结构完整性,执行三项检查:

  • 每个 <details> 必须有对应的 </details> 关闭标签
  • 每个 <details> 块内必须包含 <summary> 标签
  • 每个 <summary> 标签内容必须包含"点击展开/收起"提示文字
  • 同一 <details> 块内不允许重复的 <summary> 标签

错误输出格式为 MARKDOWN_DETAILS_ERRORS,附带文件路径和行号。

4. 文档结构检查(check-doc-structure

脚本 check-doc-structure.py 是最复杂的门禁项,它通过**scripts/lib/taxonomy.py** 读取 metadata/taxonomy.yml 中定义的文档分类体系,对**docs/**下的线性 README 执行多层约束验证。核心检查包括四个维度:

标准块顺序验证 :每个 docs README 必须按固定顺序包含五个标准块------顶部标题块、## 字多不看## 快速导航 、完整细粒度目录(<details> 折叠块)、## 使用方式 。H1 标题和 **## 字多不看**之间禁止插入任何内容。同时检查是否包含禁止标题(如"和其他目录的边界"、"维护规则")。

主锚点顺序验证 :从 taxonomy 获取每个文档的 expected_anchors,验证这些锚点在 README 中的出现顺序与 taxonomy 定义一致,且全部存在。

目录覆盖验证 :提取顶部导航和折叠细粒度目录中的所有 #anchor 链接,确认所有主锚点和以主锚点为前缀的手动锚点都在目录中有对应条目。

重复锚点检测 :对全仓库所有 Markdown 文件(排除 skip 列表)进行 **<a id="...">**重复锚点扫描,确保每个手动锚点全局唯一。

5. 目录文档覆盖检查(check-directory-docs

脚本 check-directory-docs.py 维护一个硬编码的 REQUIRED_DIRS 列表(约 35 个目录),验证每个目录都包含必需的文档文件。默认要求同时存在 README.mdAGENTS.md.github/ 目录例外,仅要求 AGENTS.md ,避免 GitHub 首页误展示平台配置说明。脚本还会自动发现仓库中未被 REQUIRED_DIRS 列表覆盖的新目录(排除 symlink、vendor subtree 和生成目录),确保新目录不会遗漏文档。

6. 元数据路径与锚点检查(check-metadata

脚本 check-metadata.py 验证 metadata/taxonomy.ymlmetadata/redirects.yml 中所有引用的本地路径和锚点是否有效。对于 taxonomy.yml,解析 path:entry:agent_guide: 字段值以及 - 列表项中的路径引用;对于 redirects.yml,额外执行三项专项检查:

  • 重定向源路径是否仍然存在于仓库中(存在则说明迁移未完成)
  • 重定向源是否映射到自身(no-op redirect)
  • 重定向源是否重复定义

💡:当 taxonomy 或 redirects 发生修改时,先运行 make check-metadata 验证路径有效性,再运行完整 make test。元数据错误通常表现为"missing metadata target"或"missing metadata anchor"。

7. AI 引用语料检查(check-ai-citation

脚本 check-ai-citation.py 覆盖两个 AI 入口文件(llms.txtassets/ai-citation/llms-full.txt)以及 assets/ai-citation/*.md 目录下的所有 Markdown 文件。验证机制与 check-local-links.py 类似,但使用更宽泛的 PATH_PATTERN 正则以捕获非链接格式的路径引用(如纯文本中的 docs/concepts/README.md)。额外验证 llms-full.txt 是否覆盖了 taxonomy 中定义的所有文档路径,确保 AI 完整上下文入口的完整性。

在 CI 层,ci.yml 中的 link-checker job 使用 lycheeverse/lychee-action@v2.8.0 检查仓库内所有 Markdown 文件中的外部链接有效性。此检查仅在 CI 中运行,不在 make test 中包含,因为它需要网络访问且耗时较长。配置文件为 .lychee.toml

检查项全览

| |:--|:------|:---------|:-----|:--------|:--------|

| 1 | Markdown 格式 | make lint | npx markdownlint-cli | .history, tools/external | (markdownlint 原生输出) |

| 2 | 本地链接/锚点 | make check-links | check-local-links.py | .git, .history, node_modules, .github/wiki, tools/external, tools/chat-vault | MISSING_LINKS, MISSING_ANCHORS |

| 3 | 折叠块结构 | make check-details | check-markdown-details.py | .git, .history, node_modules, .github/wiki, tools/external | MARKDOWN_DETAILS_ERRORS |

| 4 | 文档结构 | make check-doc-structure | check-doc-structure.py | .git, .history, node_modules, .github/wiki, tools/external | DOC_STRUCTURE_ERRORS |

| 5 | 目录文档覆盖 | make check-directory-docs | check-directory-docs.py | symlink, vendor subtree | DIRECTORY_DOC_ERRORS |

| 6 | 元数据路径 | make check-metadata | check-metadata.py | (无) | METADATA_ERRORS |

| 7 | AI 引用路径 | make check-ai-citation | check-ai-citation.py | (无) | AI_CITATION_ERRORS |

| 8 | 外部链接 | CI only | lychee-action | (由 .lychee.toml 控制) | (lychee 原生输出) |

CI 触发与流水线

GitHub Actions 工作流定义于 .github/workflows/ci.yml,在以下三种条件下触发:

  • pushdevelopmaster 分支
  • pull_request 目标为 developmaster 分支
  • 手动 workflow_dispatch 触发

流水线包含两个并行 job:markdown-lint (7 项同步检查)和 link-checker (外部链接)。两个 job 都使用 actions/checkout@v6 并启用 submodules: recursive,确保外部 submodule 中的文件也被纳入检查范围。

辅助工具:sync-doc-toc

make sync-doc-toc 执行 sync-doc-toc.py,根据 metadata/taxonomy.yml 和文档中的实际锚点自动重建 docs 线性 README 的折叠细粒度目录块。脚本从 taxonomy 获取每个文档的 main_anchors ,扫描文档中 <a id="..."> 锚点(只收集主锚点及其子前缀锚点),提取锚点后紧跟的标题行,渲染为层级目录,最后原地替换 <details> 块内容。当修改了 docs README 的章节锚点后,必须先运行 make sync-doc-toc 再运行 make test ,否则 **check-doc-structure**会因目录未同步而报错。

执行流程与开发者工作流

推荐的完整提交前检查序列

  1. 格式校验make lint --- 确保 Markdown 格式合规
  2. 目录同步 (仅当修改了 docs README 时):make sync-doc-toc --- 重建细粒度目录
  3. 全量门禁make test --- 执行全部 7 项本地检查
  4. 差异审查git diff --- 确认无临时文件或敏感信息混入
  5. 推送并观察git push origin develop --- 观察 GitHub Actions 结果

错误诊断速查

错误前缀 含义 典型修复
MISSING_LINKS 仓库内引用的文件不存在 检查路径拼写或补全缺失文件
MISSING_ANCHORS 锚点在目标文件中不存在 检查锚点拼写或目标文件标题是否变更
MARKDOWN_DETAILS_ERRORS <details>/<summary> 结构异常 补充缺失的关闭标签或 <summary>
DOC_STRUCTURE_ERRORS docs README 结构违反契约 调整标准块顺序、补充缺失锚点、运行 sync-doc-toc
DIRECTORY_DOC_ERRORS 目录缺少必需的 README/AGENTS 在对应目录下创建缺失文件
METADATA_ERRORS taxonomy/redirects 中引用失效 修正 metadata YAML 中的路径或锚点
AI_CITATION_ERRORS AI 入口文件引用路径漂移 更新 llms.txt 或 AI 引用语料中的路径

扩展阅读

下一章:问题解决框架

相关推荐
江畔柳前堤1 天前
roLabelImg 详细安装教程
开发语言·人工智能·后端·云原生
阿里云大数据AI技术1 天前
分链路差异化设计的DSP准实时数仓|钛动科技基于阿里云实时计算 Flink 版 + DLF Paimon + EMR Serverless StarRocks 的实践
人工智能·flink
陕西企来客1 天前
2026年7月AI智能搜索曝光趋势研判
大数据·人工智能·机器学习·ai智能搜索曝光
阿里云大数据AI技术1 天前
从算力到智能体,面向 Agentic AI 的基础设施演进
人工智能·agent
hangyuekejiGEO1 天前
GEO技术服务选型指南
大数据·人工智能·python
普通攻击往后拉1 天前
Leetcode 206. 反转链表
算法·leetcode·链表
阿里云大数据AI技术1 天前
EMR Serverless Spark AI Function 的双维降本实践
人工智能·sql·spark
维基框架1 天前
GitHub源码处理提速 一趟扫描反而更慢
人工智能·github
冬奇Lab1 天前
代码库知识库系列(05):向量检索 vs 知识图谱——加了调用图并没有变更好
人工智能
AKAMAI1 天前
你的源服务器可能是你做出的最昂贵决定
运维·人工智能·云计算