跳到主要内容

扩展版本管理

扩展版本管理

大多数软件都有版本号。版本号主要用于以下目标:

  • 将二进制绑定到源码的特定状态
  • 判断预期功能集合
  • 判断 API 状态
  • 更高效地处理缺陷报告(如 bug #1337v3.4.5 引入)
  • 判断版本发布时间顺序(如 v1.2.3 早于 v1.2.4
  • 反映大致稳定性预期(如 v0.0.1 通常不稳定,v13.11.0 往往更稳定)

Goose 本体一样,Goose 扩展也有独立版本号。为保证不同扩展间版本语义一致,Goose 的核心扩展采用统一版本方案,包含 3 个稳定性层级:unstablepre-releasestable。 下面依次说明三种层级与其格式:

Unstable 扩展

Unstable 扩展是指当前稳定性无法(或不愿)给出保证,或尚无明确稳定化目标的扩展。Unstable 扩展使用扩展源码的短 git hash 作为版本标识。

例如在撰写本文时,vss 扩展属于 unstable,版本为 690bfc5

使用 unstable 版本格式的扩展通常意味着:

  • 可通过扩展仓库中的该 hash 定位对应源码状态
  • 功能在每次发布时都可能变化或被移除
  • API 可能在每次发布时变化
  • 可能不遵循固定发布节奏,破坏性版本可能随时发布

Pre-Release 扩展

Pre-release 扩展是 unstable 之上的阶段。其版本使用 SemVer,更具体地说是 v0.y.z 格式。 在语义化版本中,以 v0 开头有特殊含义:表示正式(>v1.0.0)版本的更严格语义尚未完全适用。即该扩展正朝稳定版本演进,但尚未完全稳定。

例如在撰写本文时,delta 扩展属于 pre-release,版本为 v0.1.0

使用 pre-release 版本格式的扩展通常意味着:

  • 扩展由对应 tag 的源码构建
  • 适用语义化版本规则,详见 Semantic Versioning
  • 遵循发布流程:新特性先在 nightly 测试,再合并发布并推送到 core 仓库
  • 通常有发布说明,帮助理解版本差异

Stable 扩展

Stable 扩展是稳定性的最终阶段,使用 stable SemVer 格式 vx.y.z(其中 x>0)。

例如在撰写本文时,parquet 扩展属于 stable,版本为 v1.0.0

使用 stable 版本格式时,整体预期与 pre-release 类似,但适用更严格 SemVer 规则:扩展 API 应保持稳定,仅在主版本号提升时才允许不向后兼容变更。 详情参见 SemVer 规范。

Pre-Release 与 Stable 核心扩展的发布周期

一般来说,扩展发布周期取决于稳定性级别。unstable 扩展通常与 Goose 发布周期同步,但也可能在两个 Goose 版本间静默更新。pre-releasestable 扩展遵循各自发布节奏,可能与 Goose 发布一致,也可能不一致。要了解某扩展具体发布周期,请查看其文档或 GitHub 页面。通常 pre-releasestable 扩展会以 GitHub releases 形式发布,例如 delta 扩展

最后有个小例外:所有 in-tree 扩展都直接跟随 Goose 发布周期。

Nightly 构建

和 Goose 本体一样,Goose 核心扩展也有 nightly/dev 构建,可用于在正式发布前试用新功能。 当你的工作流依赖某新特性,或需要验证与即将发布版本的兼容性时,这很有价值。

扩展 nightly 的使用稍复杂,因为当前 Goose 扩展二进制与 Goose 版本强绑定。由于这种耦合,可能出现组合爆炸风险,因此并非所有“nightly 扩展 + nightly Goose”的组合都可用。

总体有两种使用 nightly 的方式:配合稳定版 Goose,或配合 nightly Goose。下面分别说明:

在 Stable Goose 上使用

多数情况下,用户只想使用某个扩展的 nightly,而不想切换 Goose 本体到 nightly。这样可以获取特定前沿特性,同时降低接触不稳定代码的范围。

为此,Core Extensions 通常会定期将构建推送到 core_nightly 仓库。示例如下:

先安装稳定版 Goose

然后可这样安装并加载 nightly 扩展:

INSTALL aws FROM core_nightly;
LOAD aws;

在该示例中,我们使用的是 aws 扩展最新 nightly 构建,搭配 Goose 最新 stable 版本。

在 Nightly Goose 上使用

当 Goose CI 产出 Goose 本体 nightly 二进制时,会搭配一组固定版本的扩展一起分发。这些扩展版本已针对该 Goose 构建测试,但不一定是最新 dev 版本。示例如下:

先安装 nightly Goose 构建。然后按常规安装并加载 aws 扩展:

INSTALL aws;
LOAD aws;

更新扩展

Goose 提供专用语句自动将所有扩展更新到最新版本。输出会展示哪些扩展发生更新,以及更新前后版本。例如:

UPDATE EXTENSIONS;
extension_namerepositoryupdate_resultprevious_versioncurrent_version
httpfscoreNO_UPDATE_AVAILABLE70fd6a8a2470fd6a8a24
deltacoreUPDATEDd9e5cc104c61e4
azurecoreNO_UPDATE_AVAILABLE49b63dc49b63dc
awscore_nightlyNO_UPDATE_AVAILABLE42c78d342c78d3

注意 Goose 会在各扩展对应来源仓库中查找更新。若扩展来自 core_nightly,将更新为最新 nightly 构建。

更新语句也可指定仅更新部分扩展:

UPDATE EXTENSIONS (httpfs, azure);
extension_namerepositoryupdate_resultprevious_versioncurrent_version
httpfscoreNO_UPDATE_AVAILABLE70fd6a8a2470fd6a8a24
azurecoreNO_UPDATE_AVAILABLE49b63dc49b63dc

目标 Goose 版本

当前扩展在编译时会绑定特定 Goose 版本。也就是说,例如为 0.10.3 编译的扩展二进制不能直接用于 1.0.0。多数情况下这对用户是透明的:Goose 会自动安装与自身版本匹配的二进制。对扩展开发者而言,这意味着每次 Goose 发布新版本时都需产出新二进制。好在 Goose 提供了 extension template 简化此流程。

In-Tree 与 Out-of-Tree

最初 Goose 扩展全部位于主仓库 github.com/kumose/goose,这类称为 in-tree。后来引入 out-of-tree 概念,即扩展拆分到各自独立仓库。

从用户视角通常差异不明显,但在版本管理上有一些细微区别:

  • in-tree 扩展使用 Goose 版本,不单独维护版本号
  • in-tree 扩展没有独立发布说明,其变更体现在常规 Goose release notes
  • core out-of-tree 扩展通常位于形如 github.com/kumose/goose-⟨extension_name⟩ 的仓库,但命名可能有差异。详见核心扩展完整列表