CI/CD 流水线(Gitee Go)
解决什么问题:每次 push / PR 都自动跑静态检查 + 构建,master 分支额外自动部署到 Web 服务器,保证线上 wiki 始终是高质量、可访问的。
流水线概览
push to master / PR
│
▼
┌──────────────────────────┐
│ Stage 1: 静态检查 │ ← 1 分钟内
│ - frontmatter 校验 │
│ - 死链扫描 │
│ - 文档统计 │
└──────────────────────────┘
│
▼
┌──────────────────────────┐
│ Stage 2: 构建 │ ← 约 10-15 秒
│ - pnpm install │
│ - vitepress build │
│ - 验证 dist 产物 │
└──────────────────────────┘
│(master + branch 都会上传制品;仅 master 有 Stage 3)
▼ (仅 master 分支)
┌──────────────────────────┐
│ Stage 3: 部署 │ ← 约 30 秒
│ - agent 下载制品包 │
│ - deploy.sh 发布到 dist │
│ - nginx reload + 自检 │
└──────────────────────────┘流水线文件(3 条,以 Gitee Go 网页上启用的为准)
| 文件 | 触发 | 用途 |
|---|---|---|
.workflow/master-pipeline.yml | push → master | lint + build + 部署(主链路) |
.workflow/branch-pipeline.yml | push → 非 master | 编译 + 上传制品 + 发布 release(不部署) |
.workflow/pr-pipeline.yml | PR → master | 编译验证(不部署) |
旧的
.workflow/world_map_cicd.yml(npm 版)已于 2026-10-01 删除,统一为 pnpm 版三件套。
Stage 1:静态检查
触发:所有 push 和 PR(master 链路内合并为单个 step,原来分两个 step 跑两次 pnpm install 是浪费,已合并)。
Node 版本:24.13.0(vitepress 2.0 alpha.18+ 要求 Node ≥ 22,本地 engines 声明 >=22)。
命令:
bash
pnpm config set registry https://registry.npmmirror.com
pnpm install --frozen-lockfile
pnpm run lint # frontmatter + 死链
pnpm run statsfrontmatter 校验规则
| 字段 | 必填 | 合法值 |
|---|---|---|
title | ✓ | 任意字符串 |
type | ✓ | overview / concept / case / stub / structure / theme |
layer | ✓ | L1 / L2 / L3 / L4 / L5 / cross-layer / meta |
group | ✓ | 字符串(sidebar 分组) |
status | ✓ | mature / stub / draft / archived |
附加规则:
- frontmatter title 与正文 H1 不一致 → error
- 仅 emoji 差异 → warning(不阻断构建)
- 无 frontmatter 的 index.md → warning(概览页可豁免)
- meta/ai-collaboration/drafts/ 和 meta/source/ → 跳过
死链扫描
实现:scripts/check-deadlinks.mjs
- 提取所有
[text](href)形式的链接 - 跳过 http(s)😕/ 外部链接和 # 锚点
- 检查相对路径和
/绝对路径两种形式 - 检查
.md后缀、index.md、目录三种候选
输出示例:
========================================
World Map · 死链扫描报告
========================================
扫描文件:317 个 .md
含链接的文件:174
总链接数:1247
✅ 零死链文档统计
实现:scripts/stats.mjs
- 总文档数 / 总行数 / 总字节
- 按 status / layer / type 三个维度分布
- 输出到 CI 日志,PR 时直接可见
Stage 2:构建
触发:所有 push 和 PR
命令:
bash
pnpm config set registry https://registry.npmmirror.com
pnpm install --frozen-lockfile
pnpm run docs:build # vitepress build(自带死链检查)
cp deploy.sh .vitepress/dist/deploy.sh # 让部署脚本随制品一起发布
# 验证产物
ls -al .vitepress/dist
du -sh .vitepress/dist产物:BUILD_ARTIFACT = .vitepress/dist/
当前基线(vitepress 2.0.0-alpha.20,2026-10-01):
- 构建时间:约 10-15 秒(Vite 8 + rolldown;alpha.17 时代约 22 秒)
- 产物大小:约 19M(alpha.17 时代约 30M)
- 产物文件数:约 900 个文件(含 deploy.sh)
Gitee Go build@nodejs 已知坑
| 现象 | 原因 | 修复 |
|---|---|---|
npm ERR! missing script: build | 默认脚本执行 npm run build | 已改用 pnpm 显式命令,不再依赖默认脚本 |
| Node 版本太老导致构建失败 | nodeVersion 字段或默认镜像 Node 过旧 | 所有 yml 固定 nodeVersion: 24.13.0 |
find index.html 定位到子页面导致部署失败 | 制品包是散装文件,head -n 1 命中子页面 | 网站根改用 deploy.sh 定位(制品根仅此一份),详见下节 |
Stage 3:部署(仅 master)
触发:仅 master 分支 push(PR 不触发)。
前置配置(已就绪,2026-10-01):
yaml
# .workflow/master-pipeline.yml 中的 stage-deploy
hostGroupID:
ID: wiki
hostID:
- da3b39c4-b5b7-4894-b654-ccbd776a3326 # Web 服务器部署主机(ubuntu@100.90.0.150):
- nginx 1.28,站点配置
/etc/nginx/sites-enabled/world-map.conf,root /data/world-map/dist(兼容 VitePress cleanUrls,/assets/长期缓存) - Gitee Go agent 常驻:
/root/gitee-go-runner+ systemdgitee-go-runner.service(开机自启,挂了 10 秒拉起) - 发布目录
/data/world-map/{dist,logs},属主ubuntu
deploy 段逻辑(master-pipeline.yml):
bash
# 1. 找到 agent 下载下来的制品包
# 2. 解压到 /tmp/wm-artifact
# 3. 用 deploy.sh 定位网站根(不用 index.html,避免误中子页面)
# 4. sh deploy.sh deploy → 发布 + nginx reload + curl 自检部署脚本:./deploy.sh(仓库根 + 制品根各一份,部署时制品里的新版会自更新服务器副本)
| 命令 | 作用 |
|---|---|
deploy [SRC_DIR] / restart | 发布到 /data/world-map/dist → nginx reload → curl 自检 / 和 /modeling/ |
stop | 停止 nginx(谨慎) |
status | 查看 nginx 状态 + 本地 curl 自检 |
定位规则(2026-10-01 修复后的版本,两处一致):
- 目录下有
index.html→ 就是网站根 - 否则找
deploy.sh(制品根仅此一份,最可靠) - 兜底:最短路径的
index.html
本地开发
提交前:
bash
pnpm run lint # frontmatter + 死链
pnpm run docs:build # 验证构建或一次性:
bash
pnpm run ci # lint + build(与 Gitee Go 一致)手动脚本:
bash
pnpm run stats # 看统计
pnpm run lint:frontmatter # 只查 frontmatter
pnpm run lint:deadlinks # 只查死链本地预览:
bash
pnpm run docs:dev # 边改边看,hot reload(默认 :5173)
pnpm run docs:preview # 预览构建产物(默认 :4173)日常工作流
本地改 → pnpm run ci 自检 → git push master → Gitee Go 自动部署到 100.90.0.150:80- 主分支
master始终可部署;日常直接在 master 上做(单人 + AI 协作,分支开销大于收益) - 重大骨架重构 / >10 文件批量改动才开 feature branch(见 git 流程规范)
与写作范式的关系
CI 强制执行的规则 = 写作范式(meta/writing-style/)的程序化版本:
| 写作范式规定 | CI 强制执行 |
|---|---|
| frontmatter 必填 4 字段 | pnpm run lint:frontmatter |
| type 枚举 6 个 | enum 校验 |
| layer 枚举 | enum 校验 |
| status 枚举 | enum 校验 |
| 标题与 H1 一致 | title check |
| 文档末尾 ≥3 条相关链接 | (暂未自动化,建议手动检查) |
| Mermaid 图表 | (暂未自动化) |
| 表格 > 纯文字 | (暂未自动化) |
已落地的自动化(2026-10-01 前还是"后续可优化",现在已做):
未来可加的检查:
配置文件位置
world-map/
├── .workflow/
│ ├── master-pipeline.yml # ← 主链路:lint + build + 部署
│ ├── branch-pipeline.yml # ← 非 master:编译 + 制品 + release
│ └── pr-pipeline.yml # ← PR:编译验证
├── deploy.sh # ← 发布脚本(仓库根 + 制品根)
├── scripts/
│ ├── check-frontmatter.mjs # ← frontmatter 校验
│ ├── check-deadlinks.mjs # ← 死链扫描
│ └── stats.mjs # ← 文档统计
├── package.json # ← pnpm scripts(vitepress 2.0.0-alpha.20)
└── .gitignore # ← 排除 node_modules 等