Jenkins与持续集成流水线

目录:

1.序言

2.job的基本配置

---2.1 源码管理

---2.2 构建命令配置

---2.3 构建触发配置(何时开始构建)

3.插件及常用功能

---3.1 构建后操作:触发下个构建

---3.2 构建后操作:邮件通知及附件

---3.3 构建后操作:单元测试报告展示

4.流水线配置

5.结语

1.序言

当传统工业的大部分工作都交由软件控制时,软件生产商还有什么理由人工处理机械性的工作呢?

当我们提交了一部分修改完成的代码后,我们总是希望可以快速、持续地得到直观且有效的反馈,以达到我们持续快速交付的目的。持续集成也是敏捷开发的好伙伴。Jenkins工具则是我们达到目的的利器。

我们在平时的工程中,总有一部分工作是相对机械化,易出错的(例如部署,打包),把这部分工作较给机器来做,我们仅需要轻轻地点一下鼠标泡杯咖啡就能让自己轻松地完成工作,岂不是美滋滋?

简单地说,使用自动化持续集成工具的目的是为了,让我们仅仅去关注我们最核心的功能(用户需求的代码编写)。

先来介绍什么是一条流水线(骨架),然后再一步步完善每一个步骤(血肉)。过程中会介绍两种常用的构建工具,gradle(Android工程)与maven,还有常用的插件、功能。

不妨先梳理一下日常工作的步骤:

1.编写功能(程序猿的核心价值)

2.使用IDE编译       //gradlew build & mvn complile 

3.运行单元测试用例(遵循TDD的良好开发习惯)//gradlew test & mvn test

4.运行集成测试/功能测试(如果有的话.....) //  gradlew integration (自己配置的job 可以参考gradle in action) & mvn integration-test

5.部署/打包  // gradlew assembleDebug & mvn package 

6.@#¥%……&*()

步骤2-5则是机械性的重复工作,若交由工具完成,可以让我们专注于其他核心价值。先贴一张流水线(pipeline)的图,介绍完基础步骤后再介绍流水线的搭建。

流水线(绿色:通过,红色:失败,蓝色:未执行,黄色:不稳定的)

图中的信息表示为:第254次构建-->客户端代码编译及风格检查-->运行单元测试用例-->运行集成测试用例-->打测试环境包(部署到测试环境)-->打正式环境的包(手动启动,前四步为自动执行)

我们可以通过流水线的一次构建,来快速地知道我们是否在哪个环节有错误,如果没有错误,我们就可以很自信地交给QA或部署。

我们再回头看一眼我们的工作步骤及括号中的命令,其实每一步都是在运行构建工具执行一条命令。而Jenkins的核心也就是代替人工一条条地去执行工程中约定好的命令,并且对每一条命令进行反馈。所以配置Job无外乎配置所需要执行的命令。

2.一个Job的基本配置

点开流水线中的任意一个job的配置项,我们可以看到如下图

红色框框出了大体的配置思路的目录,可以说是非常友好了。

general:基本配置,job名、描述等

源码管理:git or svn 用户名及密码  亦或是上游工程的源代码

pre setep:构建命令执行前的操作

build:构建命令

构建操作:包括对测试覆盖率的收集等

构建后操作:构建后发送邮件、是否把某个文件发布到workspace、配置下游job等

我们从大方向说起

2.1 源码管理

在这里介绍两种常用的来源

1.Git:通常为pipeline的第一个job的来源,从远程代码库拉取代码即可,配置如图,包括仓库地址、账号、分支就够了

2.clone workspace:该选项的意思是,克隆某一个workspace(这TM不废话),兄弟你先别急。选择了clone workspace就可以直接使用上游构建的代码库,可以省去一次执行build命令的时间,并且保证本次pipleline的构建使用的都是统一的代码库。通常使用在非第一个的job。

使用clone workspace时候有一个需要注意的地方,就是上游“构建后操作”必须添加如下配置,不然你无法拉取到上游的workspace

2.2 BUILD 构建命令配置

maven工程

maven工程的构建命令很简单,配置好pom文件的路径,以及所要执行的命令就可以了(图示即为打包为jar的命令)

Android工程

gradle命令作为构建工具依旧简单,只需要配置gradle版本,需要执行的命令即可(图示为运行android的测试用例,并且生成测试覆盖率报告)

2.3 构建触发器

构建触发器就是说何时开始构建,比如当jenkins检测到git上有新的代码提交就进行构建,又或者是2小时轮询一次,发现有新代码就进行一次构建。

图示的配置项即为通过轮询方式进行构建,每2分钟进行一次源码变化的检查,如果有新的提交,则构建,否则不作操作。

通常配置为:第一个job进行轮询,后续的job的触发方式由上游job build成功后自动触发


由上述的3个步骤就可以配置出一个独立的job,但是它远远无法达到持续集成的目的。

但是一个持续集成的流水线正是由数个job配合工作的产物。

下面我们来完善我们流水线中的细节。

我们始终要记得持续集成中的主体思路

1.编写功能(程序猿的核心价值)

2.使用IDE编译       //gradlew build & mvn complile

3.运行单元测试用例(遵循TDD的良好开发习惯)//gradlew test & mvn test

