一卓的博客

怕什么真理无穷,
进一寸有一寸的欢喜。

0%

版本号命名规则

版本号命名规则

本文根据 Semantic Versionning 2.0.0 和 Semantic Versioning 3.0.0 选择性的整理出版本号命名规则指南。

版本号的格式为 X.Y.Z(又称 Major.Minor.Patch),递增的规则为:

1
2
3
X 表示主版本号,当 API 的兼容性变化时,X 需递增,Y 和 Z 同时设置为 0。
Y 表示次版本号,当增加功能(不影响 API 的兼容性) 或者 API 被标记为 Deprecated 时,Y 需递增,同时 Z 设置为 0。
Z 表示修订号,当做 Bug 修复时(不影响 API 的兼容性),Z 需递增。

详细的规则如下:

1
2
3
4
5
6
7
X, Y, Z 必须为非负整数,且不得包含前导零,必须按数值递增,如 1.9.0 -> 1.10.0 -> 1.11.0
0.Y.Z 的版本号表明软件处于初始开发阶段,意味着 API 可能不稳定;1.0.0 表明版本已有稳定的 API。
先行版本号(Pre-release)意味该版本不稳定,可能存在兼容性问题,其格式为:X.Y.Z.[a-c][正整数],如1.0.0.a1,1.0.0.b99,1.0.0.c1000。
开发版本号常用于 CI-CD,格式为 X.Y.Z.dev[正整数],如 1.0.1.dev4。
版本号的排序规则为依次比较主版本号、次版本号和修订号的数值,如 1.0.0 < 1.0.1 < 1.1.1 < 2.0.0;
对于先行版本号和开发版本号,有:1.0.0.a100 < 1.0.0, 2.1.0.dev3 < 2.1.0;
当存在字母时,以 ASCII 的排序来比较,如 1.0.0.a1 < 1.0.0.b1。

注意:版本一经发布,不得修改其内容,任何修改必须在新版本发布!

一些修饰的词

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Snapshot: 版本代表不稳定、尚处于开发中的版本
Alpha: 内部版本
Beta: 测试版
Demo: 演示版
Enhance: 增强版
Free: 自由版
Full Version: 完整版,即正式版
LTS: 长期维护版本
Release: 发行版
RC: 即将作为正式版发布(Release Candidat) 用在软件上就是候选版本。系统平台上就是发行候选版本。RC 版不会再加入新的功能了,主要着重于除错。
GA: General Availability,正式发布的版本,在国外都是用 GA 来说明 release 版本的。
Standard: 标准版
Ultimate: 旗舰版
Upgrade: 升级版

Linux:

奇数的发展中版本(develop),如 2.5 ,及偶数的稳定版本,如 2.6 。

FAQ

  • 在 0.y.z 初始开发阶段,我该如何进行版本控制?
    最简单的做法是以 0.1.0 作为你的初始化开发版本,并在后续的每次发行时递增次版本号。

  • 如何判断发布 1.0.0 版本的时机?
    当你的软件被用于正式环境,它应该已经达到了 1.0.0 版。如果你已经有个稳定的 API 被使用者依赖,也会是 1.0.0 版。如果你很担心向下兼容的问题,也应该算是 1.0.0 版了。

  • 这不会阻碍快速开发和迭代吗?
    主版本号为零的时候就是为了做快速开发。如果你每天都在改变 API,那么你应该仍在主版本号为零的阶段(0.y.z),或是正在下个主版本的独立开发分支中。

  • 对于公共 API,若即使是最小但不向下兼容的改变都需要产生新的主版本号,岂不是很快就达到 42.0.0 版?
    这是开发的责任感和前瞻性的问题。不兼容的改变不应该轻易被加入到有许多依赖代码的软件中。升级所付出的代价可能是巨大的。要递增主版本号来发行不兼容的改版,意味着你必须为这些改变所带来的影响深思熟虑,并且评估所涉及的成本及效益比。

  • 为整个公共 API 写文件太费事了!
    为供他人使用的软件编写适当的文件,是你作为一名专业开发者应尽的职责。保持专案高效一个非常重要的部份是掌控软件的复杂度,如果没有人知道如何使用你的软件或不知道哪些函数的调用是可靠的,要掌控复杂度会是困难的。长远来看,使用语义化版本控制以及对于公共 API 有良好规范的坚持,可以让每个人及每件事都运行顺畅。

  • 万一不小心把一个不兼容的改版当成了次版本号发行了该怎么办?
    一旦发现自己破坏了语义化版本控制的规范,就要修正这个问题,并发行一个新的次版本号来更正这个问题并且恢复向下兼容。即使是这种情况,也不能去修改已发行的版本。可以的话,将有问题的版本号记录到文件中,告诉使用者问题所在,让他们能够意识到这是有问题的版本。

  • 如果我更新了自己的依赖但没有改变公共 API 该怎么办?
    由于没有影响到公共 API,这可以被认定是兼容的。若某个软件和你的包有共同依赖,则它会有自己的依赖规范,作者也会告知可能的冲突。要判断改版是属于修订等级或是次版等级,是依据你更新的依赖关系是为了修复问题或是加入新功能。对于后者,我经常会预期伴随着更多的代码,这显然会是一个次版本号级别的递增。

  • 如果我变更了公共 API 但无意中未遵循版本号的改动怎么办呢?(意即在修订等级的发布中,误将重大且不兼容的改变加到代码之中)
    自行做最佳的判断。如果你有庞大的使用者群在依照公共 API 的意图而变更行为后会大受影响,那么最好做一次主版本的发布,即使严格来说这个修复仅是修订等级的发布。记住, 语义化的版本控制就是透过版本号的改变来传达意义。若这些改变对你的使用者是重要的,那就透过版本号来向他们说明。

  • 我该如何处理即将弃用的功能?
    弃用现存的功能是软件开发中的家常便饭,也通常是向前发展所必须的。当你弃用部份公共 API 时,你应该做两件事:(1)更新你的文件让使用者知道这个改变,(2)在适当的时机将弃用的功能透过新的次版本号发布。在新的主版本完全移除弃用功能前,至少要有一个次版本包含这个弃用信息,这样使用者才能平顺地转移到新版 API。

  • 语义化版本对于版本的字串长度是否有限制呢?
    没有,请自行做适当的判断。举例来说,长到 255 个字元的版本已过度夸张。再者,特定的系统对于字串长度可能会有他们自己的限制。

参考链接:

Semantic Versioning 2.0.0
Semantic Versioning 3.0.0

请作者喝杯咖啡吧