October 19, 2024
软件开发的过程中,定义版本号是一项重要的任务。
一个清晰而有序的版本号能够帮助开发者、测试人员、产品经理等理解和跟踪软件版本的变化。
一、经典命名方式的组成
版本号通常由主(大)版本号、次(子)版本号和修订(补丁)版本号三部分构成,形如X.Y.Z:
- 主版本号X:当软件进行了重大更新或编写重写时,主版本号递增。通常表示程序的架构、API、模块等发生了重大变化。
- 次版本号Y:当软件在原有的基础上增加了部分功能时,次版本号递增。程序的功能或者特性有新增或修改。
- 修订版本号Z:当软件修复了Bug时,或提供了安全增强,补丁版本号递增。表示程序改善了一些细节问题。
- 另外可能有编译版本号:通常是构建系统自动生成,每次代码提交都会导致自动加1。
在开发过程中,软件处于不同的稳定期中,为了体现重要节点,有一些约定的版本修饰词:
- Alpha: 内部测试版本,API还没有稳定下来,新功能刚刚实现,BUG 众多,一般用于开发人员内部交流。
- Beta: 测试版,API已经比较确定,新功能已经基本完成,BUG 较多,一般用于社区参与者测试,并向开发人员反馈。
- RC: release candidate,即将作为正式版发布,正式版之前的最后一个测试版。
- GA:general availability,发行的稳定版,或干脆啥都不加,只有数字版本号,也有称Final。
- LTS: long term support,长期维护,官方会确定并生命对这个版本维护到哪一年,会修复所有在这个版本中发现的 BUG。
二、其他命名方式
- 以单纯的数字递增方式命名,比如 OpenJDK从9-23,每半年发布一个主版本。较快速度开发迭代,重一要版本标记为LTS长期维护,或者基于社区版进行深度产品化发布商业支持版。
- 以年份+月份(或者序列号)方式命名,如 Ubuntu 24.04.1,其中24.04表示2024年4月,1表示第一个更新版本
三、兼容性和可维护性
X.Y.Z 经典命名方式容易理解兼容性:
- 一般来说,同一个主版本下API和架构不会发生很大变化,后面发布的版本向前兼容同样主版本号前面的版本,比如2.3.8兼容2.0.1。但不同的主版本不予保证,常见原因可能是同样功能API定义发生了变化,或者早期的特定被弃用。
- 次版本在上一版本上增加功能,定义新的API。
- 修订版本提供bug修改及重要安全补丁,API尽可能不变。
其他命名方式下,兼容性不太容易从版本号上看出来,需要查看产品或项目文档。
不过若有LTS版本声明,可以把LTS看做主版本,在其生命周期内,基于LTS的次版本和修订版本都会有很好的兼容性。主版本递增的则因项目而不同。
四、各模块的定义
一个产品或者项目,内部会有众多组成模块。如果是小项目,没有必要对模块进行版本细分,只需全局版本号即可。
但如果是较大项目,则很有必要对其中的模块定义版本,进行管理并维护。
目前常见的有以下几种:
- 各模块实现代码分散在不同的项目中,通过开发库的方式组合在一起。各模块自行定义版本号。适合大型的项目,如操作系统等。
- 各模块分别定义版本号,但彼此有关联,项目主版本升级时,各模块会同时升级,比如SpringCloud。
- 发布版本时,对不同模块成熟度加以说明,可以生产就绪的标注为GA,已完成功能但还需时日打磨的标注为EA/Preview/Beta等。
五、杂谈
- 有的产品会进行混用版本定义,如很多偏消费类,直接用于产品名称,如Windows95,XP,2000,但其内也部有开发版本号。
- 见过有的产品经理将刚开发出的产品直接赋予为很大的版本号,理由是客户会觉得大的版本会更加成熟。个人觉得这种方式不妥,特别是对于开源项目。只能增加开发人员的维护疑惑。
- 版本迭代有两种主要因素:功能特性和开发周期。经典版本命名方式以功能实现为主,发布时间容易拖延;按照时间周期发布则遵循小步快跑的原则,到时间就发布,有多少功能特性就纳入多少,达不到生产就绪的进行标注,通过特定参数才能激活使用。
六、维护的开源项目版本号
- Tomcat:经典命名方式,当前维护版本 V9-V11,分别对应不同的JEE和Servlet规范版本。近期发布了V11主版本。
- WildFly:主版本递增方式。从WildFly 9开始,社区版本演进采用快速迭代方式,每个季度发布一个版本。商业支持版为EAP(Red Hat JBoss Enterprise Application Platform),以某个社区版作为上游,拉出分支版本进行产品化,提供商业级维护支持,定期提供维护更新版,目前为EAP 8.0 Update03。
- Kafka:经典命名方式。下一个主版本为 v4.0。
- Redis:经典命名方式。次版本沿用Linux社区习惯,偶数为稳定版,奇数为开发版。下一个主版本为 v8.0。
- Nginx:经典命名方式。次版本沿用Linux社区习惯,偶数为稳定版,奇数为开发版。商业版Nginx Plus提供更丰富的功能和服务支持,以某个社区版为基础开发,版本号使用主版本递增方式,如R32 基于社区版 v1.25.5。
- Spring:Framework和Boot采用经典命名方式。Cloud采用年份+序号命名方式,如2024.0.0,伞型子项目有各自的版本号。
- Quarkus:经典命名方式。每个月发布一个次版本。约每半年有LTS版提供1年以上的长期支持,如3.8, 3.15等。
- OpenJDK:主版本递增方式。每半年发布一个主版本,除LTS以外版本维护期半年到下一版本发布。LTS目前为2年发布一个,如11/17/21/25,下一LTS为v25,将于2025年9月发布。
- Jakarta EE:经典命名方式。约2年发布一个主版本,基于新的JDK版本。包含很多子规范,大多数采用经典命名方式,如Servlet 6.1。下一个主版本为 v11。
- MicroProfile:经典命名方式。已发布主版本为v7.0。包含子规范采用经典命名方式。
- Spark:经典命名方式。下个主版本为v4.0。
- Flink:经典命名方式。下个主版本为v2.0。
- Postgres:经典命名方式。主版本递增较快,也可以看做主版本递增方式。已发布主版本v17。
- Mysql:经典命名方式。LTS版本为前一个主版本功能稳定版,如目前最新开发版为v9.1,LTS为上一主版本8.7。
- MongoDB:经典命名方式。社区版已发布主版本v8.0。
- KeyCloak:主版本递增方式。商业支持版为红帽的Red Hat Single Sign-On,上游为社区版某个版本,采用经典命名方式。
- ElasticSearch:经典命名方式。
- Jenkins:主版本+版本递增方式。定义LTS和每周发布包,如v2.462为LTS,进行小版本升级维护;每周发布版本,如v2.481。
- Ansible:经典命名方式。
- Prometheus:经典命名方式。下个主版本为v3.0。
- Docker:经典命名方式。
- Podman:经典命名方式。
- Kubernetes:经典命名方式。每季度发布一个版本。标记稳定,beta等特性。
- Openshift:经典命名方式。每个发布以Kubernetes的某个版本作为上游,增强功能和产品稳定性。
- Rocky:经典命名方式。基于RHEL,命名相同。每年发布一个次版本,主版本每4-6年发布,维护期十年以上之久。
- Ubuntu:年份月份序号命名方式。每版本发布一个版本。每两年的4月发布LTS版,半年提供更新版本,如v24.04.1。