首页
/ Moby 项目发布流程深度解析:九周发布周期、代码冻结与 RC 候选版本机制

Moby 项目发布流程深度解析:九周发布周期、代码冻结与 RC 候选版本机制

2026-09-06 16:08:06作者:冯梦姬Eddie

本文以 project/RELEASE-PROCESS.md 为核心,完整解析 Moby(Docker 引擎的开源项目)的发布流程:九周时间盒式的发布周期、第 6 周开始的代码冻结(freeze)与 Release Candidate(RC)机制、冻结期内 master 与 RC 的并行演进策略,以及补丁发布的分支/回移(backport)配套规则。读完本文后,你将能够判断一个改动"还能不能赶上本次发布",理解 docker-vX.Y.Z 标签、docker-MAJOR.x 发布分支与 releases/versions.yaml 之间的协作关系,并在自己的贡献计划中合理安排合入时机。

一、发布范围:一次"全家桶"式版本发布

根据 RELEASE-PROCESS.md,Docker 项目的发布流程覆盖 Docker Engine、Compose、Kitematic、Machine、Swarm、Distribution、Notary 等项目,以及它们各自的底层依赖(如 libnetwork、libkv 等)。文档中明确了流程的分工:

  • RELEASE-PROCESS.md(本文主体):描述整体发布节奏——何时开发、何时冻结、何时发版;
  • PATCH-RELEASES.md:描述补丁(bugfix)发布的逐步技术细节,包括是否需要建立 release 分支、补丁的回移规则。

当前仓库是这一流程的直接载体。从 releases/versions.yaml 可以看到项目当前所处的版本状态:

docker:
  last: "29.7.2"
  next: "29.8.0"

这说明最新已发布版本是 29.7.2,下一个目标版本是 29.8.0。结合 BRANCHES-AND-TAGS.md 的说明,仓库中的各个组件拥有各自独立的版本体系:

组件 标签格式 示例
Moby 核心库 vX.Y.Z v2.0.0-beta.5
Docker Engine docker-vX.Y.Z docker-v29.1.2
API(api/ 目录,独立 Go module) api/vX.Y.Z api/v1.52.0
Client(client/ 目录,独立 Go module) client/vX.Y.Z client/v1.52.0

标签遵循类语义化版本规范:vX.Y.Z[-suffix[N]],例如 1.8.0 的首个候选版本打 v1.8.0-rc1,第二个 alpha 版本打 v1.0.0-alpha1

二、发布周期:九周时间盒(Release cycle)

Docker 项目采用基于时间的发布周期(time-based release cycle),每 9 周 发布一次。一个周期的开始日就是上一个周期的结束日——周期首尾相接,滚动前进。

周期被明确划分为两个阶段:

  1. 前 6 周:开发阶段(Development phase) 提交到任意关联项目的新功能与 bugfix 都有资格(eligible)进入下一个发布版本。但文档特别强调:此期间提交的任何改动都不保证会在本周期内合并。

  2. 第 7 周起:冻结阶段(Freeze phase),持续 3 周,详见下一节。

原图中的周期示意如下(ASCII 图完整继承自 RELEASE-PROCESS.md):

                                    Codebase              Release
Start of                            is frozen             (end of the
the Cycle                           (7th week)            9th week)
+-----------------------------------+---------------------+
|                                       |                     |
|           Development phase           |    Freeze phase     |
|                                       |                     |
+---------------------------------------+---------------------+
                   6 weeks                      3 weeks
<---------------------------------------><-------------------->

这个 6+3 的结构是整个发布流程的骨架:所有围绕"何时能提交""冻结期内改什么""补丁从哪切"的规则,都是围绕这两个阶段展开的。

三、冻结期(The freeze period)与 RC 候选版本

在周期开始后的第 6 周,代码库正式冻结(frozen),进入接近最终发布的状态,同时生成一个 Release Candidate(RC)。冻结期的目的非常明确:在正式发布前发现 bug、收集社区对 RC 状态的功能与稳定性反馈

