news 2026/9/24 20:36:06

Dart SDK 分支管理与发布周期全解:从 main 到 stable 的四通道工作流

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Dart SDK 分支管理与发布周期全解:从 main 到 stable 的四通道工作流

Dart SDK 分支管理与发布周期全解:从 main 到 stable 的四通道工作流

【免费下载链接】sdkThe Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.项目地址: https://gitcode.com/gh_mirrors/sdk1/sdk

Dart SDK 采用"单主干 + 三个发布通道"的简洁分支模型:日常开发集中在main分支,功能在验证充分后通过 flag 门控逐步开放,最终经devbetastable三个通道逐级发布。本文以仓库文档 docs/Branches-and-releases.md 为核心骨架,结合 tools/VERSION、tools/utils.py 及 docs/Cherry-picks-to-a-release-channel.md 等源码级证据,完整讲解分支职责、约两个月一轮的发布节奏、cherry-pick 季节的操作流程,以及实验性 flag 如何与发布通道协同工作。读完你既能看清整个 SDK 从提交到发布的完整链路,也能直接上手执行"把修复带到 beta/stable"的完整操作。

四分支模型:一条主干,三条发布通道

Dart SDK 的分支结构非常简单直接:所有日常开发都在main上完成,尚未准备就绪的特性统一藏在实验 flag 之后,待稳定性充分验证后才默认开启;偶尔也会为大型破坏性改动创建临时特性分支。除此之外,还有devbetastable三个发布分支,负责把代码逐级推向用户。

四类分支的职责与约束如下:

分支来源刷新频率发布产物开发者注意事项
main日常开发主干持续每日构建你的 CL 应该落在 main
dev从 main 全量推送通常每周两次dev 通道构建不要在 dev 上直接落 CL
beta从 dev 全量推送,或 cherry-pick通常每月一次beta 通道构建不要在 beta 上直接落 CL
stable从 beta 全量推送,或 cherry-pick有发布时stable 通道构建不要在 stable 上直接落 CL
  • main:日常开发分支,"everyday" 开发都在这里进行,所有普通 CL 都应落在 main。可以理解为开发者唯一真正打交道的分支。
  • dev:由 main 通过全量推送(full push)填充,通常每周两次。除非紧急情况,否则不会在 dev 上落 cherry-pick。dev 通道构建由此分支发布。
  • beta:由 dev 全量推送填充,通常每月一次,或通过 cherry-pick 更新。beta 通道构建由此分支发布。
  • stable:主发布分支。当某个版本准备好发布时,从 beta 全量推送而来,或通过 cherry-pick 更新。stable 通道构建由此分支发布。

一个需要反复强调的纪律是:devbetastable三个分支都不接受直接提交的 CL,发布分支的内容只能通过全量推送或 cherry-pick 两条路径进入,这从流程上保证了发布内容的可追溯性。

发布周期:约两个月一轮的稳定化流程

Dart SDK 的正常发布周期约为2 个月,但这个数字并非承诺——团队会根据稳定性提前或推迟发布。团队并不遵循特性驱动的发布节奏,但大型语言特性可能例外:为了让所有工具链(VM、编译器、分析器等)保持同步,可能推迟某个版本。

完整周期可以拆解为以下阶段:

  1. 日常阶段(周期的大部分时间):团队持续在main上工作,并定期把 main 的绿构建(green build)全量合并到dev,约每周两次。如果在 dev 上快速发现了 bug,会再做一次额外的全量推送。
  2. 稳定化阶段(周期最后约 2 周):把最新的 dev 版本全量推送到beta,进入 beta 通道稳定期。此阶段只允许对 beta cherry-pick 关键修复(critical fixes)。main 上的开发与 dev 通道的发布照常继续。这一阶段被称为cherry-pick season(cherry-pick 季节),每周会做多批 cherry-pick 并在 beta 通道发布。
  3. 发布阶段:当 beta 通道状态良好("looks good")时,合并到stable并正式发布。
  4. 补丁维护阶段:在 2 个月的周期中,基于最新的 stable 版本,持续为安全(security)、崩溃(crash)、关键 bug(critical bug)发布补丁版本。

