# 发布与收尾

> 不管客户的流程是什么，都要发布你验证过的那个版本，想好怎么撤销，并让文档如实反映现状。

部署与发布 · /zh/release-mgmt/ · 2026-11-05

## 1. 准备发布记录

**Codex**

```text
$neutron:release-check 为 [release 分支] 上的 [发布版本] 准备发布记录。生产环境当前运行的是 [上一个生产版本的 commit]。
通过已连接的 Jira MCP 或已认证的 acli，读取 Jira Fix Version 里的每个 ticket，包括验收标准和评论。把 ticket 和已合并的 PR 双向核对，并阅读仓库里的发布 runbook。从 main 合并进来的补丁版本 ticket 是预期之内的，单独列出。无法访问 Jira 时，向我要 ticket 列表和粘贴的详情。
报告每一处对不上的地方、验证缺口、测过的 artifact，以及每一项数据库迁移、配置、定时任务或外部调用的变更和它的撤销方式。
不要部署，也不要改动任何环境。
```

**Claude Code**

```text
/release-check 为 [release 分支] 上的 [发布版本] 准备发布记录。生产环境当前运行的是 [上一个生产版本的 commit]。
通过已连接的 Jira MCP 或已认证的 acli，读取 Jira Fix Version 里的每个 ticket，包括验收标准和评论。把 ticket 和已合并的 PR 双向核对，并阅读仓库里的发布 runbook。从 main 合并进来的补丁版本 ticket 是预期之内的，单独列出。无法访问 Jira 时，向我要 ticket 列表和粘贴的详情。
报告每一处对不上的地方、验证缺口、测过的 artifact，以及每一项数据库迁移、配置、定时任务或外部调用的变更和它的撤销方式。
不要部署，也不要改动任何环境。
```

