一、序言
- python --version 可以看到 python 版本号,比如 2.7.5、3.7.3
- 微信、京东或者一些小程序打开的时候底部也会显示版本号比如 V1.0.7 等等
- 问题:这些版本号的各个数字分别代表什么,软件版本如何命名的,有哪些常用的版本命名规范,软件新增功能后、bugfix 后、对外发布的版本号等等应该怎么命名…
二、为什么要进行版本控制
试想一种情况:某造车新势力计划于 1.11 开新品发布会,届时新车型会搭载公司最新的 L2+ 自动驾驶软件产品。在此之前,产品部各个团队加班加点进行开发和测试,每个团队都有自己的开发目标:要实现哪些功能、要在什么时间点之前完成测测试和联调、要达到哪些 KPI 等等。路测有很多台车,大家测试也都很积极,路上碰到问题可能直接就在车上完成 bugfix 并继续测试,或者每个工程师解决完自己的问题后就直接往车上拷贝代码去测试,感知定位和规控都是这么干的,过了一段时间,每台车的路测表现似乎都还可以,但是版本却异常混乱,以至于演示前都不知道每个模块应该以哪台车的代码为准,A 车说自己测了哪些哪些功能都没什么问题,B 车说自己修复了很多问题是比较稳定的版本,…领导很头大,虽然最后每个模块都把自己觉得最优的版本确定下来了,但演示前重新联调还是碰到很多问题,最后匆忙上阵,还好演示过程比较顺利,但发布会后领导决定自此以后一定要做好版本管理,不允许这种情况再次发生。
从上面的情况可以看出版本管理的必要性,否则会给每个团队内部、团队之间、以及最后的版本集成造成很多麻烦,增加了开发和维护成本,甚至耽误产品开发的进度。
这里说的版本控制呢,涉及每个模块的代码管理、每日版本的构建、转测版本的构建,以及最终发布版本的集成构建等。每个模块都做好自己的代码管理,是最终团队能进行有效版本管理的基础。
为什么要进行版本控制,其实翻译下来就是为什么需要软件版本号,官方的说法
- 便于软件版本管理,跟踪软件产品
- 便于营销推广,与同类型的软件产品进行差异化比较
- 更好提供为用户提供软件技术支持(软件兼容性、软件缺陷)
三、版本管理
-
git 和 svn 是常用的代码管理工具。git 是分布式版本管理系统,每个人都在本地维护自己的版本,可以任意修改最终决定是否合入主干。svn 是集中式架构,通常有写保护,即可以多个人同时读,但只有一个人可写入。git 常用在平时的代码开发与维护,svn 常用在版本集成与资料维护等
-
其中 git 可以通过打标签 git tag 的方式进行版本管理,git tag 打标签的方法在上一篇文章中有介绍:git tag 打标签版本控制比较常用的几种命名方式:
-
GNU 风格版本号命名规则
-
主版本号.子版本号 [.修正版本号 [.编译版本号]] Major_Version_Number.Minor_Version_Number[.Revision_Number[.Build_Number]] 示例:1.2.1, 2.0, 5.0.0.build-13124
-
-
windows 风格的版本号命名规则
-
主版本号.子版本号 [修正版本号 [.编译版本号]] Major_Version_Number.Minor_Version_Number[Revision_Number[.Build_Number]] 示例: 1.21, 2.0
-
-
Net Framework 风格的版本号命名规则
-
主版本号.子版本号[.编译版本号[.修正版本号]] Major_Version_Number.Minor_Version_Number[.Build_Number[.Revision_Number]] 示例:暂无,待补充
-
-
语义化版本控制规范
-
主版本号.次版本号.修订号-先行版本号.标识符+版本编译信息 MAJOR.MINOR.PATCH-additional labels for preRelease.Identifiers+build metadata.Identifiers 示例:1.9.1, 1.10.0, 1.0.0-alpha.1+2021121914132, 1.0.0-alpha.beta
-
-
四、语义化版本控制规范
- 谁建立的
语义化版本控制的规范是由 Gravatars 创办者兼 GitHub 共同创办者 Tom Preston-Werner 建立。语义化版本控制规范官网
- 语义化版本控制的价值
解决”依赖地狱“问题,能对软件依赖关系和兼容性做清晰的说明,便于软件包管理
- 语义化版本控制对字符串长度是否有限制
无。但超过255字符的版本号已过度夸张
- 版本号递增规则说明(以下描述多读几遍就理解了)
主版本号:MAJOR, 当你做了不兼容的API修改
次版本号:MINOR, 当你做了向下兼容的功能性新增
修订号:PATCH, 当你做了向下兼容的问题修正
先行版本号:pre-Release, 表示这个版本并非稳定可能无法满足预期的兼容性需求
标识符:Identifiers, 用于标识先行版或版本编译信息的优先级
- 快速开发阶段版本命名规则
0.y.z
最简单的做法:以0.1.0 作为初始化开发版本,后续每次发行时递增次版本号,比如 0.2.0
- 什么时候发布 1.0.0
被用于正式环境时
已经有稳定的API供使用者依赖时
已经需要考虑向下兼容问题时
- 语义化版本控制规范细则
1. 标准版本号格式 X.Y.Z, 均为非负整数,每个元素以数值递增,如1.9.0->1.10.0->1.11.0
2. 已经标记号的版本发行号,禁止改变该版本的内容。任何修改都必须以新版本发行。
3. 0.y.z用于初始开发阶段,1.0.0用于界定公共API的形成。
4. 修订号的变更:x.y.Z, 必须在只做了向下兼容的修正时递增,修正指的是针对不正确的结果而进行的内部修改,如bugfix
5. 次版本号变更:x.Y.z, 必须在有向下兼容的新功能出现时递增,也可以在内部程序有大量新功能或改进被加入时递增,
其中包括修订级别的改变,如某次迭代新增了很多需求实现。
每当次版本号递增时,修订号必须归零
6. 主版本号变更:X.y.z, 必须在有任何不兼容的修改被加入公共API时递增。
可以包括此版本号及修订级别的改变。
每当主版本号递增时,次版本号和修订号必须归零
7. 先行版可以标定在修订版之,以"-"连接,再以"."加上标识符来修饰
标识符由ASCII字符数字和连接号来表示:0-9A-Za-z
如 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92
先行版的优先级低于相关联的标准版本
如 1.0.0-alpha < 1.0.0
8. 版本编译信息被标定在修订版或先行版本号之后,以"+"连接,再以"."加上标识符来修饰
示例:1.0.0-alpha+001, 1.0.0+20130313144700
9. 版本优先层级。指的是不同版本排序时如何比较。判断优先层级时,拆分后从左到右依序比较每个标识符
如 1.0.0 < 2.0.0 < 2.1.0 < 2.1.1
标准版本号相同时,比较先行版本号
如 1.0.0-alpha < 1.0.0
数字标识符比非数字标识符优先级低
如 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta
总之版本优先层级应从左到右比较,由第一个找到的差异值决定
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
- 采用语义化版本号是否必须按照如上规则
不一定,可以结合实际项目需要,但版本优先层级的比较要按照上述规则
比如 proj0.5_0.1.0_2021217.1
- 版本发布日志示例
五、git tag 打标签进行版本控制
- git tag 打标签进行版本管理时,可按照上述规则添加版本号
评论区