Bazel 发布模型(Release Model)完全指南:Rolling 与 LTS 双轨制、版本号规则与发布流程
【免费下载链接】bazela fast, scalable, multi-language and extensible build system项目地址: https://gitcode.com/GitHub_Trending/ba/bazel
本文以 Bazel 官方 Release Model 文档 为主体,系统讲解 Bazel 自 4.0 起采用的"滚动发布(Rolling)+ 长期支持(LTS)"双轨发布模型:包括支持矩阵与四个支持阶段、major.minor.patch语义化版本规则、两类发布轨道各自的节奏与完整发布流程,以及如何用 Bazelisk 对回归问题做二分定位。读完本文,你将能够看懂 Bazel 任意版本号背后的含义、判断某个版本当前处于什么支持状态,并理解从基线提交到正式发布的全过程及其中的 cherry-pick 与 release candidate 机制。
双轨发布模型:Rolling 与 LTS
Bazel 4.0 及更高版本提供两条发布轨道(release track):
- 滚动发布(Rolling releases):从主分支(HEAD)直接发布,每两周左右一个版本,是下一个 LTS 版本的预览。滚动发布可以与 Google 内部的 Blaze 发布保持同一基线(baseline)。
- 长期支持发布(LTS releases):每约 12 个月从 HEAD 切出一个新的主版本,成为当期的 Active 版本,并在随后数年内依次经历 Maintenance、Deprecated 阶段,为用户提供可预期的长期支持窗口。
从仓库结构可以佐证这套模型的落地:docs/versions/目录下按版本归档了 7.6.1、7.7.1、8.0.1、8.1.1、8.2.1、8.3.1、8.4.2、8.5.1、8.6.0、8.7.0、9.0.0、9.1.0 等版本的文档,说明每个 LTS/小版本都有独立的文档快照与之对应。
支持矩阵:各 LTS 版本当前处于什么阶段
下表为文档给出的最新支持矩阵,标注了各 LTS 主版本的支持阶段、最新版本号与停止支持时间(End of support):
| LTS release | Support stage | Latest version | End of support |
|---|---|---|---|
| Bazel 10 | Rolling | 以滚动发布页为准 | N/A |
| Bazel 9 | Active | 9.2.0 | Dec 2028 |
| Bazel 8 | Maintenance | 8.8.0 | Dec 2027 |
| Bazel 7 | Maintenance | 7.7.1 | Dec 2026 |
| Bazel 6 | Deprecated | 6.6.0 | Dec 2025 |
| Bazel 5 | Deprecated | 5.4.1 | Jan 2025 |
| Bazel 4 | Deprecated | 4.2.4 | Jan 2024 |
理解这张表时有两点需要特别注意:
- "Latest" 徽章不代表最新支持:GitHub 仓库上的 "Latest" 徽章始终指向语义版本号最高的那个版本,即使某个旧版本的维护补丁发布得更晚,徽章也不会指向它。因此判断"该用哪个版本"应以上表支持阶段为准,而非仓库徽章。
- 版本跨度大时注意支持周期:一个 LTS 版本在 Maintenance 阶段停留 2 年后即进入 Deprecated 阶段,届时官方不再提供任何支持,用户应迁移到更新的 LTS 版本。
版本号规则:语义化版本(Semantic Versioning)
Bazel 使用major.minor.patch的 Semantic Versioning 方案,各段位的含义如下:
- Major(主版本):包含与上一版本不向后兼容的特性。每个 major 版本就是一个 LTS 版本。
- Minor(次版本):包含向后兼容的缺陷修复和从主分支 back-port 回来的新特性。
- Patch(补丁版本):仅包含关键缺陷修复。
- Pre-release(预发布):在下一个主版本号后追加连字符和日期后缀来表示,例如
7.0.0-pre.20230502.1。
文档给出了一组直观的示例:同一次发布流程中,四种类型版本号分别形如6.0.0(Major)、6.1.0(Minor)、6.1.2(Patch)、7.0.0-pre.20230502.1(Pre-release)。
这套规则与仓库发布脚本的实现互相印证:release.sh 中的__do_release会读取当前 release 分支与 release candidate 编号来生成 tag 名,而滚动发布与 LTS 的命名/分支策略在脚本中也有明确区分(详见下文发布流程)。
支持阶段(Support Stages)
每个 Bazel 主版本都会经历四个支持阶段:
| 阶段 | 含义 |
|---|---|
| Rolling | 该主版本仍处于预发布阶段,Bazel 团队从 HEAD 持续发布滚动版本。 |
| Active | 当前活跃的 LTS 版本。团队会把重要特性与缺陷修复 back-port 到它的 minor 版本中。 |
| Maintenance | 处于维护模式的旧 LTS 版本。团队只承诺 back-port 与安全、OS 兼容性相关的关键缺陷修复。 |
| Deprecated | 官方不再提供支持,所有用户都应迁移到更新的 Bazel LTS 版本。 |
阶段转换的节奏是:新 LTS 发布后立即进入 Active,上一 LTS 进入 Maintenance;在 Maintenance 停留 2 年后进入 Deprecated。
发布节奏(Release Cadence)
两条轨道按不同的节奏发布:
滚动发布(Rolling releases)
- 与 Google Blaze 发布协调,大约每两周从 HEAD 发布一次;
- 是下一个 Bazel LTS 版本的预览;
- 可以携带不兼容变更。对于重大破坏性变更,官方推荐使用
--incompatible_*标志,并遵循向后兼容策略。
滚动发布的具体版本清单见滚动发布索引页,官方推荐使用 Bazelisk 来消费这些版本。
LTS 发布(LTS releases)
- Major(主版本):预计约每 12 个月从 HEAD 切一次。新 LTS 一旦发布立即进入 Active 阶段,上一 LTS 进入 Maintenance。
- Minor(次版本):Active 轨道上的新 minor 版本预计每 2 个月发布一次。
- Patch(补丁版本):Active 与 Maintenance 阶段的 LTS 按需发布 patch,仅用于关键缺陷修复。
发布流程与策略(Release Procedure & Policies)
滚动发布的流程
滚动发布流程很直接:大约每两周创建一个新版本,与 Google 内部 Blaze 发布保持同一基线。由于发布节奏快,不会向滚动版本 back-port 任何变更。
LTS 发布的完整流程
LTS 发布遵循以下流程:
- 确定基线提交(baseline commit)
- 新 major LTS:基线为主分支的 HEAD;
- minor 或 patch 发布:基线为当前最新版本的同一 LTS 发布分支的 HEAD。
- 创建发布分支:从基线提交创建名为
release-<version>的分支。 - 通过 PR 向发布分支 back-port 变更
- 社区成员可在相关 issue/PR 上回复 "
@bazel-io flag" 将提交标记为潜在发布阻塞项(release blocker),由 Bazel 团队分类并决定是否 back-port; - 只有主分支上向后兼容的提交才能被 back-port,为解决合并冲突所做的少量附带修改可以接受。
- 社区成员可在相关 issue/PR 上回复 "
- 使用 Cherry-Pick Request Issue 请求 back-port
- Bazel 维护者通过创建 cherry-pick 请求来申请将特定提交合入发布分支,具体步骤为:
- 打开 cherry-pick 请求模板;
- 填写请求详情:Title(简洁描述性标题)、Commit ID(s)(要 cherry-pick 的提交 ID,多个用逗号分隔)、Category(请求类别)、Reviewer(s)(多个审阅者 ID 用逗号分隔);
- 设置 milestone:在 Milestone 区域选择对应的
X.Y.Z发布阻塞项,这会触发 cherry-pick bot 为release-X.Y.Z分支处理你的请求; - 提交 issue。
- cherry-pick bot 会处理请求并通知提交是否可被 cherry-pick:如果 cherry-pick 时无合并冲突,bot 会创建一个新的 PR;该 PR 经 Bazel 团队成员批准后,提交被 cherry-pick 并合入发布分支。
- Bazel 维护者通过创建 cherry-pick 请求来申请将特定提交合入发布分支,具体步骤为:
- 识别发布阻塞项并修复问题:发布分支会与 postsubmit 和 downstream test pipeline 相同的测试套件在 Bazel CI 上运行,团队监控发布分支的测试结果并修复回归。
- 创建发布候选(release candidate):所有已知发布阻塞项解决后,从发布分支创建新的 RC。RC 会在 bazel-discuss 邮件列表中公告,团队监控社区对该候选版本的 bug 报告;若发现新的发布阻塞项,回到上一步解决后重新创建 RC。首个 RC 创建后不允许再向发布分支添加新特性,cherry-pick 仅限关键修复,且请求者必须回答:该变更为何关键、带来什么收益、引入回归的可能性有多大。
- 将 RC 推送为正式发布:若无进一步发布阻塞项,则推送 RC 为官方版本:
- patch 版本:最后一个 RC 发布至少两个工作日后推送;
- major/minor 版本:最后一个 RC 发布两个工作日之后、且不早于首个 RC 发布一周之后推送;
- 仅在下一天是工作日的那天推送;
- 发布后在 bazel-discuss 公告,团队监控并处理社区对新手版的 bug 报告。
源码视角:发布脚本如何落地这套流程
仓库中的 release.sh 正是上述流程的自动化实现,关键函数与文档步骤一一对应:
- 分支创建:
__create_release(release.sh)接收发布名与基线提交,创建形如release-<name>rc<n>的分支(branch_name="release-${release_name}rc${force_rc}"),并调用__apply_cherry_picks把传入的提交逐个 cherry-pick 到新分支——对应流程第 1~4 步。 - Cherry-pick 冲突处理:
__apply_cherry_picks(release.sh)在 cherry-pick 失败时进入交互式 shell 提示维护者解决冲突,可选择git cherry-pick --abort或git cherry-pick --continue,与文档"仅向后兼容提交可被 back-port、允许少量冲突修复"的策略一致。 - 发布与分支清理:
__do_release(release.sh)先判断is_rolling_release:滚动发布只有rc1分支、没有独立的正式 release 分支;非滚动发布则要求当前分支(最后一个release-X.Y.ZrcN候选分支)与正式分支release-X.Y.Z指向同一提交,否则拒绝发布。随后生成 release commit、打 tag、把 CHANGELOG.md 的更新合回 master 并推送。 - 发布说明生成:release 脚本还通过 relnotes.sh / relnotes.py 从提交历史生成发布说明,并在
__create_release_commit中把说明写入仓库根目录的 CHANGELOG.md,保证每个版本都有可追溯的变更记录。
报告回归与二分定位(Report Regressions)
如果在新版本、发布候选甚至 HEAD 上发现回归,请在 GitHub 上提交 bug。文档特别推荐使用Bazelisk 的 bisect 功能来定位罪魁提交(culprit commit),并把定位结果一并写入 bug 报告。
典型场景:构建在 Bazel 6.1.0 上成功、却在 6.2.0 的第二个 RC 上失败,可执行:
bazelisk --bisect=6.1.0..release-6.2.0rc2 build //foo:bar补充要点:
- 可通过设置
BAZELISK_SHUTDOWN或BAZELISK_CLEAN环境变量,让 Bazelisk 在执行对应 bazel 命令前先 shutdown/clean 构建状态,以便稳定复现问题; - 使用 bisect 功能前请把 Bazelisk 升级到最新版本。
更多 Bazelisk 用法可参考仓库中的 bazelisk 安装文档。
规则作者如何维护版本兼容
对于规则(rules)作者,若需要让自己的 Starlark 规则同时兼容多个 Bazel 版本,请参考 Rule Compatibility 页面。其核心结论是:
- 规则对 Bazel 的兼容性断裂有两种典型场景:依赖的特性在 HEAD 上被移除(破坏与未来 LTS 的兼容),或依赖的特性只在更新的 LTS 中可用(破坏与当前/旧 LTS 的兼容);
- 追求"可管理的迁移过程":用户不应被迫同时升级规则主版本与 Bazel 主版本;
- 最佳实践包括:规则自身遵循语义化版本;HEAD 上的规则同时兼容最新 LTS 与 Bazel at HEAD;利用
--incompatible_*标志配合 向后兼容策略 平滑迁移。
向后兼容:破坏性变更如何落地
与发布模型配套的向后兼容策略(详见 backward-compatibility.mdx)要点如下:
- 破坏性变更推荐通过
--incompatible_*标志引入; - 每个
--incompatible_*标志都对应一个解释行为变化并提供迁移配方的 GitHub issue; - 不兼容标志推荐 back-port 到最新 LTS 版本,但默认不启用,让用户在下个 LTS 到来前完成迁移;
- 由
--experimental_*标志守护的 API 与行为可随时变化; - 永远不要在生产构建中使用
--experimental_*或--incompatible_*标志。
未带--experimental_*的 API/行为一般视为稳定受支持特性,包括 Starlark 语言与 API、随 Bazel 分发的规则、Remote Execution API 与 Build Event Protocol 等 Bazel API,以及命令行标志及其语义。
小结
Bazel 的发布模型是一套"快节奏预览 + 长周期稳定"的双轨体系:滚动发布让用户每两周就能尝鲜下一个 LTS 的功能并提前适配破坏性变更,LTS 发布则通过 Active/Maintenance/Deprecated 四阶段为生产用户提供最长数年的可预期支持。理解支持矩阵、语义化版本规则与release-<version>分支 + RC 候选 + cherry-pick bot 的发布流程,是评估升级风险、参与社区 back-port 以及用 Bazelisk 定位回归问题的前提。本文所有流程细节均来自仓库中的 Release Model 文档,并由 release.sh 等发布脚本与docs/versions/下的版本化文档目录互相印证。
【免费下载链接】bazela fast, scalable, multi-language and extensible build system项目地址: https://gitcode.com/GitHub_Trending/ba/bazel
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考