我以前的博客《Jenkins 多分支构建》及《Jenkins 多分支构建中的邮件配置》探索了在多分支构建中Jenkinsfile的配置。然而在个人配置中,根节点为node
,但里面却没有使用Jenkinsfile的DSL去声明构建的流程,而是经过groovy代码去实现整个的构建逻辑,用try-catch
处理构建失败的问题,看起来很混乱。而且,整个构建原本有拉取并检出代码、构建、发布这几个阶段,可是在Jenkinsfile里却没有体现出来,因此当发现构建较慢时也不利于定位问题所在的步骤。本篇文章将彻底处理这些问题。html
咱们仍是以以前的代码为例,这里为了专一于具体的配置,我简化一下构建命令及省略掉发邮件的代码,以下:node
node { checkout scm echo "current branch: $BRANCH_NAME" try { if (BRANCH_NAME.startsWith("release/")) { sh "./gradlew clean -Ppublish assemble" } else { sh "./gradlew clean assembleTest" } currentBuild.result = 'SUCCESS' } catch (any) { currentBuild.result = 'FAILURE' throw any } finally { if (currentBuild.result == 'FAILURE') { // send e-mail } } }12345678910111213141516171819
若是说,要把这个流程划分为多个阶段,那仍是挺简单的,在node
下增长stage
节点就能够了,以下:git
node { stage('Checkout') { checkout scm } stage('Build') { echo "current branch: $BRANCH_NAME" try { if (BRANCH_NAME.startsWith("release/")) { sh "./gradlew clean -Ppublish assemble" } else { sh "./gradlew clean assembleTest" } currentBuild.result = 'SUCCESS' } catch (any) { currentBuild.result = 'FAILURE' throw any } finally { if (currentBuild.result == 'FAILURE') { // send e-mail } } } }1234567891011121314151617181920212223
简单一加,构建一,在Jenkins web页面上就出现了个Stage View了。可是Jenkins会提示咱们,这种方式的stage声明已经弃用了。因此接下来介绍一下我所探索的更完整的Jenkinsfile写法。web
咱们先上一张项目最终的Stage View截图:express
这是实际项目的效果,多了加固和热修复相关阶段,本文暂时跳过。接下来,仍是使用原来的例子,介绍一下如何实现它。网络
首先,咱们的根节点应声明为pipeline
。
而后在pipeline
下,咱们再声明一个agent
节点。这个可就厉害了。好比一般咱们会有多个构建从节点,但这多个构建节点的配置可能不一样,好比有的只配置了Android环境用于执行Android项目构建,有的只能执行iOS项目构建,有的是用于执行Go项目的。那这么多不一样的节点怎么管理及分配呢?那就是经过对节点声明不一样的标签label
,而后在咱们的构建中指定标签,这样Jenkins就会找到有对应标签的节点去执行构建了。假设咱们如今用于执行Android项目构建的节点配置了Android
标签,那么咱们的配置将以下:并发
pipeline { agent { label 'Android' } }12345
在pipeline
内,咱们还能够定义一个options
,这个能够用于作什么呢?好比个人构建从节点资源有限,因此构建并发数我只定义为2。若是某个构建由于一些网络或其余问题卡住了,build了三天三夜都没停下来,其余要构建的任务(job)就只能排队一个个执行了,若是再来一个构建任务,它又构建了很久没停下来,那么后面的任务就都等不到了。一般遇到这样的状况咱们须要手动去取消一下任务,而options
里咱们能够为整个构建配置一个超时时间。
好比咱们的Android项目,一般整个构建都不会超过半个小时,那咱们就配置超时时间为半个小时,若是它超时了,就会终止此次的构建。所以,咱们的配置修改成以下:app
pipeline { agent { label 'Android' } options { timeout(time: 30, unit: 'MINUTES') } }12345678
options
还有其余配置,好比失败后重试整个pipeline的次数:retry(3)
。其余的就不一一介绍了,可翻文档。ide
接下来就是这篇博客的重点之一了。
前面提到,直接添加stage
是过期的作法。那么如今未过期的作法是什么呢?那就在在stages
里声明。
咱们在pipeline
下,增长一个stages
节点,而后在这个节点里再增长不一样的stage
。须要注意的是,这里咱们已经有默认的检出代码了,因此不须要再写checkout scm
。咱们将前面的构建步骤,划分为构建和发布。因此咱们的Jenkins脚本改成以下:post
pipeline { agent { label 'Android' } options { timeout(time: 30, unit: 'MINUTES') } stages { stage('Build') { steps { sh './gradlew assembleTest' } } stage('Publish') { steps { sh './gradlew firTest' } } } }1234567891011121314151617181920
注:上面的firTest
是我编写的发布到fir.im的插件里的任务。
可是有一点要注意,全部分支都要执行构建,却只有release
分支才须要发布到fir上供测试人员下载测试。因此咱们须要对Publish
阶段增长一个条件,即何时下执行,以下:
stage('Publish') { when { expression { BRANCH_NAME ==~ /release\/.*/ } } steps { sh './gradlew firTest' } }12345678
这里用到了groovy的正则匹配的语法,即BRANCH_NANE
以release/
开头时,才执行下面的步骤。
注意这里的steps
,是能够增长多个步骤的。好比构建成功后想要发个消息通知,那就里面增长发个消息通知的命令。
上面的stages
完成了咱们对构建分阶段步骤的需求,可是咱们还须要构建失败时可以发邮件通知到咱们,这里就用到了post
节点了。
咱们在pipeline
内增长post
节点,它定义的是在阶段运行结束时的操做,它支持这样一些后置条件:
always
老是运行,不管成功、失败仍是其余状态。
changed
当前状态与上一次构建状态不一样时就运行
failure
当前失败时才运行
success
当前成功时运行
unstable
不稳定状态时运行
aborted
被终止时运行。
咱们这里须要在失败时进行邮件通知,因此咱们添加这样的节点内容:
post { failure { // send e-mail } }12345
最终咱们的Jenkinsfile以下:
pipeline { agent { label 'Android' } options { timeout(time: 30, unit: 'MINUTES') } stages { stage('Build') { steps { sh './gradlew assembleTest' } } stage('Publish') { when { expression { BRANCH_NAME ==~ /release\/.*/ } } steps { sh './gradlew firTest' } } } post { failure { emailext( subject: "Jenkins build is ${currentBuild.result}: ${env.JOB_NAME} #${env.BUILD_NUMBER}", mimeType: "text/html", body: """<p>Jenkins build is ${currentBuild.result}: ${env.JOB_NAME} #${env.BUILD_NUMBER}:</p> <p>Check console output at <a href="${env.BUILD_URL}console">${env.JOB_NAME} #${env.BUILD_NUMBER}</a></p>""", recipientProviders: [[$class: 'CulpritsRecipientProvider'], [$class: 'DevelopersRecipientProvider'], [$class: 'RequesterRecipientProvider']] ) } } }