持续集成
---

更关注代码质量。持续集成是为了确保随着需求变化而变化的代码，在实现功能的同时，质量不受影响。因此，在每一次构建后会运行单元测试，保证代码级的质量。单元测试会针对每一个特定的输入去判断和观察输出的结果，而单元测试的粒度则用来平衡持续集成的质量和速度。

持续集成的核心价值在于[^CI]：

1. 持续集成中的任何一个环节都是自动完成的，无需太多的人工干预，有利于减少重复过程以节省时间、费用和工作量；
2. 持续集成保障了每个时间点上团队成员提交的代码是能成功集成的。换言之，任何时间点都能第一时间发现软件的集成问题，使任意时间发布可部署的软件成为了可能；
3. 持续集成还能利于软件本身的发展趋势，这点在需求不明确或是频繁性变更的情景中尤其重要，持续集成的质量能帮助团队进行有效决策，同时建立团队对开发产品的信心。

###持续集成系统

在前面的内容里，我们已经介绍了持续集成的各项基础设施——如使用版本管理、编写测试、自动化部署。要构建这样的一个持续集成系统需要下面的内容：

 - 支持自动构建
 - 源码服务器
 - 持续集成服务器

我们已经实现了前两点，针对于第三点——持续集成服务器，我们可以以 Jenkins 为例做一些简单的说明。它是一种基于 Java 开发的持续集成工具，并提供了用于监控持续重复工作的软件平台。

它可以让整个开发流程到部署都实现自动化。由于每个功能可以一点点的加在 build 中，那么这样就能保证每次的新 build 可以交付新的功能。同时，我们可以根据用户的反馈情况及时调整开发方向，降低项目风险。

###持续集成流程

我们就可以对这个工作流展开深入介绍。持续集成主要就是要保证整个过程是**可持续**的。如下图是一个持续集成的工作流：

![CI Workflow](assets/article/chapter6/ci.jpg)

不同的开发者在自己的机器上开发功能代码。在完成一定的本地提交后，这些代码将会提交给源代码控制服务器。不过，在那之前我们应该在本地跑测试来减少持续集成失败的情况。接着，我们的CI会定时去获取源码服务器是否有代码修改。如果有代码修改，那么我们的集成服务器将会获取这些代码。然后，构建这个项目，运行测试，再输出返回结果。最后，我们可以开发一些小工具来提醒用户 CI 是否运行成功。

如果这个过程中 CI 运行失败的话，那么我们就不能再提交新的代码——除了修复 CI 的代码外。持续集成变红不能过夜，要么快速解决，要么回退。

在这个过程中，有两点值得注意，一个是小步前进，一个是迟早反馈。

####小步前进

小步前进是一系列步骤的集合，其目的是：集成越早问题越小。即当我们的代码越早的提交到源码服务器，那么其他人就可以尽可能早的和我们的代码集成到一起。这也意味着，每天结束时，我们在本地的修改要尽可能小，并且这些修改还要保证不会破坏持续集成。

我们需要频繁地在本地提交我们的代码，编写独立的测试——如果我们在最后才编写测试，就会拖慢整个流程，它使得我们不能尽可能早的提交代码。

####尽早反馈

> 反馈越早，那么问题越小。

无论是精益还是敏捷都在强调一点——尽早反馈，反馈对于提高敏捷开发流程效力非常重要。从日常的：

 - Code Review
 - 静态代码分析
 - 自动集成测试
 - 自动验收测试
 - 高频率发布

我们都在做尽可能小的反馈，这些实践对于我们完成一个好的持续集成来说是非常重要的基础。

参考资料：

 -《持续交付：发布可靠软件的系统方法》

[^CI]: [基于 Jenkins 快速搭建持续集成环境](https://www.ibm.com/developerworks/cn/java/j-lo-jenkins/)
