目录

项目开发维护 | 版本规范

1. 版本规范

1.1. 语义化版本规范(SemVar)

目前(2021.07)业界主流的版本规范是语义化版本规范。语义化版本规范(SemVer,Semantic Versioning)是 GitHub 起草的一个具有指导意义的、统一的版本号表示规范。它规定了版本号的表示、增加和比较方式,以及不同版本号代表的含义。在这套规范下,版本号及其更新方式就包含了相邻版本间的底层代码和修改内容的信息。

语义版本格式为:主版本号.次版本号.修订号(X.Y.Z),其中 X、Y 和 Z 为非负的正数,且禁止在数字前方补零。每个元素必须以数值来递增。例如:1.1.1 -> 1.2.0 -> 1.3.0。一个例子如下所示,v1.2.3 就是一个语义化版本号。

  • 主版本号(MAJOR):当做了不兼容的 API 修改。
  • 次版本号(MINOR):当做了向下兼容的功能性新增及修改。这里有个不成文的约定需要注意,偶数为稳定版本,奇数为开发版本。
  • 修订号(PATCH):当做了向下兼容的问题修正。

之外,还有一种版本号是把先行版本号(Pre-release)和版本编译数据,作为延伸加到了上述的版本号后面,格式为 X.Y.Z[-先行版本号][+版本编译元数据],一个例子如下所示:

  • 先行版本号,可以被标注在修订版之后,被标上先行版本号则表示这个版本并不稳定且可能无法满足预期的兼容性要求。带先行版本号的格式为:X.Y.Z-先行版本号,先行版本号必须由 ASCII 字母数字和连接号 [0-9A-Za-z-] 组成,数字型的标识符禁止在前方补零,且禁止有空格。

    比如下面这几个例子:

    1
    2
    3
    4
    
    1.0.0-alpha
    1.0.0-alpha.1
    1.0.0-0.3.7
    1.0.0-x.7.z.92
    
  • 版本编译元数据,一般是编译器在编译过程中自动生成。编译元数据可以被标注在修订版或先行版本号之后,先加上一个加号(+),再加上一连串以句点分隔的标识符来修饰。标识符必须由ASCII字母数字和连接号 [0-9A-Za-z-] 组成,且禁止留白。

    下面是一些编译版本号的示例:

    1
    2
    3
    
    1.0.0-alpha+001
    1.0.0+20130313144700
    1.0.0-beta+exp.sha.5114f85
    

1.2. 语义化版本控制规范

语义化版本控制规范比较多,这里只列出几个比较重要的。如果需要了解更详细的规范,可以参考这个链接(https://semver.org/lang/zh-CN/)的内容。

  • 使用语义化版本控制的软件必须定义公共API。该API可以在代码中被定义或出现于严谨的文件内。无论何种形式都应该力求精确且完整。

  • 标记版本号的软件发行后,禁止改变该版本软件的内容,任何修改都必须以新版本发行。

  • 主版本号为零(0.y.z)的软件处于开发初始阶段,一切都可能随时被改变,这样的公共 API 不应该被视为稳定版。1.0.0 的版本号被界定为第一个稳定版本,之后的所有版本号更新都基于该版本进行修改。

    1.0.0 的版本号用于界定公共API的形成,这一版本之后所有的版本号更新都基于公共 API及其修改内容。

  • 修订号 Z(x.y.Z | x > 0)必须在只做了向下兼容的修正时才递增,这里的修正其实就是 Bug 修复。

  • 次版本号 Y(x.Y.z | x > 0)必须在有向下兼容的新功能出现时递增,在任何公共 API 的功能被标记为弃用时必须递增,当这些公共 API 有改进时可以递增。其中可以包括修订级别(修订号那个修订)的改变。每当次版本号递增时,修订号必须归零。

  • 主版本号 X(X.y.z | X > 0)必须在有任何不兼容的修改被加入公共 API 时递增。其中可以包括次版本号及修订级别的改变。每当主版本号递增时,次版本号和修订号必须归零。

  • 不同版本在判断优先层级时,必须把版本依序拆分为主版本号、次版本号、修订号及先行版本号后逐次进行比较。

1.3. 如何确定版本号

有这么几个经验(孔令飞说):

  • 在实际开发的时候,我建议你使用 0.1.0 作为第一个开发版本号,并在后续的每次发行时递增次版本号。
  • 当我们的版本是一个稳定的版本,并且第一次对外发布时,版本号可以定为 1.0.0。
  • 当我们严格按照 Angular commit message 规范提交代码时,版本号可以这么来确定:
    • fix 类型的 commit 可以将修订号 +1。
    • feat 类型的 commit 可以将次版本号 +1。
    • 带有 BREAKING CHANGE 的 commit 可以将主版本号 +1。

在做 Go 项目开发时,我建议你把所有组件都加入版本机制。原因主要有两个:一是通过版本号,我们可以很明确地知道组件是哪个版本,从而定位到该组件的功能和代码,方便我们定位问题。二是发布组件时携带版本号,可以让使用者知道目前的项目进度,以及使用版本和上一个版本的功能差别等。

1.4. 版本规划链接

https://semver.org/lang/zh-CN/

1.5. 巨人的肩膀

  1. 极客时间.孔令飞.《Go 语言项目开发实战》