开源项目如何遵循语义化版本

wen 开源项目 1

本文目录导读:

开源项目如何遵循语义化版本

  1. 核心规则
  2. 特殊版本与版本范围
  3. 项目实践中需要遵守的关键点
  4. 常见误区与最佳实践

开源项目遵循语义化版本控制(SemVer,Semantic Versioning),核心目的是通过版本号清晰传达兼容性变化,它采用 主版本号.次版本号.修订号 的格式,并遵循以下规则:

核心规则

格式为:MAJOR.MINOR.PATCH5.1)。

  1. 主版本号 (MAJOR): 当你做了不兼容的 API 修改时递增。

    • 用户视角:升级到新主版本,代码很可能需要修改,现有功能可能无法正常工作。
    • 常见场景
      • 删除或重命名公开的函数、类、方法。
      • 修改函数参数类型或返回值类型。
      • 修改数据库表结构且不提供迁移。
      • 配置项语法或含义变化。
  2. 次版本号 (MINOR): 当你以向后兼容的方式添加功能时递增。

    • 用户视角:可以安全升级,新功能可用,旧代码不受影响。
    • 常见场景
      • 添加新的公开 API(函数、类、方法)。
      • 为现有功能增加可选参数。
      • 引入向后兼容的新配置项。
      • 标记某些旧功能为“废弃”(deprecated),但暂时保留。
  3. 修订号 (PATCH): 当你做了向后兼容的缺陷修复时递增。

    • 用户视角:可以安全升级,修复了 bug,无新功能。
    • 常见场景
      • 修复导致崩溃、错误结果的安全漏洞。
      • 修复文档错误。
      • 提高性能(不改变外部行为)。

特殊版本与版本范围

  • 预发布版本: 用 连接预发布标签。0.0-alpha.10.0-beta.30.0-rc.1

    • 规则:预发布版本优先级低于其对应的正式版本。
    • 使用场景:在正式大版本发布前,用于测试、收集反馈(Alpha 内测、Beta 公测、RC 候选版)。
    • 注意:用户应谨慎使用预发布版本,其 API 可能不成熟。
  • 构建元数据: 用 连接构建信息。0.0+build.20240101

    • 规则:构建元数据不影响版本优先级比较。
    • 使用场景:标识不同的构建环境(如 CI 构建编号)。

项目实践中需要遵守的关键点

  1. 明确公共 API: 项目必须明确定义并声明其公共 API,所有遵循 SemVer 的变更都基于这个公共 API。

    • 怎么做
      • 在文档(如 README.md,文档站点)中明确哪些是公共API。
      • 对于库,通常导出给用户使用的就是公共API。
      • 内部模块、私有函数不属此列,可以随时修改。
    • 示例:一个 Python 包在 __init__.py 中通过 __all__ 导出的函数和类是公共 API,其他下划线开头的函数是内部的。
  2. 版本号递增规则:

    • 初始开发阶段:通常从 1.0 开始,在 x.y 阶段,主版本号为 0,API 不稳定,任何变化都可能不兼容
    • 正式发布 (1.0.0):当项目 API 稳定且被用于生产环境时,发布 0.0
    • 递增顺序
      • 修复 bug 后:0.0 -> 0.1
      • 新增向后兼容功能后:0.1 -> 1.0
      • 做了不兼容修改后:1.0 -> 0.0
  3. 依赖项管理:

    • 在语义化版本和依赖描述中,通常使用范围约束,允许兼容更新。
      • ^1.2.3:允许 >=1.2.3<2.0.0(即主版本不变)。
      • ~1.2.3:允许 >=1.2.3<1.3.0(即只允许修订号更新)。
      • >=1.2.3 <2.0.0:更加精确地允许主版本不变的任何次版本和修订号更新。
    • 重要:如果你的项目作为库被他人使用,描述你的依赖关系时,尽量明确兼容范围,避免锁定精确版本,这有助于下游用户解决依赖冲突。

常见误区与最佳实践

  • 误区:认为大版本号只代表大重写任何不兼容的改动,即使非常小(例如只改了函数参数类型),都需要递增主版本号。
  • 误区:认为 x.y 不需要 SemVer需要x.y 遵循相同规则,但主版本号为 0 阶段 API 不稳定,你可以随时做不兼容修改并递增次版本号(1.0 -> 2.0 视为不兼容)。
  • 最佳实践
    • 在发布前仔细检查是否增加了新功能、修复了 bug、做了不兼容更改。
    • 在 CHANGELOG 中记录变更,说明每个版本的变化,并注明每个变化是新增、修复还是破坏性变更,这有助于用户了解升级的影响。
    • 使用自动化工具:许多语言(如 Rust 的 cargo semver-checks,Go 的 gorelease,Node.js 的 semantic-release 等)可以自动检查 API 变化并建议正确的版本号。
    • 谨慎对待“废弃”功能:用次版本号标记废弃,但不要立刻删除,在下一个主版本中才最终移除,给用户留出迁移时间。
版本号组成部分 何时增加 对用户的影响
主版本 (MAJOR) 不兼容的 API 修改 需要修改代码
次版本 (MINOR) 向后兼容的新功能 可安全升级,新功能可用
修订号 (PATCH) 向后兼容的 Bug 修复 可安全升级,无新功能

遵循语义化版本的核心是诚实、明确地传达你的改动对下游用户的影响,它让用户能放心地更新依赖,从而推动整个开源生态的健康协作。

抱歉,评论功能暂时关闭!