1. 引言

语义化版本号(简称 SemVer)是一种被广泛采用的版本控制方案,被大量开源项目用于表达版本更新中所包含的变更内容。作为开发者,理解如何在自己的项目中使用 SemVer,以及如何解读版本变更的含义,是非常重要的。

本教程将带你了解 SemVer 规范的核心概念。

2. 为什么软件版本号很重要?

软件版本号帮助我们为软件或包的不同状态赋予一个唯一的标识。它有助于开发者追踪所依赖的第三方软件或库的变化。

版本控制方案有很多种,其中语义化版本号(SemVer)是由 Tom Preston-Werner 于 2013 年提出的一种流行方案,用于规范版本号的使用方式。

3. 什么是 SemVer?

在 SemVer 的规范下,版本号采用如下格式:

Screenshot-2021-03-06-at-20.27.22

其中 x、y、z 是整数,分别表示主版本(Major)、次版本(Minor)和修订版本(Patch)。

SemVer 规范假定使用该方案的项目必须有一个公开的 API。下面我们从左到右依次介绍每个部分。

3.1. 主版本(Major)

当你引入了破坏性变更(Backward-incompatible)时,应增加主版本号。 比如:删除或修改了某个公开 API 的行为。

每次主版本号增加时,次版本号和修订号都应重置为 0。

✅ 示例:从 1.2.5 升级到 2.0.0,表示引入了不兼容的变更。

3.2. 次版本(Minor)

当你新增了功能,但这些功能是向后兼容的(Backward-compatible),应增加次版本号。 也可以用于内部代码的重大重构,只要不影响 API。

次版本号变更时,修订号应重置为 0。

✅ 示例:从 2.0.1 升级到 2.1.0,表示新增了功能但没有破坏性变更。

3.3. 修订版本(Patch)

当你只修复了 bug,没有引入新功能或破坏性变更时,应增加修订版本号。

修订版本变更不应影响公开 API。

✅ 示例:从 2.1.0 升级到 2.1.1,仅修复了 bug。

3.4. 预发布(Pre-release)和构建元数据(Build)

在 patch 之后可以添加可选的标签,用于表示预发布版本或构建信息。

  • 预发布标签:通过 - 添加,如 1.0.0-alpha.1,表示该版本为预发布,可能存在风险。
  • 构建信息:通过 + 添加,如 1.0.0-alpha.1+001,用于标识构建编号,不影响版本优先级。

⚠️ 注意:预发布版本的优先级低于正式版本。例如:1.0.0-alpha < 1.0.0

4. 开发阶段的版本号(0.x.y)

SemVer 规定版本号以 0.x.y 形式表示开发阶段。此时项目被认为是不稳定的,API 可能随时变更。

通常新项目从 0.1.0 开始开发,表示初始功能版本。开发阶段应保持主版本为 0,直到进入稳定阶段再升级到 1.0.0

5. 为什么 SemVer 如此流行?

SemVer 在近年来越来越受欢迎,原因如下:

✅ 简洁易用,便于追踪变更
✅ 可通过版本号快速判断变更类型(破坏性 / 非破坏性)
✅ 可帮助评估升级风险
✅ 有助于避免“依赖地狱”(Dependency Hell),通过版本范围机制管理依赖
✅ 被 npm、Maven、Gradle 等主流工具广泛支持

6. 其他常见的版本控制方案

除了 SemVer,还有一些其他版本控制方式:

  • CalVer:基于发布日期的版本号,如 2021.03.06,适用于 Python 的 pip 和 Ubuntu 等
  • Python 版本规范:PEP 440 定义了包括 epoch、release、pre-release 等多个段的版本结构
  • 命名版本:如 Android 的 Cupcake、Donut、Eclair 等
  • Spring Framework 命名方式:扩展了 SemVer,加入了 RC(Release Candidate)和 BUILD-SNAPSHOT 等标识

7. 总结

SemVer 并不是唯一可用的版本控制方式,但它简单、清晰,尤其适合开源项目和依赖管理。

本文简要介绍了 SemVer 的基本概念和使用方法,帮助你理解版本号背后所传达的含义。合理使用语义化版本号,有助于提升项目的可维护性和协作效率。


原始标题:A Guide to Semantic Versioning