Files
ctms/docs/guides/branch-maintenance-sop-zh.md
T
Cheng Zhou 795e0a75ca
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled
build(release): simplify v0.1.0 visible assets
2026-07-17 12:40:16 +08:00

15 KiB
Raw Blame History

CTMS 分支维护与版本更新标准操作规程

一、目的

本规程用于统一 CTMS 网页端和桌面端的代码提交、分支维护、版本晋级、正式发布及生产热修复流程。

CTMS 网页端和桌面端属于同一个产品,必须共用:

  • 同一个代码仓库
  • 同一套业务核心代码
  • 同一条版本晋级链路
  • 同一个语义化版本号
  • 同一个正式发布标签
  • 同一个源代码提交

不得为网页端和桌面端分别建立长期开发、测试或发布分支。

二、长期分支职责

分支 职责 允许进入的内容 稳定性要求
dev 日常开发与集成 已评审的功能、修复和重构 可持续集成
main 下一正式版本候选 dev 晋级的完整版本范围、候选版本修复 原则上可部署
release 当前生产稳定版本 main 验收通过的正式版本、生产热修复 最高

默认晋级方向:

功能分支 -> dev -> main -> release -> 正式版本标签

禁止以下长期分支:

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 创建分支

git fetch origin
git switch dev
git pull --ff-only origin dev
git switch -c feature/<功能名称>

不得从旧功能分支、mainrelease 创建普通功能分支。

2. 开发过程中同步 dev

短期分支优先使用变基保持提交清晰:

git fetch origin
git rebase origin/dev

已经由多人共同使用的分支,不得擅自强制推送。此时可使用合并:

git fetch origin
git merge origin/dev

3. 提交前检查

前端或桌面端改动至少执行:

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 执行:

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。

v0.1.0 额外批准 GitHub Actions 额度不可用时的分阶段应急路径:先在受控 macOS 主机从最终、不可移动的 v0.1.0 tag/SHA 本地构建 macOS ad-hoc 制品,面向安装用户的 GitHub Release 只保留 DMG 与仅覆盖该安装包的 checksum,平台未签名警告和 Windows pending 状态写入 Release Notes。macOS updater 包及 .sig、完整 checksum、provenance、风险说明和 Windows pending 证据必须保存在被 Git 忽略的私有发布目录;Windows 恢复后必须从同一 tag/SHA 后补,并在联合验证通过后把 updater 制品发布到可匿名读取的独立 HTTPS 更新源。macOS 先行阶段不得发布或替换生产 latest.json,联合 feed 必须等待 Windows NotSigned 实物验证完成。

后端改动应补充执行受影响模块的后端测试、迁移检查和接口回归。

4. 创建提交

只暂存本次任务相关文件:

git status
git add <本次任务相关文件>
git diff --cached
git diff --cached --check
git commit -m "<类型>(<范围>): <变更说明>"

推荐提交类型:

类型 用途
feat 新功能
fix 缺陷修复
refactor 不改变业务行为的重构
test 测试调整
docs 文档调整
build 构建和依赖调整
ci 持续集成调整

示例:

feat(desktop): 增加原生文件选择适配器
fix(auth): 修复会话超时后的重复跳转
refactor(client): 统一网页端和桌面端运行时入口

一次提交只处理一个明确目的。不得将无关格式化、个人配置或临时产物混入提交。

5. 推送并创建合并请求

git push -u origin feature/<功能名称>

创建:

feature/<功能名称> -> dev

合并要求:

  • 代码评审通过
  • 必要测试通过
  • 客户端质量门禁通过
  • 没有误提交密钥、环境文件或构建产物
  • 桌面能力符合第一阶段或第二阶段边界

功能分支进入 dev 可使用合并请求合并或变基合并。提交过于零散时应先整理。

6. 合并后清理

确认改动已经进入远程 dev 后删除临时分支:

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 完成集成后,创建:

dev -> main

进入 main 前必须确认:

  • 本版本范围已经冻结
  • 未完成功能已经排除或关闭入口
  • 前后端测试通过
  • 网页端构建通过
  • macOS 桌面端构建通过
  • Windows x64 NSIS 兼容性构建通过;正式发布时平台签名和时间戳验证通过,或当前精确版本的已批准平台签名例外验证通过
  • 数据库迁移经过验证
  • 已知风险和回滚方式已记录

正式创建晋级合并请求前,应按照第七节完成统一版本号更新,并确保版本提交已经进入 dev

按照当前仓库治理规则,dev 进入 main 使用压缩合并,并使用版本候选级提交说明:

release(main): 准备 v1.2.0 候选版本

不得从功能分支直接跳过 dev 合并到 main

七、统一更新客户端版本

网页端和桌面端只能使用同一个产品版本号。

从最新 dev 创建发布准备分支:

git fetch origin
git switch dev
git pull --ff-only origin dev
git switch -c release-prep/v1.2.0

统一更新版本并提交:

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

候选版本验收通过后,创建:

main -> release

按照当前仓库治理规则,使用普通合并提交,保留候选版本与生产版本之间的关系。