cherry-pick season 中把你的改动带到 beta

在 cherry-pick 季节,如果你的修复需要进入 beta 通道,完整操作流程见 Cherry-picks-to-a-release-channel.md,核心步骤概括为:先在 main 上落地修复与测试 → 识别 beta/stable 是否受影响 → 在新分支上执行git cherry-pick --edit→ 更新提交信息(添加[beta][stable]hashtag,改写Reviewed-onCherry-pick,移除不适用于新 CL 的字段)→ 填写 Issue description / What is the fix / Why cherry-pick / Risk / Issue link(s) 五段式说明 →git cl upload提交 Gerrit 审批 → 由领域专家与 Dart 团队 lead 评审后提交 commit queue,tryjobs 会与 beta/stable 分支上一提交对比测试结果,引入回归则失败。

版本号如何随周期演进

版本号并不是随手改的,而是由 tools/VERSION 文件与 tools/utils.py 中的Version类、ReadVersionFileGetVersion等逻辑共同驱动。当前仓库的 VERSION 文件内容为:

CHANNEL main MAJOR 3 MINOR 14 PATCH 0 PRERELEASE 0 PRERELEASE_PATCH 0

VERSION 文件头部注释完整定义了数字的变化规则:

  • 新发布周期开始(stable 刚发布):MINOR+1,PATCH/PRERELEASE/PRERELEASE_PATCH归 0;
  • push-to-trunk(周期内首次会同时把PRERELEASE归 0):PRERELEASE+1,PRERELEASE_PATCH归 0;
  • cherry-pick 到 trunkPRERELEASE_PATCH+1;
  • 发布 stablePRERELEASEPRERELEASE_PATCH归 0(新的 stable 版本号会排在所有 prerelease 之上);
  • stable 通道的 cherry-pickPATCH+1。

