Files
ctms/docs/guides/branch-maintenance-sop-zh.md
T
Cheng Zhou c23a5d6a22
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled
Storage Persistence Guard / storage-persistence-audit (push) Has been cancelled
Client Quality Gates / Shared client and Web (pull_request) Has been cancelled
Client Quality Gates / macOS Desktop (pull_request) Has been cancelled
Storage Persistence Guard / storage-persistence-audit (pull_request) Has been cancelled
build(desktop): allow controlled unsigned v0.1.0 release
2026-07-17 10:52:20 +08:00

495 lines
14 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.
# CTMS 分支维护与版本更新标准操作规程
## 一、目的
本规程用于统一 CTMS 网页端和桌面端的代码提交、分支维护、版本晋级、正式发布及生产热修复流程。
CTMS 网页端和桌面端属于同一个产品,必须共用:
- 同一个代码仓库
- 同一套业务核心代码
- 同一条版本晋级链路
- 同一个语义化版本号
- 同一个正式发布标签
- 同一个源代码提交
不得为网页端和桌面端分别建立长期开发、测试或发布分支。
## 二、长期分支职责
| 分支 | 职责 | 允许进入的内容 | 稳定性要求 |
| --- | --- | --- | --- |
| `dev` | 日常开发与集成 | 已评审的功能、修复和重构 | 可持续集成 |
| `main` | 下一正式版本候选 | 从 `dev` 晋级的完整版本范围、候选版本修复 | 原则上可部署 |
| `release` | 当前生产稳定版本 | 从 `main` 验收通过的正式版本、生产热修复 | 最高 |
默认晋级方向:
```text
功能分支 -> dev -> main -> release -> 正式版本标签
```
禁止以下长期分支:
```text
web-dev
desktop-dev
web-release
desktop-release
macos-main
windows-main
```
桌面端差异必须放在 `frontend/src/runtime/` 适配层之后,不通过长期分支保存平台差异。
## 三、临时分支命名
| 类型 | 命名格式 | 示例 |
| --- | --- | --- |
| 新功能 | `feature/<功能名称>` | `feature/desktop-file-picker` |
| 缺陷修复 | `fix/<问题名称>` | `fix/session-timeout` |
| 生产热修复 | `hotfix/<问题名称>` | `hotfix/login-loop` |
| 文档调整 | `docs/<文档名称>` | `docs/release-sop` |
| 发布准备 | `release-prep/<版本号>` | `release-prep/v1.2.0` |
| Agent 临时任务 | `codex/<任务名称>` | `codex/desktop-menu-polish` |
分支名称使用小写英文和连字符,不使用个人姓名、日期或模糊名称。
## 四、日常功能开发流程
### 1. 从最新 `dev` 创建分支
```bash
git fetch origin
git switch dev
git pull --ff-only origin dev
git switch -c feature/<功能名称>
```
不得从旧功能分支、`main``release` 创建普通功能分支。
### 2. 开发过程中同步 `dev`
短期分支优先使用变基保持提交清晰:
```bash
git fetch origin
git rebase origin/dev
```
已经由多人共同使用的分支,不得擅自强制推送。此时可使用合并:
```bash
git fetch origin
git merge origin/dev
```
### 3. 提交前检查
前端或桌面端改动至少执行:
```bash
cd frontend
npm run version:check
npm run runtime:check
npm run desktop:release:check
npm run ui:contract
npm run type-check
npm run test:unit
npm run build
npm run desktop:build:app
```
涉及 Tauri、macOS 打包或桌面适配层时,还必须在 macOS 执行:
```bash
npm run desktop:build:app
```
正式桌面发布构建必须从同一正式 tag 分别在 macOS 和 Windows 原生 CI job 执行。两端都必须设置 updater 签名私钥,updater 签名不可关闭。平台签名默认路径仍要求 macOS 设置 Apple 签名/公证变量并以 `REQUIRE_DESKTOP_SIGNING=true` 执行,Windows 设置 PFX、密码和 RFC 3161 时间戳变量并以 `REQUIRE_WINDOWS_SIGNING=true` 执行。只有 `frontend/desktop-release-policy.json` 对当前精确版本存在已批准例外时,workflow 才可改为 macOS ad-hoc、Windows Authenticode 未签名路径;例外制品必须标注 `UNSIGNED-PLATFORM`、生成 provenance 和风险说明。两个平台与联合 feed 校验通过后才能汇总正式 updater feed。
后端改动应补充执行受影响模块的后端测试、迁移检查和接口回归。
### 4. 创建提交
只暂存本次任务相关文件:
```bash
git status
git add <本次任务相关文件>
git diff --cached
git diff --cached --check
git commit -m "<类型>(<范围>): <变更说明>"
```
推荐提交类型:
| 类型 | 用途 |
| --- | --- |
| `feat` | 新功能 |
| `fix` | 缺陷修复 |
| `refactor` | 不改变业务行为的重构 |
| `test` | 测试调整 |
| `docs` | 文档调整 |
| `build` | 构建和依赖调整 |
| `ci` | 持续集成调整 |
示例:
```text
feat(desktop): 增加原生文件选择适配器
fix(auth): 修复会话超时后的重复跳转
refactor(client): 统一网页端和桌面端运行时入口
```
一次提交只处理一个明确目的。不得将无关格式化、个人配置或临时产物混入提交。
### 5. 推送并创建合并请求
```bash
git push -u origin feature/<功能名称>
```
创建:
```text
feature/<功能名称> -> dev
```
合并要求:
- 代码评审通过
- 必要测试通过
- 客户端质量门禁通过
- 没有误提交密钥、环境文件或构建产物
- 桌面能力符合第一阶段或第二阶段边界
功能分支进入 `dev` 可使用合并请求合并或变基合并。提交过于零散时应先整理。
### 6. 合并后清理
确认改动已经进入远程 `dev` 后删除临时分支:
```bash
git switch dev
git pull --ff-only origin dev
git branch -d feature/<功能名称>
git push origin --delete feature/<功能名称>
```
工作树正在使用的分支不能直接删除,应先切换分支或移除对应工作树。
## 五、历史桌面集成分支约束
`codex/ctms-desktop` 是第一阶段 Tauri 基线使用过的历史临时集成分支,不作为当前桌面端工作线,也不作为长期桌面主线。
当前约束:
- 不得继续向 `codex/ctms-desktop` 提交、变基或推送新的桌面端工作。
- 如本地或远程仍保留该分支,只能用于追溯历史或在确认已合入 `dev` 后删除。
- 后续桌面功能、修复、稳定化和发布准备必须从最新 `dev` 创建短期 `feature/*``fix/*``docs/*``release-prep/*``codex/*` 分支。
- Agent 创建分支默认使用 `codex/<任务名称>`,并在任务合入 `dev` 后删除。
- 如果工作区处于 detached HEAD 或包含尚未归属到分支的提交,执行分支切换、提交、推送或变基前必须先确认目标基线和处理方式。
## 六、从 `dev` 晋级到 `main`
当一个版本范围在 `dev` 完成集成后,创建:
```text
dev -> main
```
进入 `main` 前必须确认:
- 本版本范围已经冻结
- 未完成功能已经排除或关闭入口
- 前后端测试通过
- 网页端构建通过
- macOS 桌面端构建通过
- Windows x64 NSIS 兼容性构建通过;正式发布时平台签名和时间戳验证通过,或当前精确版本的已批准平台签名例外验证通过
- 数据库迁移经过验证
- 已知风险和回滚方式已记录
正式创建晋级合并请求前,应按照第七节完成统一版本号更新,并确保版本提交已经进入 `dev`
按照当前仓库治理规则,`dev` 进入 `main` 使用压缩合并,并使用版本候选级提交说明:
```text
release(main): 准备 v1.2.0 候选版本
```
不得从功能分支直接跳过 `dev` 合并到 `main`
## 七、统一更新客户端版本
网页端和桌面端只能使用同一个产品版本号。
从最新 `dev` 创建发布准备分支:
```bash
git fetch origin
git switch dev
git pull --ff-only origin dev
git switch -c release-prep/v1.2.0
```
统一更新版本并提交:
```bash
cd frontend
npm run version:set -- 1.2.0
npm run version:check
cd ..
git add frontend/package.json frontend/package-lock.json frontend/src-tauri/tauri.conf.json
git add frontend/src-tauri/Cargo.toml frontend/src-tauri/Cargo.lock
git commit -m "build(release): 更新客户端版本至 v1.2.0"
git push -u origin release-prep/v1.2.0
```
创建 `release-prep/v1.2.0 -> dev` 合并请求。合并后再执行 `dev -> main` 的版本晋级。
该命令同步更新:
- `frontend/package.json`
- `frontend/package-lock.json`
- `frontend/src-tauri/tauri.conf.json`
- `frontend/src-tauri/Cargo.toml`
- `frontend/src-tauri/Cargo.lock`
版本号遵循:
| 类型 | 示例 | 使用场景 |
| --- | --- | --- |
| 主版本 | `2.0.0` | 不兼容变更或重大架构调整 |
| 次版本 | `1.3.0` | 向后兼容的新功能 |
| 修订版本 | `1.2.1` | 向后兼容的缺陷修复 |
禁止单独设置桌面端版本号。
## 八、从 `main` 发布到 `release`
候选版本验收通过后,创建:
```text
main -> release
```
按照当前仓库治理规则,使用普通合并提交,保留候选版本与生产版本之间的关系。
合并前必须确认:
- 回归测试通过
- 数据库迁移和回滚方案确认
- 网页端生产构建通过
- macOS 与 Windows 桌面端生产构建均从候选 tag 通过
- 发布说明完成
- 生产配置和密钥不在仓库中
- 正式版本号已经统一
合并后立即在 `release` 的准确提交上创建标签:
```bash
git switch release
git pull --ff-only origin release
git tag -a v1.2.0 -m "CTMS v1.2.0"
git push origin v1.2.0
```
网页端、macOS 和 Windows 桌面端必须从同一个 `v1.2.0` 标签构建。不得从不同分支、不同提交或本地未提交状态构建正式制品。两个平台的 updater 签名制品必须始终验证通过;macOS 签名/公证和 Windows 代码签名/RFC 3161 时间戳必须验证通过,除非 `frontend/desktop-release-policy.json` 对该精确版本记录了已批准例外。采用例外时必须验证 macOS 确为 ad-hoc、Windows 确为 `NotSigned`,并随安装包分发 `UNSIGNED-PLATFORM` 风险说明、provenance 和 checksum,之后才能最后原子替换生产 `latest.json`
发布记录至少包含:
- 产品版本号
- Git 标签
- 完整提交编号
- 网页端制品编号
- 桌面端制品编号
- 数据库迁移版本
- 发布日期和负责人
## 九、生产热修复流程
### 1. 从 `release` 创建热修复分支
```bash
git fetch origin
git switch release
git pull --ff-only origin release
git switch -c hotfix/<问题名称>
```
热修复只能包含解决生产问题所需的最小改动,不得顺带加入新功能或大规模重构。
### 2. 更新修订版本
例如从 `1.2.0` 更新到 `1.2.1`
```bash
cd frontend
npm run version:set -- 1.2.1
npm run version:check
cd ..
```
### 3. 验证并提交
```bash
git add <热修复相关文件和版本文件>
git diff --cached --check
git commit -m "fix(<范围>): <生产问题说明>"
git push -u origin hotfix/<问题名称>
```
创建:
```text
hotfix/<问题名称> -> release
```
### 4. 合并并创建标签
热修复合并到 `release` 并验证后创建 `v1.2.1` 标签。
### 5. 强制回合并
生产热修复必须立即回合并:
```text
release -> main -> dev
```
不得假设 `main``dev` 已经包含相同修复。发生冲突时必须立即解决并在合并请求中记录原因。
## 十、冲突处理规则
发生冲突时:
1. 先确认冲突两侧的业务意图。
2. 不使用整文件覆盖方式跳过判断。
3. 保留双方仍然有效的修改。
4. 重新执行受影响测试。
5. 在合并请求中记录冲突文件和处理结果。
禁止使用以下方式处理普通同步冲突:
```bash
git reset --hard
git checkout -- <文件>
```
除非已经明确确认可以丢弃本地修改,否则不得执行破坏性命令。
## 十一、分支保护建议
### `release`
- 禁止直接推送
- 必须通过合并请求
- 至少一名评审人批准
- 必须通过状态检查
- 正式标签只由发布负责人创建
### `main`
- 禁止直接推送
- 必须通过合并请求
- 必须完成回归和构建检查
- 只接收版本候选内容
### `dev`
- 优先通过合并请求
- 必须通过相关测试
- 禁止提交密钥和本地配置
- 禁止合入明确不可构建的代码
## 十二、每周分支维护
每周至少执行一次:
```bash
git fetch --prune origin
git branch -vv
git log --oneline --decorate --graph --all -30
```
检查事项:
- 已合并临时分支是否删除
- 是否出现未经批准的长期平台分支
- `dev``main``release` 是否符合各自职责
- 生产热修复是否已回合并到 `main``dev`
- 版本文件是否一致
- 正式标签是否准确指向 `release`
- 持续集成门禁是否持续通过
## 十三、禁止事项
- 禁止长期维护网页端和桌面端平行分支
- 禁止通过复制代码维护桌面端业务页面
- 禁止在业务模块中直接使用 Tauri API
- 禁止在不同提交上构建同一版本的网页端和桌面端
- 禁止未经 `dev``main` 直接向 `release` 发布普通功能
- 禁止生产热修复只进入 `release` 而不回合并
- 禁止在正式构建中包含未提交文件
- 禁止提交 `.env`、密钥、证书、令牌和个人配置
- 禁止提交 `node_modules``dist`、Tauri `target` 等构建产物
## 十四、发布前最终检查清单
- [ ] 本次发布范围已经冻结
- [ ] `dev` 集成测试通过
- [ ] `main` 候选版本验收通过
- [ ] 网页端与桌面端版本一致
- [ ] `npm run version:check` 通过
- [ ] `npm run runtime:check` 通过
- [ ] `npm run desktop:release:check` 通过
- [ ] `npm run ui:contract` 通过
- [ ] `npm run type-check` 通过
- [ ] `npm run test:unit` 通过
- [ ] `npm run build` 通过
- [ ] `npm run desktop:build:app` 通过
- [ ] 正式桌面发布构建已使用 updater 签名私钥执行
- [ ] 平台签名已验证,或当前精确版本已在 `frontend/desktop-release-policy.json` 获批例外且 `UNSIGNED-PLATFORM` 风险说明、provenance 和 checksum 齐备
- [ ] 数据库迁移与回滚方案确认
- [ ] 发布说明完成
- [ ] `main -> release` 合并完成
- [ ] 正式标签创建在准确的 `release` 提交上
- [ ] 网页端和桌面端从同一标签构建
- [ ] 发布记录包含版本、标签和完整提交编号
## 十五、流程速查
普通功能:
```text
最新 dev
-> feature/*
-> 开发、测试、评审
-> dev
-> 删除临时分支
```
正式发布:
```text
dev
-> main
-> 统一版本号
-> 回归与验收
-> release
-> 创建 vX.Y.Z 标签
-> 同一标签构建网页端和桌面端
```
生产热修复:
```text
release
-> hotfix/*
-> release
-> 创建修订版本标签
-> main
-> dev
```