背景
2017年一整年我的工作都是围绕Jenkins,做持续集成相关的一系列工作。支持了公司内部两个客户端平台和三个项目的APP打包,静态代码检查,Sonar平台搭建和维护等工作。
年底统计支持线上手动构建次数达到了几千次。稳定性却并没有达到我的预期,全年只有92%,最近正好在看Jenkins Pipeline相关的语法,然后实践了一下Jenkins Job升级的过程,其实并没有想象的那么简单,其中涉及到之前很多低版本的插件甚至已经被Jenkins新版本弃用。
这个过程中,首先,需要十分感谢社区的@rocl的帮助,在这个过程中,给予了很多很好的帮助和指导意见。
注意的点
其实之前对Jenkins BlueOcean第一个版本就在本地尝试运行过,但是只一个DEMO,真正迁移涉及到我们自己线上运行的Job时候,还是有些点,需要注意。
区分Declarative Pipeline和Scripted Pipeline
Declarative Pipeline和Scripted Pipeline都是Pipeline的语法,但是两者是有区别的。
Declarative Pipeline所有的声明式都必须包含在定义的pipeline的{}中: 然后在结构体中,可以新增stages,stages中需要包含stage,stage中必须包含steps,否则会报错。
类似于这样的流程:
如果需要,增加Groovy代码,则需要增加script模块包裹代码
而Scripted Pipeline则相对简单,如果是刚才同样的代码,实现是:
区别还是很明显的,但是我觉得对我而言最大的不同点,是两者环境变量的设置。
Declarative Pipeline设置环境变量是通过environment,但是Scripted Pipeline设置环境变量却是通过withEnv。
Pipeline Syntax
推荐一个快速熟悉Pipeline语法的入口,你先新建一个pipeline job,然后编辑页面,有一个Pipeline Syntax,点击之后,是如类似的页面。
我这里想强调的是,选择properties时候,当前Pipeline并不支持了,需要替换成Options,举个栗子,保留历史构建次数的。将下面的块结构体放入pipeline中即可。
动态支持取远程分支名字
在之前低版本的Jenkins内,我的实现是通过插件Dynamic Choices Paramters Plugin支持的,加上Groovy脚本实现取分支代码。
但是新版本已经弃用了这个插件, https://jenkins.io/security/advisory/2017-04-10/
它们的描述是:
Dynamic Parameter Plugin
SECURITY-462
Dynamic Parameter Plugin allows users with Job/Configure permission to definescripts to be executed on the Build With Parameters form to determine availableparameter values.
This allows users with Item/Configure permission to run arbitrary Groovy codeinside the Jenkins JVM.
As of publication of this advisory, there is no fix.
那么只有使用Active Choices Plugin,实现不是很复杂。将取分支的groovy script放入==>==>==>
最后生成:
这个结构体需要放入前面部分。
这里我想简单过程中我遇到的最大的问题,不是这里,而是因为我们的代码仓库是Gerrit,需要再取代码前执行ssh 认证,那么我之前用这个脚本无法取到远程分支名字。
最后的解决方案是,用配置的crendialId的对应用户,在安装Jenkins的机器上,配置该用户在Gerrit对应账号下的。
还有我想强调的是,如果用了Active Choices Plugin就无法正常使用Blue Ocean进行参数化构建了。会遇到报错。
"This pipeline uses input types that are unsupported. Use Jenkins Classic to resolve parametrized build."
Jenkins Issues中https://issues.jenkins-ci.org/browse/JENKINS-41709有具体描述,貌似修复茫茫无期。
后来我想到了一个方法绕过。
我只用groovy脚本取远程分支名字,但是参数化部分,使用Blue Ocean支持的Choices Parameter。
代码类似于:
这样BlueOcena参数化选择功能能使用了,但是这样做同样有一个问题,就是远程分支名字同步不能实时,如果分支增加或者减少,只能第一次失败,第二次才能构建成功或者选择到。
完整的Declarative Pipeline脚本
解释一下,最后的post部分,为了是我自己写了一个服务收集所有的构建Job的信息,因而触发下一个Job执行一个向我写的服务,post信息的任务。
有人可能会问为什么,不直接在打包job后面直接向我写的服务post信息,是因为为了不影响本身Build Job的构建状态。
最后
Jenkins Pipeline已经迁移了几个手动打包的Job,但是还是感觉跟预期的有点差距,上手并不是想象的那么容易,但是它值得迁移。
参考
https://testerhome.com/topics/11238
https://jenkins.io/doc/book/pipeline/jenkinsfile/#working-with-the-environment
https://www.xncoding.com/2017/03/22/fullstack/jenkins02.html
领取专属 10元无门槛券
私享最新 技术干货