4.运行集成测试/功能测试(如果有的话.....) //  gradlew integration (自己配置的job 可以参考gradle in action) & mvn integration-test

5.部署/打包  // gradlew assembleDebug & mvn package

步骤2-5均为一个job,每个job都需要前面已经介绍过的配置,才能运行起来,但是每个job都有各自不同的地方。

通常步骤2即为一个pipeline的起点。当编译结束后,我们应该运行单元测试(进入步骤3,进入下一个job),如何做?

你还记得构建后操作吗?

3.插件及常用功能

3.1.1 构建后操作:自动触发下一个job

图示即为构建后的触发器,意思是,构建成功后自动触发另一个job(运行单元测试的job)

3.1.2 构建后操作:手动触发下一个job

集成测试也成功后我们想发布到正式环境(我只是想想,如果你有足够的自信你也可以发),但是我们并不是每一次有提交代码都要发布到正式环境,我们可以周期性地发布,那么这一步肯定不能由上游构建触发,这里需要我们手动触发。当QA也觉得当前分支的代码没有问题的时候,由QA手动地去点击(出事就让QA背锅)。配置如下


那么构建后还有能哪些操作?

包括单元测试覆盖率的report的发布、构建成功/失败的邮件通知、构建下一个工程、把构建结果发布到workspace等等等等。

那么构建失败怎么办?发邮件通知一下研发是一个好的解决方法,或者发给你们的老大???嘿嘿嘿

3.2 构建后操作:邮件通知

Attachments为添加一个附件,附件的路径参数参考这里

failure - any   sent to:失败后给XX发邮件。

通常配置为:发布前的所有job仅在失败时发送邮件通知开发人员,发布的job在成功打包后把产物发给有关人员。

第一个编译job算是基本完成

单元测试job:既然是单元测试,我们就希望能有一个单元测试覆盖率的反馈,通常使用的是jenkins中的 jacoco插件完成

3.3 构建后操作:单元测试覆盖率报告

图示为通过jacoco插件实现的单元测试覆盖率的报告。

path to exec file:jacoco所收集到报告文件的路径(可配置),jacoco的测试报告是一个exec文件

path to class directories:生成的.class文件目录

path to source directories:源码目录

inclusions/exclusions:包括/排除哪些类

下面就是分支、行、方法、类等覆盖率的配置,那些值由你们的TL或者技术经理或者朝廷下发的标准设置。如果勾选了红框,那么你的覆盖率不达标的时候,会将本次的构建置为失败,那么你的技术经理就会收到邮件,你的技术经理就会和你彻夜聊人生和理想,你会发现彻夜聊天PY会痛。。。。。

这是单元测试的job中最核心的内容,构建成功后触发集成测试,配置相似,此处略过。

Jenkins不仅仅局限于上述的插件功能,还可以执行shell、ant、gradle脚本、对代码进行checkstyle检查、对代码进行findbugs等,这些都是比较常用的插件,如果你要使用到其中某个插件,你可以联系你们的负责人,让他安装上插件,就可以使用了,在这里不再详细地展开了。

小结:按照上述步骤,就基本可以配置出一个持续集成的流水线了。你们的流水线可以允许你们快速地对客户的需求进行快速反馈。

4.构建一个流水线

我们在前面一直提到过流水线。流水线的概念和传统手工业的流水线概念一模一样,唯一不同的地方在于,产物由实体变成了软件。

搭建流水线的方式也非常的简单,如果你配置一个job的时候,在“构建后操作:构建其他的job”一栏中也有配置,那么流水线就算配置完成了。

下图即为一个流水线的配置,配置好initial job,选择你的第一个job即可,该配置项通常配置为执行构建操作的job。

点击保存,我们就可以开始配置pipeline了。

我们要给我们的job起一个好名字,一个规范化的好名字,是一个好项目的开端。

客户端的job可以统一为01_client_工程名_操作内容(如build/UT等)

根据我们的流程,job01的主要工作应该是build,在job01的“构建后操作:构建其他job” 中我们选择job02(UT),接着在job02的“构建后操作:构建其他job”我们选择job03(集成测试)以此类推...

那么我们的流水线就算搭建起来了,当你提交代码后,会从第一个job开始依次执行到最后一个job。是不是很简单?

5.结语

正因为jenkins的强大,可以执行各式各样的功能,所以我们有的时候会把大量的构建代码写在jenkins中,但是这并不是一个最佳实践。

软件开发的过程中,时时刻刻都强调解耦。如果大量的脚本写在jenkins中,那么我们就说工程和jenkins是耦合在一起的。但是别忘记了,如果哪一天jenkins挂了,或者说服务器要迁移到一个更好的集成工具中,这部分的工作量也是非常巨大的。

所以将所要执行的脚本语言独立到一个文件中,在jenkins中执行这个文件不失为一个良好的实践。

在本篇分享中,我们先分享了所有job都需要配置的部分,之后再介绍各个job不同的部分,更多的是介绍了配置jenkins的思维过程,希望对你能有所帮助。如果有任何疑问,欢迎在评论中提出,或直接联系我,qq493243390

如果你觉得对你有帮助,请帮忙点个赞或者转发一下。不胜感激!

推荐阅读更多精彩内容