【编者的话】这是持续集成系列的第二篇,在本文中,作者介绍了CI流程的具体实现。

引言

在持续集成(CI)系列的前面一篇文章里,我们关注了CI的基本概念,它是如何帮助企业减少集成软件时的错误,采用它带来的好处和遇到的难点,以及最后,它是如何助力敏捷开发和DevOps团队文化的推行。

我们还讨论了CI落地到开发流程最常用的一些方式,最终能够带来软件质量上的提高,更快的市场交付,更快的反馈周期以及更低的开发成本。

如果你还没有读过前面一篇文章的话,不妨在继续阅读本文之前先翻阅一下!

在本文中,我们会介绍到一些工具,它们将有助于为组织实现一个强大并有价值的CI流程。

持续集成服务器

实现一个CI流程的唯一必要条件便是得有一个自动构建系统。

然而,实际上,除了自动构建系统外,安装和配置一个“CI服务器”也是相当有帮助的。

概览

CI服务器会扮演核心大脑的角色在幕后工作,将各种行业标准的实践无缝整合到CI流程的实施中。

下图展示了一个典型的CI工作流。如图所示,它涉及了6个阶段,从签入代码开始一直到最后,向组织里的不同人群提供该次签入的反馈为止。

CI工作流

图片来源: https://insights.sei.cmu.edu

初始化CI流程

通常,当开发者将代码签入到源码仓库时就会发起一个CI流程。

CI流程的工作流也可以通过其他方式触发,针对于开发团队而言,一般来说以下方法均可选用。

  • 手动 —— 无论是通过CI服务器的管理界面还是脚本,用户可以手工执行CI工作流

  • 计划任务 —— 预配置好的计划,例如一次凌晨的构建

  • 跟踪触发式 —— 在每次提交到源码版本管理系统时触发

凌晨的构建一般需要针对代码执行更大规模的检查,并且花费更长时间来完成检测。

拉取最新代码

作为整个流程里的第二步,CI服务器会负责从源码管理拉取最新的代码。这可以借助poll或者push机制实现。

使用poll机制的话,该CI服务器会配置一个源码管理服务器的位置,以及它的安全证书。它会根据一个时间间隔定期地轮询指定位置,以检测是否有发生任何新的签入以及代码变更。一旦检测到有变更,它会从源码管理服务器下载代码最新的副本到本地磁盘。

使用push机制的话,源码管理系统会配置一个'钩子'指到CI服务器。当开发人员提交了一个变更到仓库时,之前配置的钩子将会被调起,而它会让CI服务器知道,这里发生了一次变更。

构建

源代码一般是自包含构建的,即CI流程所需的构建脚本是放在源码仓库里的。正如在之前的步骤里详细介绍的那样,一旦最新的代码被拉取下来,一个捆绑好的脚本将会被用来触发该次构建。

针对Java ™项目,构建自动脚本一般会采用Maven或者Gradle。人们不大常用那些不支持内置依赖管理的构建系统。万一遇到不需要依赖管理的情况则可以试试"make",一个在类Unix系统被广泛使用的构建机制。这里有各种各样的其他构建工具可供选用。一些已经列在了构建自动化软件的Wiki里。

执行测试

在CI流程的这个阶段里,单元测试和集成测试将会被执行。一般来说,这些测试也会被打包到代码里。

针对基于Java ™实现的系统而言,这些测试会通过一个像JUnit这样的测试框架来执行,从而可以轻松模拟它们的一些测试依赖。

某些编程技术可能有它们自己的测试运行框架,Spring的Spring Junit Runner,Java EE的Arquillian等。

在CI服务器上运行测试主要有下面这些好处:

  • 你曾经有没有遇到过这样的场景,这些测试在一台机器上是通过的,但是在其他机器上却失败了?通过在一台中央服务器上执行这些测试,我们可以消除一些测试环境方面的问题

  • 针对每一次变更都会立即触发执行测试,而且如果有任何新的代码变更打破了预期的行为的话,你能够马上知道

  • 大多数团队都是并行地在开发着许多功能,甚至可能一些团队成员也是分布在全球各地。每当开发人员提交代码到仓库时,任何故障都可以被识别出来并且立即修复。

结果

在CI流程的最后,只可能存在两种结果的其中一种 —— 要么构建和测试失败了,要么通过了。

每一次签入都会被验证并且确保它不会破坏现有的代码。代码在它被合并到主干分支后不久会被构建和测试。这将可以降低主干代码崩溃的频次。

一般来说,CI服务器会配置成在遇到故障时发送邮件(发给团队里的每一个人或者仅仅单独抄送负责上一次签入的相关人员)。通过这种方式,可以快速知晓故障并且尽快采取更正措施。

大多数CI服务器还会突出展示最近一些构建的状态而且最近几次构建的状态还会用红-绿-琥珀色指示灯来标明。举个例子,Jenkins,使用的是如下指示灯来显示构建的情况。

CI Jenkins

图片来源: https://wiki.jenkins-ci.org

扩展CI服务器

前面一节着重讲述了CI的基本工作流。然而,大多数组织也会根据自己的优势将它用于更多的用途。CI服务器可以通过安装各种"插件"来拓展行为,从而实现功能上的扩展。下面介绍的是一些最常见的扩展。

技术债 & 代码质量

任何引入到软件里的变更将导致系统复杂性的提高以及混乱程度的加深。系统的混乱程度被称为“技术债”。每当新代码被引入到系统时,技术债就会相应增加。如果技术债长期不受重视的话,得到控制权的可能性将变得越来越渺茫,毕竟越来越多的功能在紧迫的期限内堆积过来。而这将会对软件的生产力和可维护性产生负面影响。

