文档即代码实战:用 Git 和 CI 管理技术文档

文档即代码(Docs as Code)把技术文档当作源代码一样对待:用 Git 做版本控制、用 Markdown 写内容、用 CI 自动构建与发布。它能根治文档与代码脱节、Review 缺失、过期没人敢信的老毛病,让文档像代码一样可审查、可追溯、可回滚。

一、为什么传统文档总是”写完就过期”

大多数团队的文档活在三类地方:项目根目录的 doc/ 文件夹、Confluence 或语雀这类 Wiki、或者干脆散落在即时通讯群里。它们的共同问题是——文档和代码是两套系统。代码改了,文档没人同步;新人想提个文档修改,发现根本没有 PR 这种概念;半年后文档和现实差了十万八千里,谁都不敢信,最后变成”文档仅供参考”。

文档腐烂的代价往往是隐性的:一个新同学想接手某个模块,翻遍仓库找不到最新设计文档,只能在群里问老人;老人的回答又散落在聊天记录里。等他终于拼凑出全貌,可能已经踩了三个坑。更糟的是,当文档和代码分属两套系统,没有人能为”文档是否还正确”负责——代码至少有测试兜底,文档没有。文档即代码要解决的,正是这个”双轨制”问题:让文档进入和代码相同的生命周期。

二、文档即代码的核心四件套

2.1 纯文本写作:Markdown / AsciiDoc / reStructuredText

放弃富文本编辑器,改用纯文本标记语言。纯文本意味着可以用 Git 做行级 diff、可以做 grep 搜索、可以被 CI 校验。Markdown 上手最快,AsciiDoc 和 reStructuredText(RST)则适合需要交叉引用、多版本、复杂排版的大型文档工程。

2.2 版本控制:Git 即真相源

所有文档放进 Git 仓库,和代码同库或相邻仓库。每次修改都是一个 commit,可以 Review、可以 blame、可以回滚到任意历史版本。文档的”最新正确状态”不再是某个人脑子里的东西,而是 main 分支上的内容。

2.3 自动化:CI 构建与预览

提交文档后,由 CI(例如 GitHub Actions 搭建的流水线)自动做拼写检查、死链检测、构建预览站。提交 PR 时自动生成预览链接,reviewer 不用本地搭环境就能看到渲染效果。

2.4 发布:静态站点

用 MkDocs、Sphinx、Docusaurus 等工具把 Markdown 构建成静态站点,合并到 main 即自动部署上线。整个过程没有人工拷贝粘贴。

三、最小可用工作流:从零搭起来

一个典型的仓库结构长这样:

docs-repo/
├── docs/
│   ├── index.md
│   ├── quickstart.md
│   └── api/
│       └── reference.md
├── mkdocs.yml          # 站点配置:导航、主题
└── .github/
    └── workflows/
        └── docs.yml    # CI:构建 + 预览 + 部署

CI 工作流负责三件事——构建、预览、部署:

name: docs
on:
  push:
    branches: [main]
  pull_request:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
      - run: pip install mkdocs-material
      - run: mkdocs build --strict   # 严格模式:有断链直接失败
      - if: github.event_name == 'pull_request'
        run: mkdocs gh-deploy --no-history  # 生成 PR 预览站

推荐用 VS Code 配合 Markdown 插件 写作,实时预览、一键插入代码块,比任何在线富文本编辑器都顺手。

四、它和”代码生成文档”是两回事

很多人会混淆两个概念。像 Swagger / SpringDoc 自动生成 API 文档 属于”代码生成文档”——文档内容从代码注解里抽出来,代码是源、文档是副产品。而文档即代码的源是人写的中文 Markdown,构建工具只是把它渲染成网页。两者并不冲突,反而互补:API 参考用代码生成保证不落后于接口,设计文档、教程、决策记录用手写 Markdown 走文档即代码流程。一个成熟团队往往两条线并行,而不是二选一。

五、团队落地清单

别一上来就追求完美,按成熟度分阶段推进:

阶段目标关键动作
入门文档进 Git把散落各处的文档迁到仓库,统一用 Markdown
进阶有 Review文档变更走 PR + 至少一人审批,禁直接推 main
成熟自动化CI 做死链与拼写校验,PR 自动出预览站
标杆可观测统计文档访问量与反馈,驱动持续更新

六、落地时最容易踩的坑

坑一:把全部历史文档一次性迁进来。 老文档又臭又长,全量迁移会劝退团队。先迁活跃项目,立标杆再推广。

坑二:只有构建没有校验。 没有 --strict 这类硬约束,断链和过期图表会悄悄积累。让 CI 红起来才有威慑力。

坑三:文档仓库和代码仓库彻底隔离。 理想情况是文档和对应代码放在同一 monorepo 或相邻仓库,改代码时顺手改文档,而不是跨系统记忆。

坑四:把文档权限锁死在个人账号。 文档进了某人的私人仓库或网盘,人一离职就成死链。文档即代码的前提是”组织资产”,用团队或组织仓库加只读归档,比个人空间稳妥得多。

七、附:一个可直接抄的 mkdocs.yml

光说不练没感觉,下面这份配置是 MkDocs Material 的精简可用版,复制即可跑:

site_name: 团队文档
theme:
  name: material
  features:
    - navigation.sections
    - content.code.copy
nav:
  - 首页: index.md
  - 快速开始: quickstart.md
  - API: api/reference.md
markdown_extensions:
  - admonition          # 支持 !!! note 提示框
  - pymdownx.superfences

把这份配置和前面的目录结构放在一起,mkdocs build 就能产出一套带搜索、带侧边导航的静态文档站。admonition 扩展让你用 !!! note 写”注意 / 警告”提示框,比纯加粗醒目得多;content.code.copy 则给每个代码块加一键复制按钮,读者体验直接拉满。如果你的文档长期只有一个人维护,这套配置也能让你在换电脑、换环境时零成本恢复工作状态—— clone 下来就能本地 mkdocs serve 预览,不必再四处追问”最新的文档到底在哪个网盘”。

八、小结

文档即代码不是什么新框架,而是一套”把文档当资产而非负担”的工程纪律。它用 Git 解决版本、用 CI 解决质量、用静态站点解决发布,最终让文档和代码在同一节奏上演进。当你下次又想新建一个在线文档空间时,不妨先想想:这篇文档,能不能直接进 Git?如果答案是能,那就别犹豫,开个仓库吧。

上一篇 WASI 实战:把 WebAssembly 带进服务器与边缘
下一篇 2026 大模型 8-9 月盘点:开源爆发与 Agent 拐点