合并前必须确认:

  • 回归测试通过
  • 数据库迁移和回滚方案确认
  • 网页端生产构建通过
  • macOS 与 Windows 桌面端生产构建均从候选 tag 通过
  • 发布说明完成
  • 生产配置和密钥不在仓库中
  • 正式版本号已经统一

合并后立即在 release 的准确提交上创建标签:

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,并在 Release Notes、私有发布证据、完整 updater checksum 和 provenance 中记录 UNSIGNED-PLATFORM 风险;面向安装用户的 Release 可按精确版本策略只显示安装包与安装包 checksum,但 updater 制品及验证证据必须保留,之后才能最后原子替换生产 latest.json

若执行 v0.1.0 的已批准分阶段应急路径,首次 macOS Release 可先于 Windows 发布,但 tag/SHA 不得移动;GitHub Release 只保留 DMG、仅覆盖该 DMG 的 checksum 和 GitHub 自动提供的源码归档,并在 Release Notes 中明确标记未签名风险与 Windows pending。updater 包、.sig、完整 checksum、provenance 和说明文件必须在私有发布目录留存。Windows 后补且联合 feed 验证通过后,才允许把这些 updater 制品发布到独立匿名 HTTPS 更新源并按上述顺序激活生产 updater feed。

发布记录至少包含:

  • 产品版本号
  • Git 标签
  • 完整提交编号
  • 网页端制品编号
  • 桌面端制品编号
  • 数据库迁移版本
  • 发布日期和负责人

九、生产热修复流程

1. 从 release 创建热修复分支

git fetch origin
git switch release
git pull --ff-only origin release
git switch -c hotfix/<问题名称>

热修复只能包含解决生产问题所需的最小改动,不得顺带加入新功能或大规模重构。

2. 更新修订版本

例如从 1.2.0 更新到 1.2.1

cd frontend
npm run version:set -- 1.2.1
npm run version:check
cd ..

3. 验证并提交

git add <热修复相关文件和版本文件>
git diff --cached --check
git commit -m "fix(<范围>): <生产问题说明>"
git push -u origin hotfix/<问题名称>

创建:

hotfix/<问题名称> -> release

4. 合并并创建标签

热修复合并到 release 并验证后创建 v1.2.1 标签。

5. 强制回合并

生产热修复必须立即回合并:

release -> main -> dev

不得假设 maindev 已经包含相同修复。发生冲突时必须立即解决并在合并请求中记录原因。

十、冲突处理规则

发生冲突时:

  1. 先确认冲突两侧的业务意图。
  2. 不使用整文件覆盖方式跳过判断。
  3. 保留双方仍然有效的修改。
  4. 重新执行受影响测试。
  5. 在合并请求中记录冲突文件和处理结果。

禁止使用以下方式处理普通同步冲突:

git reset --hard
git checkout -- <文件>

除非已经明确确认可以丢弃本地修改,否则不得执行破坏性命令。

十一、分支保护建议

release

  • 禁止直接推送
  • 必须通过合并请求
  • 至少一名评审人批准
  • 必须通过状态检查
  • 正式标签只由发布负责人创建

main

  • 禁止直接推送
  • 必须通过合并请求
  • 必须完成回归和构建检查
  • 只接收版本候选内容

dev

  • 优先通过合并请求
  • 必须通过相关测试
  • 禁止提交密钥和本地配置
  • 禁止合入明确不可构建的代码

十二、每周分支维护

每周至少执行一次:

git fetch --prune origin
git branch -vv
git log --oneline --decorate --graph --all -30

检查事项:

  • 已合并临时分支是否删除
  • 是否出现未经批准的长期平台分支
  • devmainrelease 是否符合各自职责
  • 生产热修复是否已回合并到 maindev
  • 版本文件是否一致
  • 正式标签是否准确指向 release
  • 持续集成门禁是否持续通过

十三、禁止事项

  • 禁止长期维护网页端和桌面端平行分支
  • 禁止通过复制代码维护桌面端业务页面
  • 禁止在业务模块中直接使用 Tauri API
  • 禁止在不同提交上构建同一版本的网页端和桌面端
  • 禁止未经 devmain 直接向 release 发布普通功能
  • 禁止生产热修复只进入 release 而不回合并
  • 禁止在正式构建中包含未提交文件
  • 禁止提交 .env、密钥、证书、令牌和个人配置
  • 禁止提交 node_modulesdist、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 获批例外且 Release Notes、私有 UNSIGNED-PLATFORM 证据、provenance 和完整 updater checksum 齐备;若 GitHub Release 采用 installer-only profile,公开 checksum 只覆盖公开安装包
  • 数据库迁移与回滚方案确认
  • 发布说明完成
  • main -> release 合并完成
  • 正式标签创建在准确的 release 提交上
  • 网页端和桌面端从同一标签构建
  • 发布记录包含版本、标签和完整提交编号

十五、流程速查

普通功能:

最新 dev
  -> feature/*
  -> 开发、测试、评审
  -> dev
  -> 删除临时分支

正式发布:

dev
  -> main
  -> 统一版本号
  -> 回归与验收
  -> release
  -> 创建 vX.Y.Z 标签
  -> 同一标签构建网页端和桌面端

生产热修复:

release
  -> hotfix/*
  -> release
  -> 创建修订版本标签
  -> main
  -> dev