<audio id="audio" title="35 | 版本发布：软件上线只是新的开始" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/8b/51/8bde1335e4db9e29b29dd23bd7fcc451.mp3"></audio>

你好，我是宝玉。上一章我们学习了软件测试篇，今天，我们将从版本发布这个话题开始，进入到运行维护篇的学习。

说到版本发布，对于很多开发人员来说，觉得是一件很简单的事情，就是将程序编译打包部署，但实际发布的时候，却经常出现发布错版本的问题，或者是发布前修改了一点代码导致上线出现Bug的情况发生。

而版本发布对于很多项目管理者来说，又是一个很纠结的事情，觉得还有很多功能没完成，很多Bug还没改完，害怕用户负面评价，结果时间一拖再拖，迟迟无法上线。

所以今天我将带你一起学习一下如何做好版本发布，保障好发布产品的质量。

## 关于软件版本

在讨论这个话题之前，我们需要了解“版本”的含义。也许你已经知道版本的含义，但是这里还是有必要明确一下，因为在不同的语境下，版本的含义也有所不同。比如产品经理会对开发人员说：“这个功能我们会放到下个版本中实现”，开发人员会对测试人员说：“这个Bug在昨天的版本中已经修复了”。

这里产品经理说的“版本”是指特定功能集合，开发人员说的“版本”是指某一次程序的构建结果。也就是说对软件版本来说，包含两部分含义，一部分代表特定功能集合，一部分代表某一次特定的代码构建结果。

为了明确标识软件版本，需要对版本进行编号。目前业界在软件版本的命名上，通常会采用以下方式：

> 
主版本号 . 子版本号.[.修正版本号.[构建版本号]]


比如说：1.2.1、2.0、3.0.1 build-123。

其中主版本号和子版本号用来标识功能变化，小的功能变化增加子版本号，大的功能变化增加主版本号。修正版本号则表示功能不变化的情况下修复Bug，而构建版本号表示一次新的构建，这个通常由编译程序自动生成。

团队中对版本有了清晰的定义和良好的版本编号，在讨论版本时，你就可以根据版本号清楚地知道应该有哪些功能，属于哪一次的构建结果。在修复Bug或者增加功能时，开发人员也能清楚地知道代码应该加入哪个版本。在验证Bug时，测试人员就可以知道应该在哪个版本中验证Bug有没有被修复。

## 版本发布前，做好版本发布的规划

回到前面的问题，为什么有的项目管理者会在发布前感觉没准备好，害怕上线发布呢？根源上，他们还是对于功能和质量没有信心，担心发布后获得负面的评价。

而实际上，并不代表你需要完成所有的功能，或者没有任何Bug，有一个完美的版本才能上线。毕竟追求完美是没有止境的，这世界上也不存在完美的软件，很多著名的软件，比如Windows、Office、iOS都免不了在发布后还要打补丁。

这里的关键在于，**要在用户（或客户）的心理预期和你软件的实际情况之间，达到一种平衡，让软件的功能和质量，满足好用户的预期。**

要合理管理好用户的预期，达到好的发布效果，就需要在版本发布前先做好版本发布的规划。

那么，版本的发布规划，是指规划哪些内容呢？

**首先是规划好要发布的功能。**在发布前，搞清楚哪些是用户必须要有的功能，哪些是用户可以没有的功能。对于必须要有的功能，那么要保证软件中有这个功能才能发布，对于不是必需的功能，可以以后再逐步完善。

有一个经典的案例就是第一代的iPhone，复制粘贴的功能都没有，但是在用户界面和触屏设计上做的非常好，一样取得了极大的成功。

然后是定义好发布的质量标准。在发布前，搞清楚你的用户对质量的容忍度如何，对哪些功能的质量要求高，对哪些功能的质量要求没那么高。对于那些用户在意的功能，要具有较高的发布标准，反之，则可以有较低的质量标准。

举例来说，像微博这种社交类应用软件，界面布局存在一点问题，用户是可以接受的，但是如果撰写内容的时候，因程序异常导致辛辛苦苦写的内容丢失，用户是比较难以忍受的。

**再有就是要设计好发布的策略。**考虑好是直接发布给所有用户？还是先让一部分用户试用？比如说可以先让内部用户使用，内部用户对软件质量问题容忍度是很高的，还可以帮助发现很多问题。

让一部分用户使用Beta版也是一个好的发布策略，当用户知道你的软件还是Beta版的时候，要求会比较低一点，可以接受一些不那么严重的Bug。 还有就是采用灰度测试的发布策略，让一小部分用户先用新功能，如果没发现什么问题，再继续扩大使用的用户规模，如果有问题，也只是影响少量用户。

