语义版本规范
参照语义版本规范 2.0.0-rc.1 标准,终于搞清楚那些个xxxx.xxxx.xxxx版本号到底是啥意思,也自己参照着定一个扩展版 ……
软件发布时,每个发布版本由 x.y.z.r 即主版本号、次版本号、修订号、构建号,四个部分组成。
- 构建号是构建版本时对应的 SVN 版本号,这是一个持续递增的编号,从来不会归零。
- 0.y.z.r 这样的版本号通常用于在项目开始阶段项目组内部使用或发布给内部测试,通常不对外发布,这个阶段的 API 可以不做任何兼容性的担保。
- 从 1.0.0.r 开始对外发布,此版本后版本号递增的方式是依赖于这个公共API如何变化。
- 如果新发布的版本是仅仅针对某版本的BUG修复,对外API接口不发生任何变化,则递增内部版本号 Z
- 如果新发布的版本引入的新的对外API接口,但原有接口原版本保持向后兼容,则递增次要版本号 Y,并归零修订号 Z
- 如果新发布的版本和原有版本不保持向后兼容,则递增主版本号 X,并归零次版本号 Y 以及修订号 Z
关于版本号管理、兼容性以及版本号与SVN版本管理结合的一些说明:
- 针对 DOTNET 工程,通常一个工程仅包含一个单一的 DLL 或者 EXE,因此保证该软件包的版本和对应 DLL 或者 EXE 的文件版本号是一致的。
- 根据版本号发展规则的定义,可以看出在主版本一致的情况下进行版本升级理论上是安全可靠的,例如原来引用的某个组件的版本 1.3.2.r,则升级到任何 1.3.2.r以后,2.0.0 之前的版本,都不会引人编译错误或者接口不兼容。
- 版本的升级并非取决于发布,而是取决于是否决定进行对外接口的变更,例如在 1.0.0 版本发布后,并不计划加入新功能,而仅仅是内部的重构或者BUG修改,那么就不应该递增次版本号。另一种情况是,通常会发布一些未完全完成的部分版本,例如 1.0.0 中可能有部分功能是标示为未实现的,继续完成这些未实现的版本,也不应该递增次版本号。仅仅当决定引入新的对外接口以后,才应该递增次版本号。
- 简单起见,通常在软件发布时并不进行版本库的分支处理,可以在收到 BUG 报告并计划进行修复时,才针对该版本创建分支并切换到分支进行开发。例如,在发布了版本 1.0.0.r 以后,由于引入的新的功能,主线上版本已经升级为 1.1.z.r,那么收到 1.0.0.r 的BUG并准备修复时,必须在 SVN 创建 R 构建号对应的分支,并切换到该分支进行BUG修复,然后发布的版本应该是 1.0.1.r2 (当然这个分支的一些修改可能还要考虑合并到主线上去),再针对 1.0.1.r2进行被动或者主动修订,则可以在此分支上直接继续工作即可了。
- 现在的IDE重构功能都太强大了,因此一旦版本发布,要保持向后兼容,通常就是一件需要小心翼翼的事情,一不小心,可能就因为重构改变了某个对外接口的签名,结果打破了向后兼容性,这对于一些基础组件无疑是个悲剧。可以考虑采用一个独立的单元测试包来测试版本兼容性,通常这个单元测试包应该在独立解决方案中(针对DOTNET而言)以免它被不小心的重构了,一旦产品发布,该单元测试包通常也停止继续追加测试,在持续开发过程中,需要不时的运行一下该单元测试,以保证向后兼容性没有问题。
语义版本规范原文请参考 http://semver.org/