本文目录导读:

- 方案一:语义化版本(Semantic Versioning,简称 SemVer)—— 最推荐、最通用
- 方案二:基于日期的版本号(CalVer,Calendar Versioning)
- 方案三:特定生态或框架的版本风格
- 如何为你的项目制定规范?(决策步骤)
- 总结建议
制定开源项目的版本命名规范,核心目的是让用户、贡献者和开发者能够清晰、无歧义地了解每个版本的兼容性、稳定性和变更程度。
没有一个放之四海而皆准的“唯一”规范,但业界有几种成熟且广泛采用的做法,选择哪一种,通常取决于项目的类型(库、框架、应用、游戏)、目标受众以及开发节奏。
以下是制定开源项目版本命名规范的几种主流方案及其制定要点:
语义化版本(Semantic Versioning,简称 SemVer)—— 最推荐、最通用
这是开源世界最流行、最核心的规范,它为版本号赋予了明确的语义,告诉你升级是否会有破坏性。
格式: 主版本号.次版本号.修订号 (5.3)
- 主版本号(MAJOR): 当做了不兼容的 API 或功能修改时增加。(用户升级需谨慎,可能无法直接替换)
- 次版本号(MINOR): 当做了向下兼容的功能性新增时增加。(用户升级通常很安全,只是多了新功能)
- 修订号(PATCH): 当做了向下兼容的问题修正(Bug 修复)时增加。(用户升级最安全,只是修了Bug)
制定要点(需在文档中明确):
- 定义“主版本号”的触发条件: 是任何API变更,还是只有破坏性变更?如果项目是前端UI组件,重大视觉重构算不算?需要明确。
- 预发布版本: 可以附加后缀,如
-alpha.1,-beta.2,-rc.1,这些版本优先级低于正式版本。5.3-beta.2 < 2.5.3。 - 构建元数据: 可以附加 号,如
0.0+build.1234,但这不影响版本优先级。 - x.y 阶段: 主版本号为 0 表示项目处于初始开发阶段,不承诺稳定性,任何变更(包括破坏性变更)都可以只增加次版本号。
- 优点: 清晰、标准化、生态系统支持好(npm、pip、Maven等包管理器都支持依赖范围约束)。
- 缺点: 对开发者纪律要求较高;对于持续交付的Web应用或服务,频繁的版本号变化意义不大。
基于日期的版本号(CalVer,Calendar Versioning)
如果你维护的是一个持续迭代的客户端应用、库或服务,版本号代表的是发布的时间点,而不是语义的兼容性。
格式示例:
YY.MM.DD(如12.15)YYYY.MM(如12)YY.Week(如50)
知名例子: Ubuntu(22.04)、Node.js(22.x 主线)、Google Chrome(120.x)。
制定要点:
- 时间粒度: 年度、月度还是每日?取决于你的发布频率。
- 是否需要补丁号: 如果一个月内发布了多次修复,可以加后缀
YY.MM.PATCH。 - 与语义化的结合: 很多项目在日期主版本下,结合语义化次版本。
12.1(2024年12月的第一个补丁)。
- 优点: 简单、直观,用户能直接知道版本新旧,适合不需要严格向后兼容性承诺的场景(如日常工具、Web应用)。
- 缺点: 无法直观判断升级是否会破坏现有功能。
特定生态或框架的版本风格
有些大型项目形成了自己的惯例,跟随它们可以降低用户的学习成本。
- Linux 内核风格: X.Y.Z (如
12.3),偶数Y表示稳定版,奇数Y表示开发版。 - Python 风格(PEP 440): 遵循SemVer但更严格。
2.3a4(Alpha版本)、2.3.dev5(开发版)。 - Go Modules 风格: 依赖模块路径和版本号一起管理,主版本号 >=2时,路径会带上
/v2。
如何为你的项目制定规范?(决策步骤)
-
定义你的项目类型:
- 底层库/框架/API -> 强烈推荐 SemVer,用户依赖你,兼容性至关重要。
- 客户端应用/游戏/终端工具 -> SemVer 或 CalVer 均可,如果用户经常需要手动升级,CalVer更直观,如果希望用户精确控制依赖,SemVer更好。
- SaaS/Web服务 -> CalVer 或 简单的递增整数 更合适(如
v2024.12),因为服务是后端部署,用户端不需要关心版本兼容性。 - 内部分支/开发流程 -> 可以只用 Git Tag(如
v1.2.3-beta)配合 CI/CD 的构建号。
-
明确强制规则(写在
CONTRIBUTING.md或README.md):- 谁来决定版本号的增加?(通常是维护者通过 Issue 或 PR 标签决定)。
- 是否使用 SemVer? 如果是,必须明确声明。
- 预发布版本怎么写?
-alpha,-beta,-rc,后跟数字。 - 特殊情况如何处理? 比如安全修复热更新(通常只升补丁号),或清理陈旧API时(升主版本号)。
- 版本号的显示格式: 是否带
v前缀(如v1.2.3还是2.3)?建议统一,Git Tag 常用v前缀。
-
编写正式文档:
- 在项目根目录创建
VERSIONINGS.md或CHANGELOG.md中说明版本策略。 - 明确说明版本号变更的触发条件。
- 提供示例。
一个简单的示例文档(基于 SemVer):
# 版本命名规范 本项目遵循 [语义化版本 2.0.0](https://semver.org/lang/zh-CN/)。 **格式:** `主版本号.次版本号.修订号` - **主版本号:** 当进行不兼容的 API 修改时增加,用户升级前请仔细阅读升级指南。 - **次版本号:** 当添加新的向后兼容的功能时增加,用户可放心升级。 - **修订号:** 当进行向后兼容的 Bug 修复时增加,用户应尽快升级。 - **预发布版本:** 在数字后添加 `-alpha.x`、`-beta.x` 或 `-rc.x`。`1.0.0-rc.1` 表示第一个发布候选版本。 - **重要:** 版本号不带 `v` 前缀(Git Tag 除外,统一使用 `v` 前缀,如 `v1.2.3`)。 **变更类型与版本号对应关系:** | 变更类型 | 版本号变更 | |---|---| | 新增功能(向后兼容) | 次版本号 +1 | | 修复 Bug(向后兼容) | 修订号 +1 | | 破坏性 API 变更 | 主版本号 +1 | | 内部重构、文档、测试 | 不触发版本号变更 |
- 在项目根目录创建
总结建议
- 新项目、库、框架: 无脑选 SemVer,这是通用语言,降低沟通成本。
- 现有应用的次要版本: 可以稍微放宽,在
README中声明“我们尽力遵循SemVer,但不保证严格。” 用户知道是风险较小的升级。 - 维护一个大项目(如 CLI 工具、游戏引擎): 结合 CalVer 主版本 + SemVer 次/修版本,或者使用 SemVer + 预发布 来管理大版本之间的快速迭代。
- 最终目标: 为你的用户提供确定性,无论选哪种规范,一致执行比选哪个更重要,在文档中明确说明,并严格遵守。