像Gmail在最初的几年，一直是Beta版本测试。还有像苹果的iOS，用户也可以选择安装最新的Beta版本，可以先体验新功能，但是必须忍受系统的不稳定。

**最后，就是有一个综合性的版本发布计划。**在确定了要发布的功能、定义好了质量标准、设计好了发布策略，就可以制定一个综合性的版本发布计划了，确定好发布的时间点。

这个发布计划，不只是项目内部成员，还需要和项目之外利益相关方，比如客户、市场运营人员，大家一起确定最终的发布计划。

在对版本的发布做好规划后，就不用再纠结于该不该发布，该什么时候发布的问题。

有功能没完成没关系，关键要看这个功能是不是必须要有；有Bug没有修复完成，是不是影响发布，要看这些Bug是不是影响发布的质量标准；还可以采用一些像Beta版、小规模用户试用的发布策略，降低用户对功能和质量的预期。

## 规范好发布流程，保障发布质量

在规划好发布的版本后，要发布版本似乎是一件很简单的事，就是将源代码编码、部署。

但发布版本，可能并不是像你想的那么容易，这其中有几个需要注意的问题。

首先是必须保证要编译部署的是正确的版本。虽然一般来说，开发人员不会犯这样的错误，但是如果发布了错误的版本，后果可能很严重，所以要引起足够重视。比如说当年拼多多造成了几千万损失的薅羊毛事件，就是错误发布了一个测试用的无门槛券，导致被大量滥用。

然后要保证版本稳定可靠。如果你有开发经验的话，应该知道开发软件，一个常识就是每一次对代码的修改，都可能导致新的Bug产生。如果你的代码库在发布之前还一直在增加新的功能或者是不停地修复Bug，那么质量是难以稳定下来的。

再就是要在发布失败后能回滚。没有谁能保证程序发布后没有严重问题，所以最保险的办法就是要在部署后，如果发现发布的版本出现严重问题，就应该对程序进行回滚操作，恢复到部署之前的状态。即使有些不可逆的升级，也需要事先做好应对措施，比如发布公告，停止服务，尽快修复。