冻结期内的关键规则(直接来自 RELEASE-PROCESS.md):

  • master 分支照常开发:冻结只针对 RC,master 继续正常的开发节奏;
  • RC 不接受任何新功能:冻结期内新 feature 一律不进 RC;
  • 有选择地 cherry-pick:当 bug 在 master 上修复后,发布负责人(release owner)会挑选(selectively)其中关键的修复,cherry-pick 到 RC 中;
  • RC 滚动更新:随着 RC 内容变化,会不断推出新的 RC 供社区测试和评审。

这个"master 不停车、RC 单独冻结"的双轨模型,正是 Moby 能够维持 9 周滚动周期的核心机制:开发不中断,发布质量靠冻结期内的定向修复与社区反馈来保证。

冻结期结束时(周期第 9 周),所有项目一起发布(released together)——呼应第一节提到的全家桶式发布范围。

四、补丁发布:从 master 直切还是走发布分支?

RELEASE-PROCESS.md 将补丁发布的逐步技术细节委托给 PATCH-RELEASES.md,其决策逻辑非常清晰:

  1. 如果 master 上没有不适合补丁发布的内容变更:patch release 可以直接从 master 分支切出;
  2. 如果 master 上已有不适合进补丁发布的变更:需要建立一条 release 分支,后续 bugfix 和补丁必须回移(backport) 到该分支。

补丁(patch)必须同时满足三个条件:

  • 不是重大功能/新功能;
  • 不破坏现有功能;
  • 是 bugfix 或小型改进。

要标记"某个针对 master 的 PR 应进入下一个补丁发布",作者或维护者需要给该 PR 打上与发布分支对应的标签:

process/cherry-pick/<BRANCH_NAME>

例如针对 docker-29.x 分支,就是 process/cherry-pick/docker-29.x

发布分支的命名与生命周期规则在 BRANCHES-AND-TAGS.md 中定义:

  • Docker Engine 的发布分支命名格式为 docker-MAJOR.x(如 docker-29.x);
  • 一条发布分支可以覆盖一整个大版本的发布周期,也可以只服务于某个小版本线(例如历史上的 26.026.1 分支);
  • 当前仓库记录的维护状态中,docker-29.x 为 Maintained(维护方为 Moby Project 维护者团队),25.0 分支仍处于维护状态直至 2026-12-04;
分支 贡献状态 说明
docker-29.x Maintained 预期维护至 docker-30.x 之后
25.0 Maintained 预期维护至 2026-12-04
docker-28.x27.x26.126.024.023.0 Unmaintained 不再接受贡献,不在安全公告范围内

分支的贡献状态定义也值得注意:Maintained 表示接受贡献与回移、在安全公告范围内;Unmaintained 则相反。这决定了补丁回移的目标分支选择。

五、发布分支的落地操作:仓库中的同步脚本

仓库在 releases/scripts/ 下提供了两个直接服务于上述发布流程的 bash 脚本,可作为发布操作的事实佐证。

5.1 sync-branch:将发布标签合入分支

sync-branch 接收一个或多个发布标签作为参数,逐个执行 git merge --no-ff 将其合入当前分支:

  • 如果合并失败且存在冲突(git diff --diff-filter=U 非空),脚本会以 git checkout "$tag_to_sync" -- '.' 以标签侧内容为准解决冲突后继续合并——即发布标签的内容优先于分支侧;
  • 所有标签合入后,脚本还会用 git merge-base --is-ancestor 逐一校验每个标签确实已成为 HEAD 的祖先,防止"合并看似成功但实际未包含某个标签"的情况。

这一"标签内容优先 + 事后祖先校验"的设计,正对应补丁发布流程中"发布分支必须完整包含目标发布内容"的要求。

5.2 unmerged-tags:找出该回移的发布标签

