Files
Edu/docs/superpowers/specs/2026-07-08-cicd-no-push-local-build-design.md
SpecialX 68ddff1065
Some checks failed
CI / quality-go (push) Failing after 3s
CI / quality-proto (push) Failing after 2s
CI / quality-ts (push) Failing after 47s
CI / deploy (push) Has been skipped
refactor(infra): 重构为 no-push 本地构建部署模式
- 删除 6 个分散 workflow(ci-ts/ci-go/ci-proto/ci-py/docker/deploy)
- 合并为单个 ci.yml:3 个 quality job 并行 + deploy job 串行
- 全部使用官方镜像(node:22-alpine/golang:1.22-alpine/bufbuild/buf/docker:25-git)
- deploy job 用 DooD 模式挂载 /var/run/docker.sock
- docker-compose.deploy.yml 改用 build: 替代 image:(no-push)
- 新增 docker-compose.tools.yml 一次性预拉所有 CI 镜像
- 支持 workflow_dispatch 指定 commit_sha 回滚
- 更新 project_rules §15 与 cicd-runbook.md 为 no-push 模式
- 新增设计文档 docs/superpowers/specs/2026-07-08-cicd-no-push-local-build-design.md
2026-07-08 17:12:57 +08:00

138 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CI/CD 设计本地构建部署no-push
> 日期2026-07-08
> 状态:已批准,待实施
> 替代方案:[2026-07-08 之前的 docker.yml + deploy.yml push 方案](../../.github/workflows/)
## 1. 背景
### 1.1 现状问题
- `node-with-docker:22` 自定义镜像已丢失,原方案依赖它无法运行
- 推送到 Gitea Registry 的拉取速度极慢,影响部署效率
- 用户习惯本地构建测试后再推送,无需保留历史构建产物
- 微服务架构下,拆分多个 workflow 文件ci-ts/ci-go/docker/deploy使流程碎片化
### 1.2 目标
- 不依赖任何自建镜像,全部使用官方镜像
- 不推送镜像到 registry构建即部署
- 单文件管理整个 CI/CD 流程
- 支持回滚(不依赖 registry tag
- 提供一次性预拉所有镜像的 compose 文件
## 2. 设计
### 2.1 架构总览
```
PR/push 触发
├─ quality-ts job (container: node:22-alpine) 并行
├─ quality-go job (container: golang:1.22-alpine) 并行
├─ quality-proto job (container: bufbuild/buf:latest) 并行
└─ deploy job (container: docker:25-git) 仅 push main, needs: [quality-*]
挂载 /var/run/docker.sockDooD
├─ docker compose up --build本地构建 3 个服务)
└─ 健康检查轮询
```
### 2.2 文件结构
```
.github/workflows/
└─ ci.yml # 唯一的 CI/CD 文件
infra/
├─ docker-compose.deploy.yml # 改造build: 替代 image:
├─ docker-compose.tools.yml # 新建:预拉所有 CI 需要的镜像
└─ deploy.env.example # 保留
```
### 2.3 ci.yml 设计
**单文件多 job**
- `quality-ts`PR+push 都跑container: node:22-alpinepnpm install → lint → typecheck → test → build
- `quality-go`PR+push 都跑container: golang:1.22-alpinego mod download → vet → build → test
- `quality-proto`PR+push 都跑container: bufbuild/buf:latestbuf lint + buf breaking仅 PR
- `deploy`:仅 push main 或 workflow_dispatch 触发needs: [quality-ts, quality-go, quality-proto]
**deploy job 关键配置**
- `container: docker:25-git`(官方镜像,自带 docker CLI + compose v2 + git
- `options: --volume /var/run/docker.sock:/var/run/docker.sock`DooD 模式)
- 流程checkout → cp compose 文件到 /opt/edu/ → docker compose up --build → 健康检查
**回滚**
- `workflow_dispatch` 支持 `commit_sha` 输入
- checkout 时使用指定 commit SHA
- 重新 build + deploy
### 2.4 docker-compose.deploy.yml 改造
所有服务从 `image:` 改为 `build:`
- `api-gateway``build: ./services/api-gateway`
- `classes``build: { context: ., dockerfile: services/classes/Dockerfile }`monorepo 上下文)
- `teacher-portal``build: { context: ., dockerfile: apps/teacher-portal/Dockerfile }`monorepo 上下文)
删除 `IMAGE_TAG` 环境变量依赖。`docker compose up --build` 自动判断变更的服务。
### 2.5 docker-compose.tools.yml预拉镜像
用于一次性拉取所有 CI/构建需要的镜像到本地:
- CI 运行时node:22-alpine、golang:1.22-alpine、bufbuild/buf:latest、docker:25-git
- 服务构建基础node:20-alpine、golang:1.22-alpine、alpine:3.20
- 开发基础设施mysql:8.0、redis:7-alpine
用法:`docker compose -f infra/docker-compose.tools.yml pull`
### 2.6 回滚策略
| 方式 | 操作 | 适用场景 |
| ---------- | --------------------------------------------------- | ---------------- |
| git revert | `git revert <bad-commit> && git push` → 自动触发 CI | 代码回滚(推荐) |
| 手动触发 | Actions → ci.yml → Run workflow → 填 commit_sha | 部署特定版本 |
### 2.7 actrunner 配置
```toml
container:
valid_volumes:
- /var/run/docker.sock
```
## 3. 实施步骤
1. 删除现有 4 个 workflow 文件ci-ts.yml、ci-go.yml、ci-proto.yml、docker.yml、deploy.yml
2. 创建 `.github/workflows/ci.yml`(合并单 workflow
3. 改造 `infra/docker-compose.deploy.yml`build 替代 image
4. 创建 `infra/docker-compose.tools.yml`(预拉镜像)
5. 更新 `.trae/rules/project_rules.md` §15no-push 模式规范)
6. 更新 `docs/standards/cicd-runbook.md`(删除 registry 章节,新增本地构建章节)
7. 提交并推送
## 4. 与旧方案对比
| 维度 | 旧方案push 到 registry | 新方案no-push 本地构建) |
| --------------- | -------------------------- | ------------------------------ |
| workflow 文件数 | 4 个 | 1 个 |
| 镜像推送 | push 到 Gitea Registry | 不推送 |
| 部署方式 | compose pull + up | compose up --build |
| 自建镜像 | 依赖 node-with-docker:22 | 全用官方镜像 |
| 回滚 | 切换 registry tag | git revert / workflow_dispatch |
| 构建产物保留 | registry 保留历史 | 不保留 |
## 5. 风险与缓解
| 风险 | 缓解 |
| ------------------------- | ---------------------------------------------- |
| 本地镜像被清理后无法回滚 | 回滚走 git revert + 重新 build不依赖镜像缓存 |
| docker.sock 挂载安全风险 | actrunner 仅在部署服务器运行,已隔离 |
| 构建慢 | layer cache 在宿主机本地,未变更的层秒过 |
| Gitea workflow_run 不支持 | 用 needs 串联,不用 workflow_run |