Files
Edu/docs/standards/git-workflow.md

38 KiB
Raw Permalink Blame History

Edu Git 工作流规范

版本1.3 日期2026-07-10 状态v1.3恢复分支开发模式AI 不切换分支 适用范围Edu 多语言 monorepopnpm workspace + go.work + pyproject.toml 关联文档:


目录

  1. 分支开发
  2. Conventional Commits 规范
  3. commitlint + husky 配置
  4. 事后 Code Review
  5. 文档同步规则
  6. 多语言 monorepo 提交规则
  7. 版本管理
  8. 紧急回滚
  9. 附录CICD 与 Edu Git 工作流差异

一、分支开发

1.1 模式

本项目采用分支开发模式:人类决策者为每个任务/模块创建分支并分配给 AIAI 只在当前分配的分支上工作,分支的创建、切换、合并均由人类决策者维护。

AI 不允许自行切换/创建/合并分支。AI 禁止执行以下命令:

  • git checkout -bgit switch(创建/切换分支)
  • git branch(创建分支)
  • git merge(合并分支)
  • git push origin main(推送主干)

核心原则

  • main 分支始终保持可发布状态,只有人类决策者能向 main 合并
  • 人类决策者为每个任务/模块创建分支并分配给对应 AI
  • AI 只在当前分配的分支上工作,不切换、不创建、不合并分支
  • AI 完成提交后通知人类决策者合并,不自行 push main
  • 提交前本地通过 lint + typecheck + test + build见 §3.4 pre-push hook
  • 通过特性开关Feature Flag控制未完成功能的暴露
  • 代码审查改为事后追溯(见 §4不在合并前阻塞
  • 默认多 AI 协作,每个模块单一负责制

1.2 AI 提交流程

AI 只在当前分配的分支上执行 git addgit commit,完成后通知人类决策者合并,不推送 main。

# 1. 本地校验(强制)
pnpm run lint        # TS 服务
pnpm run typecheck   # TS 服务
cd services/api-gateway && go vet ./... && go build ./...  # Go 服务
ruff check src/      # Python 服务

# 2. 提交(遵循 Conventional Commits见 §2
git add <files>
git commit -m "feat(<scope>): <subject>"

# 3. 通知人类决策者合并
# AI 不执行 git push origin main不创建/切换/合并分支

AI 可执行git addgit commitgit statusgit loggit diffgit pull(仅同步当前分支)。

AI 禁止执行git checkout -bgit switchgit branchgit mergegit push origin maingit push --force

1.3 人类合并流程

人类决策者负责将分支合并到 main,合并时机与策略由人类决策者判断。

# 人类决策者操作AI 不执行)
# 1. 同步最新 main
git checkout main
git pull origin main

# 2. 合并分支(由人类决策者选择策略)
git merge <branch-name>          # 或 git merge --no-ff <branch-name>

# 3. 推送 main触发 CI 部署)
git push origin main

# 4. (可选)删除已合并分支
git branch -d <branch-name>

合并策略建议

  • 一般任务:git merge --no-ff(保留分支拓扑,便于追溯)
  • 紧急修复:git merge --ff-only(线性历史)
  • 大特性分支:git merge --squash(压缩为单 commit

1.4 冲突处理

  • 分支合并冲突:由人类决策者在合并分支到 main 时解决AI 不参与合并操作
  • 架构冲突:由协调 AI 仲裁,通知人类决策者保留方案后合并,通过后续 commit 修正
  • 禁止 git push --force 到 main:仅协调 AI 在事故时可 git push --force-with-lease origin main,需人类决策者确认

1.5 main 分支保护

  • 禁止 force push仅协调 AI 在事故时操作,需人类决策者确认)
  • pre-commit / commit-msg / pre-push hook 强制校验(见 §3.4
  • 不要求 PR review代码质量由本地校验 + 事后 review§4+ CIproject_rules §15保证
  • AI 无权直接 push main,所有 main 变更须经人类决策者合并

二、Conventional Commits 规范

2.1 提交信息格式

所有提交信息必须遵循 Conventional Commits 1.0.0

<type>(<scope>): <subject>

<body>

<footer>

2.2 类型type

类型 含义 是否触发发布
feat 新功能 MINOR
fix Bug 修复 PATCH
perf 性能优化 PATCH
refactor 重构(不改变行为)
style 代码风格(格式化、空白)
test 新增/修改测试
docs 文档变更
build 构建系统或依赖变更
ci CI 配置变更
chore 杂项(不修改 src 或 test
revert 回滚某次提交

2.3 范围scope

scope 必须是服务名或包名,详见 §3.3 scope-enum

示例

  • feat(identity): 实现用户注册接口
  • fix(gateway): 修复路由匹配优先级
  • perf(teaching): 优化课表查询 N+1 问题
  • docs(contracts): 补充 identity.proto 字段说明

2.4 主题subject

规则

  • 使用中文简短描述
  • 不超过 50 个字符
  • 不以句号结尾
  • 使用祈使句("实现用户注册"而非"实现了用户注册"
  • 不包含 type/scope已在前面体现

2.5 正文body

规则

  • 解释"为什么"而非"做了什么"(代码已说明做了什么)
  • 每行不超过 72 个字符
  • 使用无序列表列出关键变更点
  • 涉及 breaking change 必须在正文开头说明

示例

feat(teaching): 作业提交支持附件上传

- 新增 Attachment 聚合根,支持多文件关联
- Outbox 事件 HomeworkSubmitted 新增 attachments 字段
- BFF 接口新增 multipart/form-data 支持

BREAKING CHANGE: HomeworkSubmitted 事件 schema 变更,
消费方需升级 proto 至 v2 才能消费新事件

2.6 脚注footer

用于关联 Issue、PR、Jira 卡片:

fix(content): 修复题库导入时重复题目标题去重逻辑

Closes #123
Refs EDU-456
Reviewed-by: @reviewer-name

三、commitlint + husky 配置

3.1 安装与初始化

# 在 monorepo 根目录
pnpm add -Dw @commitlint/cli @commitlint/config-conventional husky lint-staged

# 初始化 husky
pnpm exec husky init

3.2 commitlint 配置

实际生效配置文件:仓库根 .commitlintrc.jsCommonJS

/** @type {import('@commitlint/types').UserConfig} */
module.exports = {
  extends: ["@commitlint/config-conventional"],
  rules: {
    // type 枚举
    "type-enum": [
      2,
      "always",
      [
        "feat",
        "fix",
        "perf",
        "refactor",
        "style",
        "test",
        "docs",
        "build",
        "ci",
        "chore",
        "revert",
      ],
    ],
    // type 小写
    "type-case": [2, "always", "lower-case"],
    // type 不能为空
    "type-empty": [2, "never"],
    // scope 枚举(见 3.3,与 .commitlintrc.js 保持同步)
    "scope-enum": [
      2,
      "always",
      [
        // 网关层Go
        "api-gateway",
        "push-gateway",
        // 业务微服务NestJS / FastAPI
        "iam",
        "core-edu",
        "classes",
        "content",
        "data-ana",
        "msg",
        "ai",
        // BFF 聚合层NestJS
        "teacher-bff",
        "student-bff",
        "parent-bff",
        // 微前端Next.js
        "teacher-portal",
        "student-portal",
        "parent-portal",
        "admin-portal",
        // 共享包packages/
        "shared-proto",
        "shared-ts",
        "shared-go",
        "shared-py",
        "shared-tokens",
        // 工具与平台级
        "arch-scan",
        "infra",
        "docs",
        "deps",
        "release",
      ],
    ],
    // scope 小写
    "scope-case": [2, "always", "lower-case"],
    // subject 不能为空
    "subject-empty": [2, "never"],
    // subject 不超过 50 字符
    "subject-max-length": [2, "always", 72],
    // subject 不以句号结尾
    "subject-full-stop": [2, "never", "."],
    // body 每行不超过 100 字符
    "body-max-line-length": [1, "always", 100],
    // footer 每行不超过 100 字符
    "footer-max-line-length": [1, "always", 100],
    // header 不超过 100 字符
    "header-max-length": [2, "always", 100],
  },
};

单一事实源:实际生效的配置在仓库根 .commitlintrc.js,本节示例仅作说明。修改 scope 必须同步更新 .commitlintrc.js 与本节,并在提交时说明原因。

3.3 scope-enum 完整清单

与仓库根 .commitlintrc.js 保持同步;修改 scope 必须同时更新此处与 .commitlintrc.js

分类 scope 对应目录 说明
网关层 api-gateway services/api-gateway/ API 网关Go + Gin
网关层 push-gateway services/push-gateway/ WebSocket 推送网关Go
业务微服务 iam services/iam/ 身份与访问管理NestJS
业务微服务 core-edu services/core-edu/ 教学核心服务NestJSOutbox + Kafka
业务微服务 classes services/classes/ 班级服务P1 黄金模板P3 并入 core-edu
业务微服务 content services/content/ 内容资源服务NestJS + Neo4j
业务微服务 data-ana services/data-ana/ 数据分析服务Python + FastAPI + ClickHouse
业务微服务 msg services/msg/ 消息通知服务NestJS + ES
业务微服务 ai services/ai/ AI 网关服务Python + FastAPI + LLM
BFF 聚合层 teacher-bff services/teacher-bff/ 教师端 BFFNestJS
BFF 聚合层 student-bff services/student-bff/ 学生端 BFF待建立
BFF 聚合层 parent-bff services/parent-bff/ 家长端 BFF待建立
微前端 teacher-portal apps/teacher-portal/ 教师端 PortalNext.js
微前端 student-portal apps/student-portal/ 学生端 Portal待建立
微前端 parent-portal apps/parent-portal/ 家长端 Portal待建立
微前端 admin-portal apps/admin-portal/ 管理端 Portal待建立
共享包 shared-proto packages/shared-proto/ protobuf 契约定义
共享包 shared-ts packages/shared-ts/ TS 共享类型与工具(待建立)
共享包 shared-go packages/shared-go/ Go 共享工具(待建立)
共享包 shared-py packages/shared-py/ Python 共享工具(待建立)
共享包 shared-tokens packages/shared-tokens/ 设计令牌(待建立)
工具 arch-scan scripts/arch-scan/ 架构元数据库扫描器
平台级 infra infra/ 基础设施K8s / docker-compose / backup / monitoring
平台级 docs docs/ 平台级文档(跨多模块)
平台级 deps - 依赖升级
平台级 release - 发布相关

chore / ci / build 等 Conventional Commits 标准 type 不需要 scope可直接使用 chore: xxxci: xxx

3.4 husky hooks

实际生效的 hook 文件在仓库根 .husky/ 目录。使用 npx --no-install 确保使用本地依赖。

.husky/commit-msg

npx --no-install commitlint --edit $1

.husky/pre-commit

npx --no-install lint-staged

.husky/pre-push推送前类型检查TS 服务 typecheck 通过后才允许推送):

#!/usr/bin/env sh
# 推送前运行类型检查TS 服务)
pnpm -r run typecheck 2>/dev/null || echo "[pre-push] typecheck 跳过或不可用"
# Go 服务编译检查
for d in services/api-gateway services/push-gateway; do
  if [ -d "$d" ]; then (cd "$d" && go build ./... ) || exit 1; fi
done

注意pre-push 中的 typecheck 在 TS 服务 ESLint 9 flat config 迁移完成前为可选(当前 pnpm -r run typecheck 缺失脚本,会 fallback 到 echo 提示。Go go build 检查必须通过。

3.5 lint-staged 配置

实际生效配置文件:仓库根 lint-staged.config.jsCommonJS

module.exports = {
  "*.{ts,tsx}": ["eslint --fix", "prettier --write"],
  "*.{go,mod,sum}": ["gofmt -w", "golangci-lint run --fix"],
  "*.{py}": ["ruff check --fix", "ruff format"],
  "*.proto": ["buf format --write"],
  "*.md": ["prettier --write"],
};

JSON / YAML 文件由 prettier 在 *.md 规则外按全局配置处理,如需显式规则可在 lint-staged.config.js 追加 '*.{json,yaml,yml}': ['prettier --write']


四、事后 Code Review

不再使用 PR 流程,代码审查改为事后追溯AI 在分支上提交后通知人类决策者合并,人类决策者合并到 main 后由模块 owner 或协调 AI 通过分支 commit history 进行 review。问题通过后续 commit 修正或 git revert 回滚。

4.1 事后 Review 流程

flowchart TD
    A[开发 AI 本地校验] --> B[分支上 git add + git commit]
    B --> C[通知人类决策者合并]
    C --> D[人类决策者合并到 main]
    D --> E[CI 自动检查]
    E --> F{CI 通过?}
    F -->|否| G[人类 git revert + 修复后重新合并]
    F -->|是| H[模块 owner 事后审查分支 commit]
    H --> I{审查通过?}
    I -->|有问题| J[后续 commit 修正或 revert]
    I -->|通过| K[review 完成]

review 依据

  • commit messageConventional Commits 格式,见 §2
  • 分支 commit history通过 git log 或平台分支/合并视图追溯)
  • commit diff通过 git log -p 或平台 commit 视图)

4.2 Code Review 清单

事后 review 时检查:

通用检查

  • 代码是否符合 编码规范
  • 是否有明显的逻辑错误
  • 错误处理是否完整(不忽略 error/err/exception
  • 日志是否包含足够的上下文request_id、user_id 等)
  • 是否存在硬编码的密钥、token、连接字符串

架构检查

  • 是否违反限界上下文边界(跨服务直接查 DB
  • 是否违反依赖方向shared 反向依赖 services
  • protobuf 变更是否向后兼容
  • 事件 schema 变更是否向后兼容

性能检查

  • 是否有 N+1 查询
  • 是否有未加索引的查询
  • 是否有不必要的大对象拷贝
  • 是否有阻塞事件循环的同步操作Python/Node

安全检查

  • 所有入口是否经过权限校验
  • 用户输入是否经过验证
  • SQL 是否使用参数化查询
  • 是否有 SQL 注入、XSS、SSRF 风险

4.3 模块 Owner 与 CODEOWNERS

实际生效文件:仓库根 .github/CODEOWNERS

不再用于自动分配 PR reviewer无 PR 流程CODEOWNERS 保留作为模块归属追溯依据:分支合并涉及某路径时,对应 owner 负责事后 review。

设计原则

  • 每个模块至少 1 名 owner核心模块 2 名
  • 跨模块变更(如 proto 契约、arch.db、project_rules由架构组事后 review
  • 基础设施变更K8s/Helm/backup由 SRE 事后 review
  • owner 名单变更通过分支提交更新,由架构组确认后人类决策者合并

模块 Owner 分配矩阵

模块分类 路径 Owner Team 备注
架构与规则 .trae/rules/docs/architecture/docs/standards/ @edu-platform/arch 架构组强制 review
架构工具 scripts/arch-scan/ @edu-platform/arch
根配置 .commitlintrc.jslint-staged.config.jspackage.jsonpnpm-workspace.yamlgo.workpyproject.tomltsconfig.base.json @edu-platform/arch 影响全局
共享包 packages/shared-proto/ @edu-platform/arch 契约变更影响所有服务
网关层 services/api-gateway/services/push-gateway/ @edu-platform/gateway
IAM 服务 services/iam/ @edu-platform/iam 核心模块
教学核心 services/core-edu/services/classes/ @edu-platform/edu-core
内容资源 services/content/ @edu-platform/content
消息通知 services/msg/ @edu-platform/messaging
数据分析 services/data-ana/ @edu-platform/data
AI 服务 services/ai/ @edu-platform/ai
BFF 层 services/teacher-bff/services/student-bff/services/parent-bff/ @edu-platform/edu-core
微前端 apps/teacher-portal/apps/student-portal/apps/parent-portal/apps/admin-portal/ @edu-platform/frontend
基础设施 infra/k8s/infra/backup/infra/security/infra/monitoring/ @edu-platform/sre 生产环境变更
CI/CD .github/.husky/ @edu-platform/sre
文档 docs/troubleshooting/docs/standards/ @edu-platform/arch known-issues 更新

Team handle 占位符:上表 @edu-platform/* 为 team handle 模板。实际团队 handle 需在 GitHub/Gitea Organization 中创建对应 team 后,同步更新 .github/CODEOWNERS

CODEOWNERS 文件维护规则

  1. 新增服务/包时,必须同步更新 .github/CODEOWNERS
  2. owner 变更(人员调动)由架构组确认后通过分支提交更新
  3. CODEOWNERS 与本节表格保持同步,单一事实源为 .github/CODEOWNERS 文件

五、文档同步规则

5.1 文档同步矩阵

代码变更类型 需同步的文档 同步时机
新增/删除服务 001_architecture_overview.md + 服务 README 分支内同步
新增/删除模块 服务 README + arch:scan 分支内同步
新增/删除导出函数 pnpm run arch:scan 提交前
修改函数签名 pnpm run arch:scan 提交前
修改权限点 project_rules.md + 权限文档 分支内同步
新增/删除数据库表 架构文档 + 服务 README 分支内同步
新增/删除路由 服务 README + OpenAPI 分支内同步
修改模块间依赖 arch:scan + 架构文档 分支内同步
新增 protobuf message proto/ README + arch:scan 分支内同步
新增 Kafka topic 架构文档 + 服务 README 分支内同步
遇到新问题/经验 known-issues.md 分支内同步

5.2 arch.db 同步规则

强制规则:任何代码变更提交前必须运行 pnpm run arch:scan 更新 arch.db。

# 提交前流程
pnpm run arch:scan          # 更新 arch.db
pnpm run arch:query -- violations  # 检查是否有违规
git add arch.db              # 将 arch.db 纳入提交
git commit -m "feat(identity): 实现用户注册接口"

违规检查

  • 长文件(> 1000 行)
  • 未校验权限的 Handler
  • 循环依赖
  • 跨限界上下文直接 DB 访问

5.3 服务 README 要求

每个服务必须包含 README.md,结构如下:

# [服务名] 服务

> 版本1.0
> 限界上下文:[上下文名]
> 技术栈:[语言 + 框架]

## 职责

[一段话描述]

## 架构

[mermaid 架构图]

## 核心流程

[mermaid 时序图]

## 目录结构

[树形结构 + 说明]

## 依赖

- 上游服务:[列表]
- 下游服务:[列表]
- 共享包:[列表]

## 约束

[业务规则、技术约束]

## 架构决策

[关键设计决策记录]

5.4 known-issues.md 格式

docs/troubleshooting/known-issues.md 采用索引式速查手册格式:

### X.X 主题分区

| 场景     | 技术/规则          |
| -------- | ------------------ |
| 简述场景 | 正确做法(一句话) |

规则

  • 索引式:场景→技术/规则映射
  • 不写代码示例和错误示范
  • 同类问题在原条目补充,不重复创建
  • 不设"工作经验日志"区:模块内经验沉淀在各自服务 READMEknown-issues 只保留索引式场景→技术映射(见 project_rules §9
  • 经验沉淀不标注 AI 身份AI 只做经验沉淀(场景→技术映射),不记录工作日志,不标注 AI 身份

六、多语言 monorepo 提交规则

6.1 单服务单提交原则

规则:一个 commit 只涉及一个服务或一个包的变更。

原因

  • 便于回滚(按服务粒度回滚)
  • 便于追踪changelog 清晰)
  • 便于 review聚焦单一职责

例外:跨服务重构或契约变更可在同一 commit 中涉及多个服务,但需在 body 中说明。

6.2 生成代码单独提交

规则protobuf 生成的代码必须与手写代码分开提交。

# 正确流程
# 1. 修改 proto 定义
git commit -m "feat(proto): 新增 UserRegistered 事件 schema"

# 2. 生成代码
pnpm run proto:generate

# 3. 单独提交生成代码
git commit -m "build(contracts): 重新生成 proto 代码"

6.3 跨语言变更拆分

当一个功能涉及多个语言(如 TS 服务 + Go 网关 + Python AI按以下顺序拆分提交

  1. 契约先行feat(proto): ...
  2. 生成代码build(contracts): ...
  3. 后端服务feat(teaching): ...
  4. 网关层feat(gateway): ...
  5. 前端feat(teacher-shell): ...

6.4 依赖升级规则

规则

  • 依赖升级使用 build(deps): 类型
  • 必须说明升级原因(安全、功能、兼容性)
  • 安全漏洞修复必须包含 CVE 编号
  • 大版本升级需单独分支并完整测试

示例

build(deps): 升级 nestjs 至 10.3.0

- 修复 CVE-2024-1234 漏洞
- 升级至最新 patch 版本
- 全部测试通过

6.5 跨服务依赖更新

当一个服务的 protobuf 变更影响其他服务:

# 1. 提交 proto 变更
git commit -m "feat(proto): UserRegistered 事件新增 attachments 字段"

# 2. 生成新契约
pnpm run proto:generate
git commit -m "build(contracts): 生成 UserRegistered v2"

# 3. 更新消费方服务
git commit -m "feat(notification): 适配 UserRegistered v2 事件"

七、版本管理

不使用 tag 发布与 release 分支(见 project_rules §15.3 no-push 模式)。版本通过 commit SHA 追溯,发布由人类决策者合并分支到 main 后触发 CI 自动部署。

7.1 版本号体系

本项目采用双层版本号(仅作记录与沟通用,不通过 git tag 标记):

层级 格式 说明
平台版本 v{阶段}.{迭代}.{patch} v0.3.1P3 阶段第 1 次迭代 patch 1
服务版本 {service}:{semver} identity:1.2.0

7.2 阶段版本范围

阶段 平台版本范围 说明
P1 地基 v0.1.x monorepo 初始化、CI/CD、arch.db
P2 身份 v0.2.x identity + auth + notification
P3 核心教学 v0.3.x org + teaching + content
P4 内容分析 v0.4.x insight + CQRS 读模型
P5 沟通AI v0.5.x comm + AI 增强
P6 硬化 v1.0.x 正式发布版

7.3 Docker 镜像标签

no-push 模式下镜像不推 registry本地构建本地使用见 project_rules §15.4)。下表标签格式仅用于本地镜像管理。

格式{registry}/edu/{service}:{tag}

tag 类型 格式 示例 用途
Git SHA sha-{short} sha-a1b2c3d 精确追溯
最新 latest latest 开发环境
服务版本 {service}-{semver} identity-1.2.0 服务独立版本

7.4 发布流程

flowchart TD
    A[开发 AI 本地校验通过] --> B[分支上 git add + git commit]
    B --> C[通知人类决策者合并]
    C --> D[人类决策者合并到 main]
    D --> E[CI 自动触发 quality + deploy]
    E --> F{CI 通过?}
    F -->|否| G[人类 git revert + 修复后重新合并]
    G --> D
    F -->|是| H[部署至目标环境]
    H --> I[健康检查轮询 /healthz]
    I --> J{健康?}
    J -->|否| K[输出容器日志 + 紧急回滚 §8]
    J -->|是| L[发布完成]
    L --> M[更新 CHANGELOG.md]

不创建 release 分支、不打 git tag。发布点通过 commit SHA 追溯,回滚通过 git revertworkflow_dispatch 指定 commit_sha(见 project_rules §15.4)。

7.5 CHANGELOG 格式

CHANGELOG.mdKeep a Changelog 格式维护,版本号对应阶段迭代(不绑定 git tag

## [v0.3.0] - 2026-08-15

### Added

- 教学核心服务新增作业管理功能
- 内容服务支持题库导入
- 教师端 Shell 新增作业批改界面

### Changed

- identity 服务升级至 NestJS 10.3
- gateway 路由匹配算法优化

### Fixed

- 修复 JWT 刷新 token 过期判断错误
- 修复课表查询时区问题

### Breaking Changes

- UserRegistered 事件 schema 变更至 v2消费方需升级

7.6 服务独立版本

每个服务维护独立的 VERSION 文件,内容为 semver

# services/identity/VERSION
1.2.0

版本号升级规则

  • MAJORBreaking Changeprotobuf 不兼容变更、API 破坏性修改)
  • MINOR:新增功能,向后兼容
  • PATCHBug 修复,向后兼容

八、紧急回滚

8.1 回滚策略

场景 回滚方式 耗时
代码缺陷 人类在 main 上 git revert + push 触发 CI 重新部署 5-10 分钟
镜像问题 kubectl rollout undo 1-2 分钟
数据库迁移问题 执行迁移 down 脚本 5-30 分钟
配置错误 回滚 ConfigMap/Secret 1-2 分钟
全站故障 workflow_dispatch 指定稳定 commit_sha 10-30 分钟

8.2 代码回滚

不创建 hotfix 分支。由人类决策者在 main 上 git revert 后 pushCI 自动重新部署。AI 不参与 main 上的回滚推送操作。

# 人类决策者操作AI 不执行 push main
# 1. 确认要回滚的 commit
git log --oneline -10

# 2. 切换到 main 并拉取最新
git checkout main
git pull origin main

# 3. 回滚指定 commit生成反向 commit
git revert <commit-sha>

# 4. push mainCI 自动触发重新部署)
git push origin main

修复型回滚也可通过新分支提交修复后由人类决策者合并,具体方式由人类决策者判断。

8.3 K8s 部署回滚

# 查看部署历史
kubectl rollout history deployment/identity -n edu-prod

# 回滚至上一版本
kubectl rollout undo deployment/identity -n edu-prod

# 回滚至指定版本
kubectl rollout undo deployment/identity -n edu-prod --to-revision=3

# 监控回滚状态
kubectl rollout status deployment/identity -n edu-prod

8.4 数据库迁移回滚

规则

  • 所有迁移必须提供 updown 脚本
  • down 脚本必须在 CI 中测试
  • 回滚前必须备份生产数据
# 回滚最近一次迁移
pnpm --filter identity run migrate:down

# 回滚至指定版本
pnpm --filter identity run migrate:down -- --to <version>

8.5 回滚原则

  1. 优先保证可用性:回滚决策应在 5 分钟内做出,无需 root cause
  2. 保留现场回滚前保存日志、metrics、错误堆栈
  3. 通知相关方:回滚后立即通知运维、产品、相关开发
  4. 复盘改进:回滚后 24 小时内完成事故复盘,记录至 docs/troubleshooting/incidents/

8.6 回滚记录格式

docs/troubleshooting/incidents/YYYY-MM-DD-incident.md

# 事故记录:[简述]

> 日期YYYY-MM-DD
> 影响范围:[服务/用户]
> 持续时间:[开始-结束]
> 严重等级P0/P1/P2/P3

## 时间线

- HH:MM 告警触发
- HH:MM 确认问题
- HH:MM 决定回滚
- HH:MM 回滚完成
- HH:MM 服务恢复

## 影响分析

[受影响的功能、用户数、业务损失]

## 根本原因

[技术原因 + 流程原因]

## 回滚过程

[执行的操作]

## 改进措施

- [ ] 短期:[立即修复项]
- [ ] 中期:[流程改进项]
- [ ] 长期:[架构改进项]

九、附录CICD 与 Edu Git 工作流差异

维度 CICDNext.js 单应用) Edu微服务 monorepo
仓库结构 单一 Next.js 应用 多语言 monorepopnpm + go.work + uv
分支策略 trunk-based 分支开发AI 不切换分支,人类维护
提交规范 Conventional Commits Conventional Commits沿用scope 扩展至服务/包)
scope 范围 模块名(如 examshomework 服务/包名(如 iamapi-gatewayshared-proto
commitlint scope-enum 35 个模块 26 个 scope含服务/包/工具/平台级,与 .commitlintrc.js 同步)
代码审查 PR Reviewer 1 人 事后 review(无 PR通过分支 commit history 追溯)
合并策略 Squash Merge 人类决策者手动合并分支到 mainAI 不合并)
版本号 单一应用版本 双层(平台版本 + 服务独立版本,仅记录不打 tag
发布粒度 整体发布 按服务独立发布
Docker 镜像 单一镜像 每服务一镜像no-push 本地构建,见 project_rules §15
回滚粒度 整体回滚 按服务回滚
数据库迁移 Drizzle 单库 每服务独立库 + 独立迁移
文档同步 npm run arch:scan pnpm run arch:scan(多语言扫描)
CI 检查 lint + tsc + test lint + typecheck + test按语言分别执行
紧急回滚 git revert + 重新部署 人类在 main 上 git revert + push 触发 CIworkflow_dispatch 指定 SHA
事故复盘 known-issues.md incidents/ 目录独立记录

变更记录

版本 日期 变更内容
1.0 2026-07-07 基线发布,从 CICD 单应用规范迁移至微服务多语言 monorepo
1.1 2026-07-08 scope-enum 对齐实际服务名identity→iam、teaching→core-edu 等);新增 §4.7 模块 Owner 与 CODEOWNERShusky hooks 与实际文件对齐;新增 pre-push hook 说明
1.2 2026-07-10 因 Gitea 问题移除分支/PR 流程§1 改为直接 push main移除特性/发布/hotfix 分支命名与保护§4 改为事后 Code Review移除 PR 流程/标题/模板/合并策略,保留 Code Review 清单与 CODEOWNERS 追溯§7 改为版本管理(移除 release 分支与 tag 发布,用 commit SHA 追溯§8 移除 hotfix 分支回滚,改为直接 git revert + push main§9 更新差异表
1.3 2026-07-10 恢复分支开发模式AI 不切换分支§1 改为分支开发人类决策者维护分支AI 禁止 git checkout -b/git switch/git branch/git merge/git push origin mainAI 只做 git addgit commit→通知人类合并§4 review 依据改为分支 commit history移除 AI 身份标注§8 回滚由人类在 main 上 git revert,不使用 hotfix 分支§9 分支策略改为"分支开发AI 不切换分支,人类维护"§5.4 经验沉淀不标注 AI 身份