针对这些问题，已经有些好的实践，比如说代码冻结、Bug分级、回归测试等可以降低发布风险，保障发布产品的质量。在《[12 | 流程和规范：红绿灯不是约束，而是用来提高效率](http://time.geekbang.org/column/article/87129)》这篇文章中，我也提到了：**流程和规范能将好的实践标准化流程化，让大家可以共享经验。**所以在版本发布上，我们也可以制定合理的流程，来应用这些好的实践，保证发布的质量。

那么一般大厂都是什么样的发布流程呢？下面这个流程可以作为一个参考。

- 在发布之前要做代码冻结。

什么是代码冻结呢？就是在发布之前，对于要发布的版本，在源代码管理工具中，专门创建一个release分支，然后对于这个分支的代码，冻结功能的修改，不接受新功能的增加，甚至重要性不高的Bug都不修改，只修复重要的Bug。

由于严格的控制代码的修改，这样可以让版本的质量逐步趋于稳定。

- 对代码冻结后发现的Bug要分级

在代码冻结后，可能还存在一些Bug，测试的过程中也会新增一些Bug。代码冻结的原则就是尽可能减少代码的修改，避免引起不稳定。所以对于这些Bug，要有一个简单的分级：是否在发布前修改，还是留在发布后再修改。

至于如何对一个Bug分级，这需要项目负责人和产品负责人一起确认。

- 每次修复Bug后，发布新的候选版本

进入代码冻结后，开发人员还需要对一些Bug进行修复，每一次修复完Bug后，就要生成一个新的候选发布版本，比如说1.1 RC1、1.1 RC2。

关于生成发布版本，现在比较流行的做法是和持续集成系统整合，完全自动化。也就是在自动化测试通过之后，会自动构建，生成各个环境的发布版本。这样好处是，可以避免人为失误导致的错误，另外程序的配置管理做好了的话，只要测试环境的版本在测试环境测试没问题，那么就可以认为在生产环境的版本也是正常的。

自动化构建，生成发布版本并不复杂，各个语言都有成熟的方案，如果你还不了解的话，可以通过搜索引擎搜索关键字：“[对应平台] 自动打包”，例如搜索“iOS 自动打包”、“iOS build automation”这样的关键字。

其中稍微有点麻烦的就是如何应用不同环境下的不同配置，比如说测试环境连测试环境服务器，生产环境连生产环境服务器。有关程序配置管理部分，可以参考这篇文章：《[大型项目程序配置管理演化之路](http://insights.thoughtworkers.org/large-project-configuration-management/)》

- 每次部署新的候选发布版本后，要做回归测试

在每次开发人员部署新的候选发布版本到测试环境后，还需要做一次回归测试。也就是说在Bug修复完，对主要流程要重新测试一遍，同时还要对之前确认过的Bug再确认一遍，以确保Bug确实修复了，并且没有引入新的Bug。

如果当前候选发布版本达到版本发布的质量标准后，就可以准备发布了。

- 申请上线发布

上线发布是一件很严谨的事，所以在正式上线发布前，通常还需要有一个申请和审批的流程。审批的主要目的是要有人或者有部门统筹对所有的上线发布有一个全面的了解和控制，避免上线过于随意导致问题，避免和其他部门的上线冲突。

- 部署发布

如果已经实现了自动化，部署发布应该是非常简单的一步。如果还没有自动化部署发布，也需要事先将详细的操作步骤写下来，避免部署发布时发生纰漏，这样在实际部署发布时，按照事先写好的步骤操作就不容易出现错误。

- 上线后的测试

项目上线后，测试人员需要马上对已经上线的版本做一个主要功能的测试，以确保线上运行正常。如果做好了数据监控，还同时要对一些关键数据进行监控，例如服务器CPU利用率、内存占用率、服务出错率等数据。

如果万一发现版本上线后出现问题，需要考虑按照事先准备好的回滚方案进行回滚操作，尽量将损失降到最低。通常不到万不得已，不建议马上对问题打补丁进行修复。因为哪怕很小的代码修改，都可能会引入新的Bug。而重新做一遍回归测试，耗时会比较长。

以上就是版本发布的一个常见流程，你也可以基于这个流程制定适合你项目的流程，让你的版本发布更加稳定可靠。

## 软件上线只是新的开始

当你的软件上线后，这不代表你的项目就结束了，可能这才只是新的开始。

用户在使用你的产品的时候，可能会遇到一些Bug或者是有一些建议，所以需要给用户反馈的渠道，让用户可以有途径对于Bug或者功能去反馈。通过收集用户的反馈，可以进一步完善你的软件产品。

只是靠用户主动反馈问题还是不够的，需要主动的对发布的版本进行监控，比如说要收集App Crash的Log、监控服务器资源占用情况、监控API出错的比例、监控网页响应的速度等数据。当发现数据异常时，很可能说明发布的版本是有问题的，需要及时的应对，回滚版本或者发布新的更新补丁。

有关线上监控和报警的内容，将会在后续我们课程《[38 | 日志管理：如何借助工具快速发现和定位产品问题 ？](https://time.geekbang.org/column/article/97682)》中带你继续学习。

不管怎么样，软件成功上线了都是一件值得祝贺的事情，同时也是时候回顾总结一下整个项目过程了，关于这一点，我也会在后续专栏文章《[39 | 项目总结：做好项目复盘，把经验变成能力](https://time.geekbang.org/column/article/98141)》中跟你一起探讨如何做好项目总结复盘，把经验变成能力。

## 总结

今天带你一起学习了版本发布的相关知识。做好版本发布，关键在于版本发布前做好版本发布的规划，以及采用一个科学的发布流程。

版本规划，其实就是通过合理的规划，尽可能的让软件的功能和质量，满足好用户的预期。所以一方面要尽可能提供应有的功能和保证质量，另一方面也可以通过合理的发布策略，例如beta测试，降低用户预期。

通过规范的发布流程，可以确保要发布的版本正确以及发布质量的稳定。流程的关键在于发布前要对代码冻结，避免发布前频繁修改代码引入新的Bug，同时在每次修复Bug后，要做回归测试保证Bug被修复以及没有引入新的Bug，上线后还要对线上版本再一次测试，确保没有问题。整个流程中一些手工部署发布的操作应该尽可能自动化。

最后，软件上线只是新的开始，还需要收集用户的反馈，对线上服务进行监控和预警，对整个版本的开发过程进行总结回顾。

## 课后思考

你在发布版本前，会做哪些准备工作？你的发布流程是什么样的？通过对这篇文章的学习，你觉得有哪些可以改进的地方？或者你觉得有什么更好的方案可以分享的？欢迎在留言区与我分享讨论。

感谢阅读，如果你觉得这篇文章对你有一些启发，也欢迎把它分享给你的朋友。