tools/utils.py 中的GetVersion(tools/utils.py#L369-L384)展示了这些字段如何拼装成最终版本字符串:

  • main/be通道 →{major}.{minor}.{patch}-edge.{git_hash}(如3.14.0-edge.abcdef1234);
  • beta/dev通道 →{major}.{minor}.{patch}-{prerelease}.{prerelease_patch}.{channel}
  • stable通道 → 纯{major}.{minor}.{patch}

Version.__str__(tools/utils.py#L177-L182)则定义了语义化版本串的拼接规则。这套机制保证了四个分支上的版本号始终可比较、可排序,这正是"dev 版本号永远低于未来 stable 版本号"这一保证的来源。

实验 flag 与分支模型的协同:大特性如何安全落地

原文档特别强调:"尚未准备好上线的特性隐藏在 flag 之后,待稳定性充分验证后启用。"这正是 tools/experimental_features.yaml 的职责所在。从该文件的结构看(其helpenabledInexperimentalReleaseVersionexpiredvalidation等字段,详见文件头部注释与 docs/process/experimental-flags.md),一个实验特性会经历如下状态机:

  1. Disabled:刚加入文件时,省略enabledInexpired字段,默认关闭,可通过--enable-experiment=xxx命令行开启;
  2. Experimental release:加入sdk/lib/_internal/allowed_experiments.json白名单并提升experimentalReleaseVersion,允许特定库/包默认开启,其他用户仍需显式传 flag;
  3. Shipped:添加enabledIn字段标记正式发布的 SDK 版本,此时 flag 默认开启且无法关闭;
  4. Retired / Rejected:添加expired: true,命令行传 flag 会收到警告但工具继续运行,条目等待最终从文件中移除。

原文档给出了一个典型时序:特性在版本 n-1 的 beta 1 公开为实验特性,在版本 n 的 beta 1 默认启用,在版本 n+1 的 beta 1 退役。从当前文件可以看出,recordspatternsclass-modifiers等已在 3.0.0 默认启用并标记expired: truedot-shorthands(3.10.0 启用)、native-assets(3.10.0 启用)、primary-constructors(3.13.0 启用)等也已走完这条生命周期,而macrosaugmentationsenhanced-parts等仍处于实验阶段。这个机制正是"main 上可以安全地长期保留未完成代码"的根基——未完成特性对用户不可见,而dev/beta/stable通道的每次构建因此都能保持"功能完整且受支持"的高质量。

实践操作:按分支定位版本与频道

查看当前分支的版本通道

VERSION 文件中的CHANNEL字段即当前分支的发布通道标识。在仓库根目录执行:

$ git branch --show-current main $ cat tools/VERSION | grep CHANNEL CHANNEL main

每个发布分支(dev/beta/stable)上的 VERSION 文件会各自携带对应的通道标识,这正与 tools/utils.py 中GetChannel(tools/utils.py#L387-L389)读取CHANNEL字段的逻辑对应。

把修复带到 stable 的完整流程(cherry-pick)

以 docs/Cherry-picks-to-a-release-channel.md 的操作步骤为基准:

$ git fetch $ git new-branch --upstream origin/stable cherry # 或 origin/beta $ git cherry-pick --edit $commit $ $EDITOR CHANGELOG.md # stable 必须更新 CHANGELOG,beta 不需要

提交信息按以下规则改写(示例见原文档):

[stable] Fix foo crash. Issue description: When attempting to use foo under certain conditions, users are unable to compile. What is the fix: foo is now evaluated at runtime. Why cherry-pick: Users of foo are no longer able to compile to bar. Risk: Low, this fix has landed on the main channel and is tested on the same infrastructure. Issue link(s): https://github.com/dart-lang/sdk/issues/12345678 Cherry-pick: https://dart-review.googlesource.com/c/sdk/+/12345678

要点包括:第一行以[beta][stable]Gerrit hashtag 开头;Reviewed-on改名为Cherry-pick并指向原始 CL;删除不再成立的Change-idCommit-queueReviewed-by字段;说明必须包含 Issue description / What is the fix / Why cherry-pick / Risk / Issue link(s) 五个要素。

CHANGELOG 要求:stable 通道的 cherry-pick 必须携带 CHANGELOG.md 条目(相关硬性要求见 docs/Gerrit-Submit-Requirements.md),beta 通道则不需要。若下一个 stable 补丁版本尚未在 CHANGELOG 中建立小节,需要新建小节并把补丁号 +1(如3.0.43.0.5),且不加发布日期——日期在正式发布时才补上;已有发布日期的小节表示已经发布,不得再改动。纯基础设施、对用户不可见的改动可通过Changelog-Exempt: ...脚注豁免。

随后上传并提交:

$ git cl upload

CL 需经领域主题专家(area subject matter expert)与 Dart 团队 lead 双重评审,之后作者将其提交到 commit queue。关键保护机制:tryjobs 会把测试结果与 beta/stable 分支上的前一提交对比,一旦引入回归即失败;若必须引入回归、或 try builders 无法在较老的 beta/stable 代码上运行,可在 Gerrit 中强制提交(... -> Submit)绕过 commit queue。

cherry-pick 依赖仓库中的提交

当修复涉及第三方依赖(如third_party/pkg/pub)时,流程变为两步。先在 SDK 检出中定位发布分支上的依赖修订号:

dart-sdk/sdk/ > git checkout beta && git pull dart-sdk/sdk/ > gclient getdep -r sdk/third_party/pkg/pub a3f8b2fd36ec432450caf907474a02023ef3e44e

然后在依赖仓库的克隆中做 cherry-pick 并推送,等待镜像同步后,通过合并提交把该提交并入依赖的受保护分支(防止被 GC),最后回到 SDK 检出用tools/manage_deps.dart创建 bump 提交:

dart-sdk/sdk/ > tools/manage_deps.dart bump third_party/pkg/pub --target=6d1857c84cfb8a014aefedaf2d453214bf5ddb96 dart-sdk/sdk/ > git branch --set-upstream-to=origin/beta dart-sdk/sdk/ > git cl upload

总结:一套面向稳定与速度的工程纪律

回顾整个模型,可以提炼出 Dart SDK 发布工程的核心设计:

  1. 单一主干,多通道发布:所有开发集中在maindev/beta/stable只通过全量推送与 cherry-pick 两种受控路径更新,杜绝了发布分支的不可控提交。
  2. 稳定化节奏前置:每个周期最后两周专门用于 beta 通道稳定化(cherry-pick season),把风险控制在发布之前。
  3. flag 门控替代特性分支:未完成特性以实验 flag 形式长期存在于 main,既保证 dev 通道构建的功能完整性,又允许大特性跨多个版本持续演进(如 null safety、records、macros)。
  4. 版本号机器可读:tools/VERSION 与 tools/utils.py 的组合让每个通道的版本号保持单调可排序,为发布判断和依赖解析提供了可靠依据。

这套机制同时服务于三类人群:普通开发者只需知道"CL 落在 main,实验特性用 flag 尝鲜";贡献者需要掌握 cherry-pick 的完整操作与提交信息规范;而需要预发布版本的团队则可以根据 dev/beta 通道的构建选择合适的时间窗口。相关细节还可进一步阅读 Cherry-picks-to-a-release-channel.md、Gerrit-Submit-Requirements.md 与 Experimental-Flags.md。

【免费下载链接】sdkThe Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.项目地址: https://gitcode.com/gh_mirrors/sdk1/sdk

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 20:35:36

大模型在线体验零门槛:OpenI启智社区上手全攻略

先说结论:如果你想接触大模型,但发现自己既没有一块像样的GPU显卡,也暂时不想为API充值,那OpenI启智社区的大模型在线体验功能是当前最值得花半小时注册试用的入口之一。我自己的第一行大模型Prompt就是在类似这种免费在线环境里敲…

作者头像 李华
网站建设 2026/9/24 20:35:35

“260110”项目编号背后:从目标拆解到项目复盘的方法论

1. “260110”到底是什么:拆解项目编号背后的信息设计先把这个标题掰开说。很多人第一眼看到“260110”,会觉得这只是一串数字,或者是某个系统自动生成的流水号。但在我过去多年的项目管理实操里,像“260110”这类编号&#xff0c…

作者头像 李华
网站建设 2026/9/24 20:34:26

StableLM-3B:开源大模型工业化落地实践指南

1. 这不是又一个“开源玩具”:StableLM 的真实定位与行业冲击力Stability AI 发布 StableLM,这件事在技术圈里炸开的动静,远比表面看起来要大得多。它不是简单地往开源模型仓库里扔一个新权重文件,而是直接把一把锋利的手术刀&…

作者头像 李华
网站建设 2026/9/24 20:34:26

n8n架构拆解与生产部署实战:从核心机制到AI工作流编排

1. 为什么我要花两周时间拆解 n8n 的架构第一次接触 n8n 是在一个跨境电商订单同步的需求里。当时团队只有三个人,后端接口要对接五个平台,每个平台的订单字段、退款逻辑、物流状态回调格式都不一样。如果用传统写脚本的方式,光是维护这些接口…

作者头像 李华
网站建设 2026/9/24 20:33:21

2026知网AIGC检测新规:五款降AI工具实测与免费降AI策略

1. 2026知网新规下,AIGC检测为何成了论文“生死线”先说一个我最近被问到最多的问题:“老师,我论文明明是自己一个字一个字写的,为什么知网AIGC检测还给我标红一大片?”我今年帮学生和同行朋友做了几十次降AI率实测&am…

作者头像 李华