Appearance
在现代软件开发中,依赖管理是一个核心挑战。为了在复杂的依赖关系中清晰地传达变更的性质与风险,业界形成了一套广泛采纳的规范 —— 语义化版本控制(Semantic Versioning, SemVer)。它不仅是一种版本编号方案,更是一种开发者之间的沟通契约。遵循 SemVer 规范,能极大地提升软件生态的稳定性和可预测性。
本文将快速解析 SemVer 2.0.0 的核心规则。
1. 基石:公共 API 的定义
任何采用 SemVer 的软件,必须声明一个公共 API(Public API)。这个 API 是软件与外部世界交互的契约,其稳定性是版本控制的依据。
- 形式: API 可以通过代码本身(例如,公共类、方法、模块导出)明确定义,也可以在严谨、详尽的文档中进行阐述。
- 要求: 无论形式如何,API 的定义都必须精确且完整,以便使用者能够清晰地理解其功能、参数和行为。
2. 版本号结构
标准的版本号必须采用 X.Y.Z
的格式,它由三个非负整数部分组成:
- X: 主版本号 (Major)
- Y: 次版本号 (Minor)
- Z: 修订号 (Patch)
格式要求:
- 各部分数值以点(.)分隔。
- 禁止在数字前方补零(例如,
1.01.2
是无效的)。 - 版本号的递增是基于数值的,而非字符串。例如:
1.9.0
->1.10.0
->1.11.0
。
3. 版本更新的核心准则
版本号的更新直接反映了其底层代码变更的性质。
初始开发阶段:0.y.z
主版本号为 0
的版本(如 0.1.0
, 0.2.5
)被视为初始开发阶段。在此阶段,公共 API 尚不稳定,可能随时发生不兼容的变更。因此,不应将其用于生产环境或视为稳定的依赖。
正式发布:1.0.0
1.0.0
版本的发布是一个重要的里程碑,它标志着稳定的公共 API 的诞生。从这个版本开始,所有的版本号更新都必须严格依据公共 API 的变更来执行。
版本递增规则 (当 X > 0):
修订号 (Z) 的递增: 当且仅当进行了**向后兼容的错误修复 (backwards-compatible bug fixes)**时,才递增修订号。例如,修复了一个导致不正确输出的内部缺陷。
x.y.Z
->x.y.(Z+1)
次版本号 (Y) 的递增: 当引入了**向后兼容的新功能 (backwards-compatible new functionality)时,递增次版本号。此外,当任何公共 API 的部分被标记为弃用 (deprecated)**时,也必须递增次版本号。此级别的更新可以包含修订级别的变更。递增次版本号时,修订号必须归零。
x.Y.z
->x.(Y+1).0
主版本号 (X) 的递增: 当发生任何**不兼容的 API 变更 (incompatible API changes)**时,必须递增主版本号。这包括移除、重命名或修改现有 API 的签名。此级别的更新可以包含次版本和修订级别的变更。递增主版本号时,次版本号和修订号都必须归零。
X.y.z
->(X+1).0.0
4. 扩展标识符
为了标记预发布版本或附加构建信息,SemVer 允许在核心版本号后添加扩展标识符。
先行版本号 (Pre-release Version)
用于标记不稳定的预发布版本,如 alpha
, beta
, rc
。
- 格式: 在修订号后附加一个连字符(
-
)和一系列点分隔的标识符。 - 标识符: 仅允许使用 ASCII 字母数字和连字符
[0-9A-Za-z-]
。数字标识符禁止前导零。 - 优先级: 先行版本的优先级低于其关联的常规版本。例如,
1.0.0-rc.1
的优先级低于1.0.0
。 - 示例:
1.0.0-alpha
,1.0.0-alpha.1
,1.0.0-0.3.7
,1.0.0-x.7.z.92
。
版本编译信息 (Build Metadata)
用于附加构建过程中的元数据,如编译时间戳、Git-hash 等。
- 格式: 在修订号或先行版本号后附加一个加号(
+
)和一系列点分隔的标识符。 - 标识符: 规则与先行版本号相同。
- 优先级: 在进行版本优先级比较时,必须忽略版本编译信息。因此,仅编译信息不同的两个版本(如
1.0.0+20230101
和1.0.0+20230102
)优先级相同。 - 示例:
1.0.0-alpha+001
,1.0.0+20130313144700
,1.0.0-beta+exp.sha.5114f85
。
5. 版本的不可变性
这是一个基础但至关重要的原则:一旦一个版本被发布,其内容便不可变更。任何后续的修改都必须作为新版本重新发布。这保证了版本号的引用是确定和可靠的。
6. 优先级与比较规则
版本的优先级决定了其在依赖解析和排序中的顺序。比较规则如下:
比较顺序: 依次比较
主版本号
、次版本号
、修订号
。这三者都按数值大小进行比较。- 示例:
1.0.0
<2.0.0
<2.1.0
<2.1.1
- 示例:
先行版本的介入: 当主、次、修订号均相同时,拥有先行版本号的版本优先级更低。
- 示例:
1.0.0-alpha
<1.0.0
- 示例:
先行版本间的比较: 若两个版本的主、次、修订号相同,则需逐个比较由点分隔的先行版本标识符:
- 数字标识符按数值比较。
- 字母或混合标识符按 ASCII 字典序比较。
- 数字标识符的优先级低于非数字标识符。
- 当比较到某处时,若一个版本的标识符字段更多,则其优先级更高。
- 综合示例:
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
SemVer 规范为软件版本管理提供了一套清晰、通用且富有表达力的语言。它通过严格的规则,将版本号与软件的 API 变更直接挂钩,从而使开发者能够安全、高效地管理项目依赖,避免了“依赖地狱”的困境。准确理解并应用 SemVer,是每一位专业软件工程师必备的技能。