引言

软件开发是一个持续迭代、持续集成、持续交付的过程,在这个过程中,软件会历经若干个版本,伴随着每个版本的发布,软件逐渐趋于成熟。那么,软件从最初的那一行代码开始,直到最后成长为一个“庞然大物”,我们该如何管理软件的版本呢?

可能存在的解决方案

我们平时可能会看到各式各样的版本号,例如:

  • V1.0
  • V20210601001
  • 2.0
  • 2.0.1.2.3
  • 3.0.2-20210601001

或许这就跟“一千个读者有一千个哈姆雷特”是一回事,不同的软件、不同的开发者就会制订出不同的版本号,只要版本号能满足现有场景,那就说明是合理的,但是暂时合理不代表将来也是合理的,因为软件是不断演进的,软件的复杂程度可能是越来越高的,软件被用于的场景可能是越来越多的,软件的集成方也可能会提出花样百出的要求,所以从一开始制定一个合理的版本管理方案显得尤为重要。

语义化版本(SemVer)

就如何管理软件版本这个问题,软件工程化实践中诞生了语义化版本(SemVer)这一方案。

什么是语义化版本?

何为语义化版本?简单来说,语义化版本就是一组关于如何制定软件版本号的一套规范,通过使用这套规范,软件的版本号能更清晰地表达出版本的含义,也能有效避免软件升级过程中出现版本混乱的问题。
语义化版本详细资料请参阅:https://semver.org。

语义化版本重要规则

  1. 标准的版本号必须(MUST)采用 X.Y.Z 的格式,X、Y 和 Z 为非负的整数,X 是主版本号、Y 是次版本号、而 Z 为修订号;
  2. 修订号 Z(x.y.Z | x > 0)必须(MUST)在只做了向下兼容的修正时才递增;
  3. 次版本号 Y(x.Y.z | x > 0)必须(MUST)在有向下兼容的新功能出现时递增;
  4. 主版本号 X(X.y.z | X > 0)必须(MUST)在有任何不兼容的修改被加入公共 API 时递增;
  5. 先行版本号可以(MAY)被标注在修订版之后,先加上一个连接号再加上一连串以句点分隔的标识符来修饰;
  6. 版本编译信息可以(MAY)被标注在修订版或先行版本号之后,先加上一个加号再加上一连串以句点分隔的标识符来修饰。

语义化版本示例

给一个标准的语义化版本:2.34.0-alpha+20210901v01。其中,版本号的各部分为:

主版本号次版本号修订号先行版本号版本编译信息
2340-alpha+20210901v01

如何判断语义化版本的优先级

优先级指不同版本的大小顺序。以下是语义化版本如何判断优先级的规则:

  1. 判断优先层级时,必须(MUST)把版本依序拆分为主版本号、次版本号、修订号及先行版本号后进行比较(版本编译信息不在这份比较的列表中);
  2. 由左到右依序比较每个标识符,第一个差异值用来决定优先层级,例如:1.0.0 < 2.0.0 < 2.1.0 < 2.1.1;
  3. 当主版本号、次版本号及修订号都相同时,改以优先层级比较低的先行版本号决定,例如:1.0.0-alpha < 1.0.0;
  4. 有相同主版本号、次版本号及修订号的两个先行版本号,其优先层级必须(MUST)透过由左到右的每个被句点分隔的标识符来比较,直到找到一个差异值后决定;
  5. 只有数字的标识符以数值高低比较,有字母或连接号时则逐字以 ASCII 的排序来比较。数字的标识符比非数字的标识符优先层级低;
  6. 若开头的标识符都相同时,栏位比较多的先行版本号优先层级比较高。例如:1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0。

Q.E.D.


学而时习之,不亦说乎? 有朋自远方来,不亦乐乎?