版本的故事(五)闯关旅程

对于代码的任何一次修改都会形成一个“版本”,其中的大部分版本是没有必要发布的,它们只是普通的提交。当开发人员完成一个里程碑计划,就在这个提交上创建一个基线(具体操作在 Git 平台上创建一个 Tag),标记这个特殊的提交,形成一个正式的“版本”。

一些研发团队使用“持续集成”开发过程,对每一个提交,都编译一个二进制包,将这二进制包部署在集成环境里,频繁进行集成测试,提高质量和工作效率。对于这些频繁的提交,不必为每一个二进制包编一个正式的版本号,我们可以用“SNAPSHOT”后缀标识这些频繁集成的版本。“SNAPSHOT”版本也称作“开发版”,例如:“1.2.3-SNAPSHOT”就是“正在开发中的1.2.3版本”。连续多个版本的名称都是相同的,这样就不必频繁改动部署脚本,可以加快集成部署的频率。

 

 

SNAPSHOT版本是不能作为正式版本发布给用户的,因为它们是“不稳定”的。“不稳定”的一个含义是这些版本还在开发中,没有经过测试验证,质量不稳定;另一个含义是其二进制包是不稳定状态,随时可能会被下一次提交覆盖。如果这样的版本发布出去,就会形成无法回溯的版本,给维护带来麻烦。

开发人员创建Tag,编译一个二进制包,提交给测试人员进行测试,这个版本称之为“候选发布版本”(Release candidate,简称 RC)。从现在开始,二进制包进入了一个“闯关旅程”。闯关成功才能成为真正的“Release”版本。

对于代码的任何一次修改都有被发布出去的可能性。开发人员问自己:“我们这次修改的版本是否应该发布出去?”,得到的答案只是一次臆测的结果。后续的一系列过程:构建、部署、测试流程能够验证是否可以发布这个版本,不断让我们增强信心。尽管每次修改都可以产生一个能够交给用户的最终产物,但是我们应该首先对每次修改都进行适用性评估。只有这次修改没有缺陷,并且满足由客户定义的验收条件,才能够发布它。——以上内容摘录自《持续交付:发布可靠软件的系统方法》

Snapshot——Release candidate——Release,这就是一个发布包的“闯关旅程”,能不能过关,取决于研发人员和测试人员的验证结果。

 

 

有一些团队制定了版本号命名规范,为发布候选版和发布版添加不同的后缀,比如“2.0.5.RC”、“2.0.5.RELEASE”,这样用户可以从版本号上判断它的质量等级。然而这也不是绝对准确的,因为即使是发布版,也有可能随时发现一个缺陷,成为一个废弃版本。所以一种普遍的做法是:只在快照版上使用“SNAPSHOT”后缀,发布候选版和发布版没有后缀,用户需要关注软件的发布说明,确定某个版本的质量水平。

安装包如何保存?放进版本库里通常不是明智之举。版本库通过增量存储来减少存储所消耗的磁盘空间,但是这通常是对文本文件有效。对于文本文件,比如源代码文件,只记录文件的那几行更改了,而非整个新版本,以此来减少存储消耗的磁盘空间。对于二进制的安装包,这个办法则难以实现。而另一方面,对于安装包,很多历史版本,比如送去测试用的安装包,是不值得长期保存的,需要定期清理,否则会占用大量的磁盘空间。版本库原则上保存全部历史版本,如果要删除已经没用的历史版本,会很麻烦。不像在平常的文件系统上。因此,用版本库来存储安装包,反而带来不便。——以上内容摘录自《理解软件配置管理》

在很多企业内部,采用一些专门的二进制包管理的工具。研发人员提交代码,自动打包,上传到二进制包管理平台,自动部署工具从平台上下载二进制包,部署到测试环境上——这就是持续集成、持续交付的过程。有很多非常好的开源二进制包管理平台,以下是其中非常著名Nexus:

Nexus 是一个强大的二进制包管理平台,支持几乎所有的技术路线,比如Maven、NPM、RPM、Docker 等等,还支持原始二进制包。关于二进制包管理平台的使用,有两点需要注意:

1:对于公司正在使用的第三方系统的安装包,比如MySQL、MongoDB、各种开发库,应该把它们的二进制包保存到内部的二进制包管理平台上。这样不仅可以规范管理所有的版本,避免开发人员使用一些来源不明的软件,还能加快下载速度,节约时间。

2:对于自研的模块,应该建立多个仓库,把不同质量等级的二进制包分别保存到不同的仓库。研发人员提交代码,编译产物上传到快照库;完成里程碑任务,生成发布候选版本,上传到发布候选库;测试合格的版本上传到发布库。这样可以对不同的仓库采用不同的管理策略,比如定期清理快照库,发布候选版本保留3年,发布版仓库采用最高级别的存储设备,确保永久保存。