持续交付
---

持续交付依赖于一系列的工具和实践，下图是一个持续交付的工作流：

![CD Workflow](assets/article/chapter6/continuous-delivery.jpg)

还有一系列与开发无关的技能：

1. 自动化
2. DevOps
3. 云基础设施
4. 以软件为中心的哲学

###基础设施

在我们使我们的项目可以持续交付软件包的时候，我们需要

####本地开发环境

在本地编写代码时，我们需要设置本地的开发环境。假设我们要开始一个 Java Web 项目，在我们的开发机器上，我们需要安装：

 - 版本管理工具，如 git，用于管理源代码。
 - IDE，如Intellij IDEA，用于搭建开发环境。
 - 构建工具，如 gradle，用于安装依赖、运行测试、构建工程等等。
 - 语法检测工具，如 checkstyle，用于检查代码语法。
 - 单元测试框架，如 JUnit，用于进行单元测试。
 - 集成测试框架，如 Cucumber、Selenium，用于做行为测试。

除此，在我们的项目代码里，我们还需要：

 - ``CI运行脚本``，用于在 CI 上运行指定的测试。
 - ``上传包脚本``，用于上传 build 完的软件包。
 - ``部署脚本``，用于在本地部署包到测试环境。
 - ``监控代码``，用于监测网站性能和用户行为。

当然我们还需要辅助一些测试工具来测试网站，如性能测试、网络测试等等。

####持续集成环境

为什么在这里会出现一个持续集成环境？我也不知道，只是想到了这里。由于我们需要持续集成，所以我们也需要一个运行持续集成服务器的机器。

持续集成服务器是由两部分组成的：Master 和 Agent。即一个用于控制其他运行持续集成服务的机器，以及执行指令的机器。因此，我们需要在一台机器上安装 Master 软件，在另外一台机器上作为 Agent。在我们的 Agent上，我们需要安装相对应的运行服务的软件，如

 - 指定版本的语言环境 ，如Java、Python。
 - 构建工具。
 - 版本管理工具，及对应的密钥。
 - 打包工具，如 RPM。
 - 虚拟桌面，即可以模拟桌面浏览器的软件。

同时，我们还需要有一个地方放置我们的RPM包。 

####测试环境

相比于上面两个环境来说，测试环境就比较简单了。我们只需要创建几个不同的环境，即开发者的测试环境、QA 环境、模拟线上环境，在这几个不同的环境上有不同的配置。

###持续部署

在持续交付之外的，还有持续部署——这个就更依赖于团队的组织结构了。其与持续交付的对比如下图所示：

![持续部署](assets/article/chapter6/continuous-delivery-continuous-deployment.jpg)

我们可以从图中看到，两者的最大不同之处在于：持续部署会直接将构建生成的部署到产品环境。这就意味着，我们不仅要有强大的技术实力，也要有足够的组织支持才能做到。而这部分已经超出了软件开发的内容了~~。