- 接着[代码评审](/zh/code-review/)交接的内容往下做：已合并的 ticket、剩下的检查和恢复说明。
- 验证之前，和 PM 一起处理每一处不一致：ticket 没有已合并的 PR，就做完它或把它移出版本；改动没有 ticket，就补建 ticket，或者[重建候选版本](/zh/branching-strategy/#remove-a-ticket-by-rebuilding-the-candidate)把它拿掉。
- 对照实际 diff 核对 agent 的总结；每个跳过的测试、每个只报告、不拦截的扫描，都要说明原因。

* **REL-8** (高风险; 由代码评审检查): **release 分支里的 ticket 与 Jira Fix Version 完全一致，不多也不少。** 唯一的例外是通过合并 `main` 带进来的补丁版本 ticket。验证之前，把已合并的 PR 和 ticket 双向核对，先解决所有对不上的地方。
* **REL-5** (高风险; 由代码评审检查): **部署的必须就是通过验证的那个 artifact。** 按 digest 或签名构建往下一个环境推。重新构建，或者对候选版本做任何改动，都需要新的证据和新的批准。

> **示例: ENG-123 · 发布记录**
>
> | 记录项   | 内容                                                                                                   |
> | ----- | ---------------------------------------------------------------------------------------------------- |
> | 版本    | `release/2.8.0`，commit `7d03f5b`；生产环境运行的是 `2.7.1`，commit `a41c9e2`。镜像 digest `sha256:9f2c…`；目标：生产环境。 |
> | 证据    | `7d03f5b` 的 CI 运行记录。CSV 内容、商户隔离和现有筛选条件已在 staging 验证。                                                 |
> | 遗留缺口  | 生产数据量下的导出耗时还没测；推到生产前解决。                                                                              |
> | 恢复    | 先暂停导出队列，再重新部署 `2.7.1` 的镜像；新增的 exports 表保留不动。导出文件一旦泄露，还要走[事故处理](/zh/incidents/)。                      |
> | 上线后检查 | 部署后 30 分钟内的导出成功率和延迟；已指定负责人。                                                                          |

## 2. 规划每项改动怎么撤销

- **REL-6** (高风险; 由代码评审检查): **部署前为每项改动规划恢复方式。** 写清怎么撤销、由谁决定。代码回滚撤销不了数据库迁移、数据变更、已发出的消息或支付。

| 改动          | 撤销方式                                                          | 遗留影响                                |
| ----------- | ------------------------------------------------------------- | ----------------------------------- |
| 后端代码        | 重新部署上一个 artifact。                                             | 新版本放进队列的任务，在旧代码上可能执行失败。             |
| 功能开关控制的行为   | 关掉开关，不用部署。                                                    | 开关打开期间写入的数据。                        |
| 表结构         | 回滚代码时，保留兼容的新增结构。见[数据库变更](/zh/migrations/)。                    | 已删除的数据：down 迁移找不回来。                 |
| 数据变更或回填     | 先在数据副本上测过，再修复。涉及资金或奖励的，用新的账本分录更正。                             | 改动过的行及其外部影响。                        |
| 消息、支付、合作方订单 | 回滚撤销不了。先查清每一项的结果，再在服务商允许的范围内取消或补偿，按[调查与恢复](/zh/incidents/)处理。 | 已完成、待处理或结果未知的影响。服务商受理了，不等于客户那边有了结果。 |
| 移动端构建       | 收不回来。在服务端关掉这个功能，或经过应用商店审核发布新构建。                               | 用户更新之前，已安装的构建会继续调用 API。             |

如果一项改动只能向前修复，部署前就要想好怎么控制影响，比如关闭功能或暂停新任务。

## 3. 按项目流程发布

- 审批、时间安排和部署，都按项目的发布 runbook 执行。PM 和客户、QA、开发人员确认之后，决定能不能发布。
- 审批时带上发布记录。变更申请通常要的信息它都有：版本、证据、风险和恢复方式。
- 首次上线或大版本发布之前，[SSAT](/zh/ssat/) 每一项适用的条目都要有证据。
- 只部署获批的 artifact。移动端指的是已签名的商店构建，并核对过版本、配置和分发目标。
- 紧急修复在它的补丁版本上走同样的步骤。记录可以简短，但不能不写。

场景：2.8.0 版本刚部署完。

**较差的 prompt**

```text
部署完了，检查一下生产环境是否正常。
```

**更好的 prompt**

```text
用已批准的读权限，在 [环境] 中验证 [发布版本]。
确认正在运行的版本和 artifact digest，然后在 [观察时长] 内检查 [改动的流程] 和它的成功指标。
报告你检查了什么、哪些检查没通过，以及还没完成的任务、还没有结果的合作方操作。
不要重启、回滚或修改配置。
```

原因：服务器健康不代表功能正常。先确认正在运行的版本，再看改动的流程和还没完成的工作。

- 上线后检查没通过时，停止上线，执行恢复计划，把还没解决的影响交给[调查与恢复](/zh/incidents/)。

### 发布移动端构建

- 版本号和构建号交给流水线设置。手动改的版本号可能倒退，商店会拒收，或者被更新的构建盖住。
- 测试和生产分别构建，各用自己的 app ID 和配置；提交前确认交的是哪一个。
- 把商店审核时间算进计划；已发布构建的修复同样要等审核。
- 商店支持时，先发给一小部分用户，并清楚怎么暂停发布。
- 如果项目用 OTA 更新，只推给原生代码匹配的构建。原生代码、权限或应用配置有改动，就需要发商店构建。
- 后端要对仍允许运行的每个版本保持[向后兼容](/zh/deliver-a-change/#r-api-1)；只有在用户能更新时，才调整强制更新设置。

## 4. 合并回主分支并对齐文档

- 生产验证通过后，技术负责人通过评审过的 PR 把 release 分支合并回 `main`，让新工作从线上正在运行的代码出发。
- 然后从 `main` 切一个文档分支，运行收尾 skill：

**Codex**

```text
$neutron:release-closeout 让 main 上的文档与 [发布版本] 的代码对齐；上一个生产版本的 commit 是 [上一个生产版本的 commit]。
对照文档索引和代码，逐个盘点文档文件：修正、新增、合并、移动或删除。
如果有需要改的，开一个只改文档的 PR，用表格列出每个文件、处理方式和原因；如果没有，报告检查过的文件和证据。不要合并。
```

**Claude Code**

```text
/release-closeout 让 main 上的文档与 [发布版本] 的代码对齐；上一个生产版本的 commit 是 [上一个生产版本的 commit]。
对照文档索引和代码，逐个盘点文档文件：修正、新增、合并、移动或删除。
如果有需要改的，开一个只改文档的 PR，用表格列出每个文件、处理方式和原因；如果没有，报告检查过的文件和证据。不要合并。
```

- agent 会留下计划、总结和分析文档。一份和现状对不上的文档，比没有文档更容易误导下一个 agent。直接删除，不要归档：git 历史和 ticket 会保留上下文。
- 这次发布的 diff 能看出哪些内容过时了；完整盘点能找出以前发布遗留下来的孤立文档。
- 先看 PR 里的文件表格，再看内容。这个 PR 只改文档。
- 遗留的问题在 Jira 建 ticket。什么都不用改时，把检查记录附到这次发布的 ticket 上。

* **REL-1** (中风险; 由代码评审检查): **每次发布后，让文档与 `main` 上的代码对齐。** 改正与代码不符的内容，补上缺的，必要时调整结构，删掉已经和现状无关的文档。README、runbook、`AGENTS.md` 和 `CLAUDE.md` 都包括在内。

  注意: 如果 `CLAUDE.md` 里除了 `@AGENTS.md` 还有别的内容，把多出来的部分移到 `AGENTS.md`。
* **REL-7** (中风险; 由代码评审检查): **每个文档文件都列在仓库的文档索引里，并写明用途。** 索引放在 `AGENTS.md` 或它指向的文件中。收尾时，没人说得清用途的文档要删除或合并；git 历史就是存档。
* **REL-4** (中风险; 由代码评审检查): **agent 说明文件描述的是现在怎样在这个仓库里工作。** 它们不是变更日志。过时的内容在这次收尾里删掉。
* **REL-3** (低风险; 目前没有任何检查): **先合并收尾的修正，再切下一个 release 分支**，这样新分支继承的是最新的说明。不需要修正时，记下检查过什么。

下一步：如果上线后检查没通过，或者有用户反馈问题，带着发布记录去[调查与恢复](/zh/incidents/)。