unmerged-tags 的用法是 unmerged-tags <RELEASE_BRANCH> <TAG>,用于计算某个标签之前(含该标签)、已合入 master 但尚未合入指定发布分支的所有 docker-v* 发布标签:

  1. 先校验标签存在,若标签已在发布分支中则直接退出(幂等);
  2. 确认标签在 master(优先 upstream/master)中;
  3. 通过 git tag --merged "$master" --no-merged "$release_branch" --sort=v:refname 'docker-v*' 按版本号排序列出候选标签,并用 awk 截断到指定标签为止。

它输出的正是需要执行 cherry-pick/backport 操作的标签清单,是第四节"回移"规则的具体执行入口。

5.3 版本号如何进入构建:hack/make.sh

构建侧的入口 hack/make.sh 展示了标签与构建版本的衔接:默认 VERSION=dev,但会优先从 GIT_CEILING 检查出的 git ref 推导——refs/tags/docker-v* 会剥离 docker-v 前缀作为版本,refs/tags/v* 剥离 v 前缀。这与 BRANCHES-AND-TAGS.mddocker-vX.Y.Z 的 Engine 标签格式完全对应:发布时打的标签,直接决定了构建产物的版本号

六、如何在冻结日前最大化合入概率?

RELEASE-PROCESS.md 给出了四条实操建议。首先要接受前提:任何特定改动都没有合入保证,但以下行为能显著提高概率:

  1. 对齐 Roadmap:团队优先评审与路线图一致的 PR。仓库根目录的 ROADMAP.md 就是该文档的实例——当前路线图的优先级包括运行时改进(向 containerd 收敛)、BuildKit 集成的镜像构建器、Rootless 模式、测试体系(integration-cli 向 integration 迁移)以及内部解耦等;
  2. 尽早开 PR:PR 开开得越早,维护者可用的评审时间越充裕。文档明确指出:在冻结日前一天才开的 PR,几乎不可能赶上本次发布;
  3. 与保持者持续沟通:通过邮件列表、IRC、GitHub issue 等渠道,在动手实现前就拿到设计层面的早期反馈,通常能显著缩短改动集的讨论周期;
  4. 代码质量达标:代码有注释、测试充分、并完整遵循 CONTRIBUTING 指南 的每一条规则——这能直接加快评审速度。

七、例外情况:发布延期(Pushed back release)

RELEASE-PROCESS.md 还规定了唯一的例外机制:

如果在冻结期结束前发现严重问题(critical issue),且解决它需要更多时间,发布将被推迟(pushed back);而一旦某次发布被推迟,下一个发布周期也会随之延迟

由于周期首尾相接(新周期从旧周期结束日当天开始),一次延期会级联影响后续所有发布的时间表——这也解释了为什么冻结期内的 RC 测试与社区反馈如此重要:它正是发布前最后一道"是否具备发货条件"的检验。

八、小结:发布流程要素速查

要素 规则 依据
发布周期 每 9 周一次,周期首尾相接 RELEASE-PROCESS.md
开发阶段 前 6 周,改动"有资格"但不保证合入 同上
冻结阶段 第 7 周起 3 周,RC 只接受 cherry-pick 的关键修复 同上
发布动作 第 9 周末所有项目一起发布 同上
延期规则 严重问题导致延期,后续周期级联推迟 同上
补丁来源 可从 master 直切;否则建 docker-MAJOR.x 发布分支并回移 PATCH-RELEASES.mdBRANCHES-AND-TAGS.md
补丁标记 PR 加 process/cherry-pick/<BRANCH_NAME> 标签 PATCH-RELEASES.md
标签格式 Engine 为 docker-vX.Y.Z,如 docker-v29.7.2 BRANCHES-AND-TAGS.mdreleases/versions.yaml
同步工具 sync-branch(合入标签)、unmerged-tags(列出待回移标签) releases/scripts/sync-branchreleases/scripts/unmerged-tags

对贡献者而言,最有操作价值的结论只有两点:在冻结日前的早期开 PR 并优先对齐 ROADMAP.md面向存量版本修 bug 时,确认目标发布分支的维护状态,并按 PATCH-RELEASES.md 要求打上 process/cherry-pick/ 标签,改动才有进入下一次补丁发布的通道。

登录后查看全文
热门项目推荐
相关项目推荐