侧边栏壁纸
博主头像
汪洋

即使慢,驰而不息,纵会落后,纵会失败,但一定可以达到他所向的目标。 - 鲁迅

  • 累计撰写 191 篇文章
  • 累计创建 74 个标签
  • 累计收到 112 条评论

版本管理 - 语义化版本控制规范

汪洋
2022-04-28 / 0 评论 / 2 点赞 / 372 阅读 / 3,199 字

一、序言

  • 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 打标签进行版本管理时,可按照上述规则添加版本号
0

评论区