迭代开发方法,将测试的执行自动化,以及使用CI来监控每一次签入的技术债,这些是保证技术债在可控范围内的不二法门。

我们应当使用一些工具,比如SonarQube,一个分辨代码质量和跟踪技术债的开源平台。它可以轻松地集成到任何CI服务器,并为用户提供团队技术债实时数据的展示。

它做的也不仅仅只是衡量技术债。它衡量并覆盖了代码质量的7个维度:

代码质量的7个维度

图片来源: SonarQube.org

SonarQube在一个友好的web界面上展示它的分析结果。这使得它成为一款非常实用的工具,不仅仅是针对开发人员,还包括管理和其他相关的非技术人员。

SonarQube

图片来源: SonarQube.org

SonarQube graph

图片来源: SonarQube.org

引申阅读请转到:

  1. Managing Technical Debt
  2. Sonarqube
  3. Codacy

代码语义

对于开发人员而言,引入CI在另外一个重要方面同样有价值 —— 它可以用于衡量代码质量 —— 语义,以及一些常见的反模式。

静态代码分析工具可以充当CI流程的一部分,以洞察代码的健康状况。历史数据也可以存储起来,从而提供一个时间段内代码质量的衡量。用户可以在两个提交之间列出比较,以确定每个提交引入的债务度量。

许多现有的工具可以对代码做静态分析并且计算出各种度量代码质量的指标。这些工具可以并入到持续集成服务器然后自动执行。

一些更加常用的工具有:

  • Checkstyle
  • Findbugs
  • Sonar

有关各种平台工具的详细列表,请参考静态代码分析工具的列表

代码审核

正如在前面的文章里介绍的那样,开发人员工作在功能分支上,并且会尽可能多地提交代码。

我们可以在持续集成服务器里使用代码分析工具(例如Sonar)来执行自动代码审查。随后每个开发者需要负责解决在他们的提交里生成的评论意见。

自动代码审查是基于一组预定义好的规则,并且是一个查找潜在技术问题的好办法。这些规则可以从所有主要的CI供应商处下载,并适用于大多数主流编程语言。

一旦自动审查的评论意见提出的问题被修复了,CI服务器会随即发起一个人工代码审查,揪出那些自动审查无法找出的问题,即验证业务需求,架构问题,代码是否可读,以及是否易于扩展。

CI服务器也可以配置成,如果某些人没有审查代码便阻止对主干分支的任何提交。最常见的做法是每个合并到主干分支的提交至少要有两个审查人员(reviewer)。在基于Java™的项目里,针对此用途最常用的工具是Gerrit。

有关其他编程语言代码审查工具的详细列表,请参考代码审查工具列表的WIKI

无界面测试

如果要在CI服务器上运行用户的UI测试,那么他必须得依赖无界面测试,因为没有浏览器的显示界面来启动。无界面测试意味着在没有图形用户界面的情况下运行UI测试。这样的测试需要一个无界面浏览器,它和市面上流行的web浏览器类似,但它是通过一个命令行接口执行的,并且拥有一个UI元素的内存模型。该内存模型用来模拟和UI的交互,比如在UI上一个按钮的一次点击,会被模拟成内存模型对象的一个行为。

市面上流行的测试工具,比如Selenium可以被用来做无界面测试。像PhantomJS这样的无界面浏览器也被广泛使用。通过在构建里引入这些测试,CI服务器将能够验证UI方面的故障。

安装CI服务器

CI服务器的安装方式有三种:

  • 单机
  • 托管
  • 私有云

单机版的CI服务器安装即是在一台单个主机上完成。这通常是用于小型项目或者小于10个研发的团队。

托管的CI服务器可以在公有云平台上看到,一般是根据订阅计价。往往这些是和CI服务器可以访问的云端源码管理系统紧密结合在一起的。这一般被那些不想维持和运维CI基础设施的企业所采纳。对于中型团队来说,这也是一个非常可行的上手CI的选择。

一些大型企业以及那些想要完全掌控及安全使用他们自己的基础设施的组织,选择的则是私有云的部署方式。一般来说,他们会配置一组高性能的服务器用来运行多个CI服务器的客户端,以支撑数以百计的开发人员签入其代码的繁重工作负载。

一些最广泛使用的CI服务器有:

  • Jenkins
  • Travis CI
  • TeamCity
  • CruiseControl

有关CI服务器的详细列表,请参阅持续集成软件的比较

小结

在这篇文章里,我们已经介绍了如何使用CI服务器来创造高质量的产品。CI服务器可以扩展成自动测量许多指标,例如技术债,代码语义,测试覆盖率等。

签入代码时代码质量的即时反馈确保故障可以更加及时地被发现,从而保证客户可以获得一个可靠且正常工作的产品。

将持续集成引入开发过程还有许多其他的好处和出发点。 这里也有许多其他工具来扩展CI服务器。敏捷软件开发及DevOps方法与持续集成天然地相辅相成。

那么,如果你还没有把持续集成纳入到你的开发流程里的话,现在还为时不晚!

下一篇

在持续集成系列的下一篇文章里,我们将介绍到实现CI的一些关键模式和反模式。透过这些建议,你将能够实现适合你所在组织开发目标和策略的最佳流程。

原文链接:continuous-integration-part-2-ci-server-toolkit(翻译:Colstuwjx)

About Author

colstuwjx

colstuwjx

互联网运维工程师,IT屌丝一枚,好技术。