跳转至

CI/CD

生态系统的所有仓库都使用 GitHub Actions。本页说明通用的模式与约定。

基本原则

  1. 在 PR 上校验,在 main 上部署。 PR 只跑构建与测试,不做任何部署。 只有合并进 main 之后才会触发部署。
  2. 只构建有改动的部分。 通过 paths-filter 判断哪些部分发生了变化, 只重建这些服务。
  3. 不并发部署。 concurrency 分组会让生产部署排队,绝不同时进行。
  4. 机密只放在 GitHub Secrets 中。 绝不写进 workflow 文件。

常见的 workflow 结构

name: deploy

on:
  push:
    branches: [main]
    paths:
      - 'backend/**'
      - 'frontend/**'
      - '.github/workflows/deploy.yml'
  workflow_dispatch:          # 允许手动触发

concurrency:
  group: deploy-production
  cancel-in-progress: false   # 部署过程中绝不中断

cancel-in-progress: false 很关键

部署被中途打断,可能留下半成品状态——新容器没起来,旧容器已经停了。 应当让部署跑到结束,把下一次排在后面。

校验阶段(PR)

检查项 作用
构建 代码能否编译
单元测试 业务逻辑
集成测试 testcontainers——真实的 PostgreSQL/Redis
Lint 代码风格
文档 strict 构建 发现失效链接与缺失文件

文档的 strict 校验

MkDocs 以 --strict 模式构建。在该模式下警告会变成错误

  • 失效的内部链接;
  • nav 中声明却不存在的文件;
  • 存在却未列入 nav 的文件。

这样就能防止文档层面的损坏流入生产环境。

部署阶段

通过 SSH 连接到主机执行。所需的 secrets(通用命名):

Secret 含义
DEPLOY_HOST 服务器地址
DEPLOY_USER SSH 用户
DEPLOY_SSH_KEY 私钥
DEPLOY_PORT SSH 端口(可选,默认 22)
DEPLOY_PATH 主机上的路径

用 SSH 密钥,而不是密码

部署使用 SSH 密钥而非密码。密钥易于吊销,意外出现在日志中的概率更低, 而且轮换时无需再向众人重新分发。

增量构建

在 monorepo 中,一处改动不该要求重建全部服务:

- uses: dorny/paths-filter@v3
  id: filter
  with:
    filters: |
      backend: 'backend/**'
      frontend: 'frontend/**'
      edge: 'nginx/**'

随后只重建发生变化的服务。若变的是 edge(nginx),则不做整体重建, 仅执行配置同步 + nginx -t + reload

edge 配置的部署

edge nginx 的 conf.d 由 git 管理。部署顺序为:

  1. 在主机上执行 git fetch && git reset --hard 同步仓库;
  2. docker exec <nginx> nginx -t——校验配置
  3. 校验通过后再执行 nginx -s reload

不得跳过 nginx -t

带着错误配置去 reload,会让 nginx 起不来——那一刻所有域名都会宕掉。 nginx -t 必须在 reload 之前运行,一旦失败就应中止部署。

自托管 runner

iOS 与 Windows 的构建(代码签名、公证、MSIX 打包)使用 自托管的 macOS / Windows runner。它们依赖特定平台的工具与证书, 因此无法在云端 runner 上运行。

版本与回滚

  • 镜像均带 tag。可在主机上用 <SVC>_IMAGE_TAG 变量固定到某个具体版本。
  • 静态站点则重新解开上一次构建的归档。

本仓库的 CI/CD

docs-gerege-mn 仓库有两个 workflow:

Workflow 触发时机 作用
ci.yml PR + 推送到 main MkDocs --strict 构建;保留构建产物
deploy.yml 推送到 main + 手动 构建 → 复制 → 更新容器 → 安装 edge vhost → 校验线上站点

详情请见本文档平台页面。