概念

现在企业的一般开发流程,从开发人员电脑开发,到发布上测试环境进行单元和集成测试,再发布到预发布环境进行「彩排」,最后才根据需要发布到生产环境上(当然还有些复杂流程就是会分A/B生产环境)。
大致可抽出:开发环境->[单元测试]->[合并代码]->测试环境->[集成测试]->预发布环境->[功能测试]->生产环境
那么「三个持续」分别负责哪一阶段或层面的工作呢?

  • 持续集成(Continuous Integration 即 CI):这里很好理解,就是负责开发环境到测试环境上的工作,属于技术层面的概念。
  • 持续部署(Continuous Deployment):业务层面的概念,负责从测试环境预发布环境生产环境的代码自动化构建、测试、部署和发布。
  • 持续交付(Continuous Delivery 即 CD):实际上,持续交付和持续部署很容易混淆,持续交付多指业务层面上(与技术无关)的工作,它属于业务层面的概念。也即要是代码无论任何时候,都持续处于一个可交付给客户(可发布上线对外提供服务)的状态。

持续集成

通过一个故事来讲述CI的作用

在某公司上班的A、B、C、D、E,正在编写一个超级大的应用,ABC是开发人员,D是测试人员,E是项目经理。
在传统的开发方式下,ABC在各自机器上开自己的功能分支,并在此分支上进行开发。期间所有编码和自测工作都仅限于在自己机器上进行。在合并集成到主分支前,他们甚至会在各自分支上或机器上开发几周或几个月的时间。
在某个时间点,项目经理E说要准备发布了,快合并到测试环境的主分支上。
此时,开发人员A、B、C都急急忙忙地把各自分支合并到测试机的主分支上,但因为这三个不同的分支在合并前没一起测试过,而且A、B、C各自的开发环境与测试环境有差异,导致很多bug和问题在合并测试时接踵而至。
合并到测试环境主分支后,测试员D准备进行自动和手动测试,他测出的Bug和问题数量将决定是否能按时发布。经过曲折且长时间的测试后,最终测试通过,项目经理E准备发布项目到生产环境。

传统的开发模式

在这个过程中,大家的心路历程是如何的呢?

  • ABC作为开发人员,会非常难受,因为在合并时会出现各种各样问题,如代码冲突,依赖冲突等。
  • 测试员D也难受,因为在ABC的开发期间,他只能干等着,但是在测试阶段,他又忙到爆炸,而且此时才能编写各种异常场景的测试用例。
  • 项目经理E也是,合并集成阶段是整个项目里最大的不可控点,无法合理预估和规划接下来各阶段的时间,任何异常情况都会把发布推迟。

以上主要问题都是因为集成阶段的不稳定和不可控导致,且每次发布前,都会有这个情况出现且越来越不受控制,维护的边际成本逐渐递增。

引入持续集成

从持续集成这四个字可知道,本质上就是不断重复且频繁的合并代码,集成各功能模块。
怎么个持续集成法呢?
不要一次性的大合并大集成,取而代之的是每当完成一个需求的功能块就马上进行合并集成,无需等待本排期内的其他需求,不用等到发布前的一次性大合并才进行。
注意:每个需求的功能模块代码在合并到主分支前,都要跑一次自动测试。
引入持续集成-工作流
引入持续集成-结构

持续集成的要求

  • 每个需求/功能开发完毕即刻合并到主分支(在合并前,功能分支要先做好单元测试,然后再合并到主分支并开始主分支的集成测试)。
  • 当主分支合并了功能分支后且通过测试,该功能即完成。
  • 在功能分支和主分支上,都要有自动测试。
  • 开发人员需要持续、经常性拉取主分支的代码并合并到自己的功能分支上,以保证代码同步,防止出现过多冲突。

优点

  • 防止各开发人员各自为政,导致大合并时出现各种环境问题、代码冲突,减少发布前的不可控情况。
  • 将一次性的大测试拆分为多个小测试逐步进行。

升华

持续集成的目的是让正在开发的软件始终处于可工作状态。同时强调,代码的提交是一种沟通方式,而既然是沟通就需要频繁,下图中代码的提交过程,事实上就是各条分支之间的对话过程。
分支间的交流

持续部署

在持续集成的基础上,将集成后的代码部署到更接近生产环境的预发布环境中。比如,完成单元测试后,可以把代码部署到连接着数据库的Staging环境中,进行更进一步的测试,此时会出现以下几种情况:

  • 测试环境与预发布环境不同,可能预发布环境需要额外配置参数。
  • 在测试环境上可正常运行,在预发布环境上无法运行。
  • 后面的部署预发布环境、生产环境都需要手动操作。

引入持续部署

每个开发完毕的新功能在通过测试后自动部署到预发布环境staging,并最终自动部署到生产环境。
引入持续集成-结构

持续交付

持续交付需要与持续集成和持续部署(或叫持续发布)搭配,持续交付基于后两者的基础上,才能实现。就如持续部署实现自动化部署到预发布环境后,业务人员(如产品或运营等)根据需要,决定发布哪些新功能,才将此功能一键发布,部署到生产环境中。持续交付体验在业务人员可在任何时候根据需要来发布业务功能,而不受新功能代码的引入,导致系统不稳定,无法发布上线的影响。

总结

从两个字持续可知三者都是可频繁、重复、稳定的操作。
持续集成是一切的基础,而基于此上的持续部署,贯穿整个过程。基于前两者,再上层的建筑就是持续交付。
持续集成,持续部署都是技术层面上,有了技术层面上的保证,业务层面上的持续交付成为可能。
技术服务于业务,而业务又依赖技术。