# 发布管理与更新日志规范

> **最后更新**: 2026-05-10
>
> 本文件讲发布管理「制度面」（版本号 / 更新日志 / hotfix 走法）。CI/CD pipeline 实施细节见 [docs/ops/02-ci-cd-architecture.md](../ops/02-ci-cd-architecture.md)。

---

## 版本号规范

格式：`v主版本.次版本.修订号`（如 v1.2.3）

| 类型 | 何时升级 | 示例 |
|------|---------|------|
| **主版本号** | 重大功能上线、架构升级、可能不向下兼容 | v1.0.0 → v2.0.0 |
| **次版本号** | 新增功能模块，向下兼容 | v1.0.0 → v1.1.0 |
| **修订号** | Bug 修复、小优化 | v1.0.0 → v1.0.1 |

> **当前现状**：仓库还**没有打过 `v*` tag**，部署也未自动化打 tag。版本号规范留作发布需要时启用——典型触发是要做版本回滚或对外公告。要启用，需要在 `deploy-production.yml` 加 tag step（`git tag -a v$VERSION -m ... && git push origin v$VERSION`），并在更新日志里同步标注。

---

## 更新日志格式

每次发布时填写，**面向用户**，使用用户能理解的语言，**不包含技术实现细节**。

必填字段：版本号、更新标题、发布日期（MM/DD/YYYY）、上线环境（UAT / 生产）、更新内容。

分类标签：`【新增功能】` / `【功能优化】` / `【问题修复】` / `【性能优化】` / `【其他】`

> 更新日志当前未制度化输出。日常工程级别的变更走 git commit message + PR title（约定式提交，主题用中文）；面向业务的更新日志在版本发布时按本规范单独整理。

---

## 发布流程

### 常规发布链路

```
develop ──PR──→ staging ──PR──→ production
   │              │                │
   │              │                └─ push 触发 deploy-production.yml
   │              └─ push 触发 deploy-uat.yml
   └─ push 触发 deploy-test.yml（不参与发布链路，是 L2 整体效果环境）
```

每一步都通过 PR + Gitea 上 squash merge（保 develop 历史线干净），不允许直推保护分支。具体门禁见 [docs/standards/05-development-workflow.md §555 分支准入规则](./05-development-workflow.md#分支准入规则)。

### Hotfix（紧急修复）

从 `production` 拉 `hotfix/*` 分支：

```bash
git switch production && git pull --ff-only origin production
git switch -c hotfix/<task>
# ... 改代码 / commit
git push origin hotfix/<task>
# 开 PR：hotfix/<task> → production
```

合并到 `production` 后，**当天必须**开一个 `hotfix-backport/<task> → develop` 的 PR，把同样的修复回灌到 develop（squash merge），否则下次 `develop → staging` FF 会失败。

```bash
git switch develop && git pull --ff-only origin develop
git switch -c hotfix-backport/<task>
# cherry-pick 或重新实现 hotfix 改动（注意：hotfix 在 production 上是 squash commit，
# 直接 cherry-pick 拿到的是合并后的最终 diff）
git cherry-pick <hotfix-squash-sha>   # 或手工编辑
git push origin hotfix-backport/<task>
# 开 PR：hotfix-backport/<task> → develop，squash merge
```

之后通过正常 FF 链路：develop → staging → production，逐级把 backport 推上去。

**注意**：hotfix 直接进 production 会暂时破坏 staging/production 与 develop 的 FF 链路（production 上 hotfix commit 的 SHA 跟 develop 上 backport commit 的 SHA 不同）。下次 `staging → production` FF 时如果失败，需要类似初次 FF-only 上线时做一次小幅强制对齐——这是 hotfix-to-production break-glass 路径的固有代价，**不要为此避免使用 hotfix**，但常规修复优先走 `hotfix/* → develop` → 正常 FF 链路。

### PR 拆分准则（按主题与风险，不按规模）

**拆 PR 看的是主题数和风险等级，不是文件数、commit 数或时间。** 单一事实源在 [CLAUDE.md § "PR 拆分准则"](../../CLAUDE.md)，本段只摘要：

- **默认不拆**——AI 节奏下拆 PR 的切换成本超过收益。
- **拆 PR 的两条硬触发**：
  1. PR 包含 ≥ 2 个**无关主题**（commit message 一句话讲不清干啥）→ 按主题拆
  2. **高风险路径**（`prisma/schema/**` / `docs/standards/**` / `CLAUDE.md` / `AGENTS.md` / `.gitea/workflows/**` / API 契约面 / 性能热路径）→ 单独 PR
- **规模不是信号**——单一主题的大 PR 接受。废弃旧阈值：~~≥ 5 commits~~ / ~~≥ 8 文件~~ / ~~≥ 1 小时~~。
- 仍不要每个 commit 一个 PR——多 commit 在同一主题下批量进同一 PR 是正确做法。
- 合并默认 **squash**。
- **rolling 分支**（如 `chore/notes-rolling`）专门收纳 `.learnings/` 笔记，定期批量 PR——中立内容 + 高频小更新场景适合 batching，跟功能 PR 不同。

### 分支生命周期

- 一个分支只做一件事，PR merge 后立即删
- 本地：`git branch -D <task>`
- 远端：Gitea 仓库设置已开 auto-delete-on-merge
- 本机一次性配置：`git config --global fetch.prune true`（每次 fetch 自动清远端已删的本地 tracking ref）
- 周期性兜底：`bash scripts/dev/sweep-stale-branches.sh` 找 `: gone]` 分支批量清

详见 [docs/standards/05-development-workflow.md §「分支生命周期与四道防线」](./05-development-workflow.md)。

---

## 相关文档

- [CI/CD 架构](../ops/02-ci-cd-architecture.md) — workflow 编排实施
- [开发工作流](./05-development-workflow.md) — 四层模型 + 测试金字塔 + 分支门禁
- [运维策略](../ops/03-ops-policy.md) — 备份 / 故障 / 监控
- [服务器基础设施](../ops/01-server-infrastructure.md) — 主机 / 端口 / 容器
