Releases 是指软件或项目的正式发布版本,在浏览一些开源仓库时,可以看到当前项目最新版本和历史版本
仔细研究就会发现,版本号不是以固定值递增的,有时候第三位加 1,有时候加 2,有时候直接把第一位加 1,后两位置 0。这些版本变化规律是什么,能否从版本号看出与上一个版本的差异?
这就引出了语义化版本规范
什么是语义化版本规范?
语义化版本规范(Semantic Versioning,缩写为 SemVer)是一种版本号的标识规范,它规定了版本号的表示、增加和比较方式,以及不同版本号代表的含义。SemVer 的出现,主要是为了解决因版本更新带来的包依赖问题
在软件管理的领域里存在着被称作“依赖地狱”的死亡之谷,系统规模越大,加入的包越多,你就越有可能在未来的某一天发现自己已深陷绝望之中
在依赖高的系统中发布新版本包可能很快会成为噩梦。如果依赖关系过高,可能面临版本控制被锁死的风险(必须对每一个依赖包改版才能完成某次升级)。而如
果依赖关系过于松散,又将无法避免版本的混乱(假设兼容于未来的多个版本已超出了合理数量)
当你项目的进展因为版本依赖被锁死或版本混乱变得不够简便和可靠,就意味着你正处于依赖地狱之中
通过 SemVer 来约束版本号的配置和增长,就可以通过版本号来向别人说明你的修改。别人在引用包时,就可以清楚的了解到版本之间的差异和兼容性情况,从而选用合适版本的包
简单来说:语义化版本规范就是一套约定俗成的规则,通过这个规则,可以清晰的看出不同版本之间的差异、兼容性,有助于解决软件包依赖和升级过程中的问题
语义化版本的格式
语义化版本格式为:主版本号.次版本号.修订号(X.Y.Z),其中 X、Y 和 Z 为非负的整数,且禁止在数字前方补零
版本号递增规则如下:
主版本号:当你做了不兼容的 API 修改
次版本号:当你做了向下兼容的功能性新增,这里有个不成文的约定,偶数为稳定版本、奇数为开发版本
修订号:当你做了向下兼容的问题修正
例如,V3.12.0 中,3 是主版本号、12 是次版本号、0 是修订号
先行版本号及版本编译信息可以加到“主版本号.次版本号.修订号”的后面,作为延伸
常见的先行版本号有:
-
Snapshot:快照,也被称为开发版,处于开发阶段。这个版本的代码禁止用于生产环境
-
Alpha (α):内测版,内部交流或专业测试人员测试使用
-
Preview:预览版,与 Alpha 类似,有时还会细分 M1,M2 版本
-
Beta (β):公测版,专业爱好者大规模测试使用,存在一些 Bug,不适合一般用户使用
-
Gamma (λ):比较成熟的测试版
-
RC (Release Candidate):候选版本,处于 Gamma 阶段,该版本已经完成了全部功能并清除了大量的 Bug。 到了这个阶段,只会修复 Bug,不会对软件做任何大的更改。一般来说,Alpha -> Beta -> Gamma 是迭代的关系,RC1 -> RC2 是取舍的关系
-
Release:发行版本,正式发行的版本,已经经过测试,一般不会出现严重的 Bug,适合一般用户使用。对于不开源的软件, Release 可能是带有免费使用时间限制的版本
-
Stable:稳定版,同 Release 版本
举个例子,现在版本号为 V3.12.0-alpha.1,按照上面先行版本号的说明,可以看出这是一个内测版的项目,适合于内部交流或专业测试人员测试使用,生产环境中不推荐下载这个版本
语义化版本的规范
语义化版本控制规范比较多,介绍几个比较重要的:
-
使用语义化版本控制的软件必须定义公共 API。该 API 可以在代码中被定义或出现于严谨的文档内。无论何种形式都应该力求精确且完整
-
标记版本号的软件发行后,禁止改变该版本软件的内容,任何修改都必须以新版本发行、
-
主版本号为零(0.y.z)的软件处于开发初始阶段,一切都可能随时被改变。这样的公共 API 不应该被视为稳定版
-
1.0.0 的版本号用于界定公共 API 的形成。这一版本之后所有的版本号更新都基于公共 API 及其修改内容
-
修订号 Z(x.y.Z | x > 0)必须在只做了向下兼容的修正时才递增,这里的修正其实就是 Bug 修复
-
次版本号 Y(x.Y.z | x > 0)必须在有向下兼容的新功能出现时递增,在任何公共 API 的功能被标记为弃用时也必须递增,当有改进时也可以递增。其中可以包括修订级别的改变。每当次版本号递增时,修订号必须归零
-
主版本号 X(X.y.z | X > 0)必须在有任何不兼容的修改被加入公共 API 时递增。其中可以包括次版本号及修订级别的改变。每当主版本号递增时,次版本号和修订号必须归零
总结
了解了语义化版本规范后,可以更好的看明白一个项目的迭代过程、轻松的在项目中指定依赖项的版本
最后看一个应用场景:
假设有个名为“救火车”的函数库,它需要另一个名为“梯子”并已经有使用语义化版本控制的包。当救火车创建时,梯子的版本号为 3.1.0。因为救火车使用了一
些版本 3.1.0 所新增的功能,你可以放心地指定依赖于梯子的版本号大于等于 3.1.0 但小于 4.0.0。这样,当梯子版本 3.1.1 和 3.2.0 发布时,你可
以将直接它们纳入你的包管理系统,因为它们能与原有依赖的软件兼容
参考:语义化版本 2.0.0 | Semantic Versioning (semver.org)