Jenkins 多分支项目过滤及 when 的高级用法
需求
前段时间在研究 Jenkins 的自动化构建时,写了一篇文章:使用 Generic Webhook Trigger 触发 Jenkins 多分支流水线自动化构建
Generic Webhook Trigger
的使用过程中,有一个问题一直困扰着我,就是多分支流水线每次触发构建时所有的分支都会去构建一遍。之前也没怎么去关心,因为在 Jenkinsfile
里我用 when
做了条件匹配。这周发现分支越来越多,而且团队合并代码变频繁之后,虽然那些分支只是做了一下pull代码的操作,但是各种排队加起来的时间也会导致整个构建的时间越来越长,而且会产生各种不必要的构建日志等等。
之前的思路一直是 Generic Webhook Trigger
里是不是有一个配置可以做到只触发特定的分支,google 了一些文章发现无果。而且类似的触发器插件都是只能做到根据过滤条件去触发这个Job。所以后来换了个思路去思考这个问题。
首先想到的是,既然是一个多分支的流水线,那么对于这种流水线本身是不是可以去过滤一些特定的分支呢?比如我们项目里只需要构建 sprint
和 master
分支,平时的 feature
分支还有其它的等等都是不需要构建的。然后就按这种想法去 google 了一下,还真的找到了答案。
Jenkins Multibranch Config: How to Filter branches based on variable string?
多分支流水线过滤
进入流水线的配置界面,在 Branch Sources
里找到了Behaviours
选项,可以添加很多行为,这里面有两个我们需要的:
Filter by name(with regular expression)
Fliter by name(with wildcards)
使用正则表达式或通配符来过滤
点击 ?
图标会有一些说明,比如正则表达式的语法使用的是Java
的。这也是我想吐槽的一点,同样一个正则表达式,在不同的地方写法各不相同,折腾死人。
保存之后,流水线里就只保留了过滤之后的分支
这一步可以把开发时的各种分支都过滤掉,只保留需要构建的分支。但是还有另一个问题,我们Jenkinsfile
的 build
阶段,会去做一些前端的代码打包工作,比较耗时。这个阶段配置的是 master
和 sprint
分支都会去执行。
但我们开发的时候,当代码合并到 sprint
分支后,我只想触发 sprint
分支去执行 build
阶段的命令。master
只需要手动去触发。这就需要用到 when
的 triggeredBy
属性
when 的 triggeredBy 属性
我们现在需要完成的目标是,当使用 Generic Webhook Trigger
触发构建的,master
分支各个 stage
都不执行。
官网的说明就这些。对于 Generic Webhook Trigger
来说,这些都没用。
然后试了下 when { triggeredBy 'GenericTrigger'}
也不行,generic-webhook-trigger-plugin有人专门提了一个 Issues
去问这个问题,但是被关闭了,也没有解决办法。
后面就去搜怎么在Jenkins中获取构建的原因,居然还找到了很多这方面的资料。可以通过currentBuild.getRawBuild().getCauses()去获取。但是出于安全考虑,Jenkins脚本中直接使用系统的方法是被禁止的,需要手动去添加一下。参考了Jenkins CI Pipeline Scripts not permitted to use method groovy.lang.GroovyObject这个问题的回答搞定了这个问题。
最后写了一个测试的脚本,如下:
打印的结果如下:
本来想根据返回的这个结果去自己写匹配语句,但感觉很麻烦干脆就试一下 when { triggeredBy 'GenericCause'}
。天哪,居然可以了,简直不敢相信。
最终的 Jenkinsfile
脚本如下:
这次虽然解决了这个棘手的问题,但是并没有非常开心。其实这些问题,文档写明白一点就不用去折腾这么久了。对于开源产品来说,一个清晰的文档真的很重要。
版权声明: 本文为 InfoQ 作者【jerry.mei】的原创文章。
原文链接:【http://xie.infoq.cn/article/561e7c20675270f708f3650e2】。文章转载请联系作者。
评论