Jenkins pipeline(流水线)是Jenkins 2.x 或以上版本提供的一套插件,是实现jenkins自动化引擎的另一种强大工具。它支持实现和集成持续交付流水线到 Jenkins。对Jenkins 流水线的定义可以通过在Jenkins经典UI中直接输入基本的pipeline script
;也可以被写在一个文本文件中 ( Jenkinsfile
),该文件可以被提交到项目的源代码仓库的根目录中,通过配置pipeline项目下载jenkinsfile文件并自动执行
pipeline脚本可以使用两种语法进行编写: 声明式和脚本式。声明式和脚本式的流水线从根本上是不同的,但都是建立在底层流水线的子系统上的,使用声明式流水线可以利用Jenkins流水线更好的特性:
脚本式流水线为Jenkins用户提供了大量的灵活性和可扩展性。但是 Groovy学习路线通常不适合团队的所有成员; 因此创造了声明式流水线来为编写Jenkinsfile提供一种更简单、更有结构性的语法。声明式流水线鼓励声明式编程模型。 而脚本化流水线遵循一个更趋近于命令式的编程模型 ,它们的主要区别在于语法和灵活性。
虽然他们都是”流水线即代码“的基础,但是创建 Jenkinsfile
并提交它到源代码仓库中提供了一些好处:
下面简单介绍一下这两种流水线语法模板:
在脚本式流水线语法中, 使用一个或多个 node
块来指定代理主机来执行流水线中的核心任务。 它根据在jenkins系统内配置的代理主机的标签选择主机,该配置不是必须的。
# 如果没有指定slave主机,则默认在master主机执行任务
node {
stage('Build') {
}
stage('Test') {
}
stage('Deploy') {
}
}
说明
node
是脚本式流水线的一种特定语法,它指示 Jenkins 在任何可用的代理/节点上执行流水线 (包含在其中的任何stage)。
stage('Build')
定义 “Build” 阶段,stage块在脚本式流水线语法中是可选的,不过在脚本式pipeline中使用stage块 ,在执行时可以清楚的显示每个stage的任务子集,所以stage块还是建议使用。
上面的stage括号内的字符串(Build)为自定义的,不一定非得根据官方给出的范例填写,方便自己区分即可。
示例如下:
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'pwd'
}
}
stage('Test'){
steps {
sh 'make check'
junit 'reports/**/*.xml'
}
}
stage('Deploy') {
steps {
sh 'deploy'
}
}
}
}
说明
pipeline {}
是声明式流水线的特定语法,他定义了包含执行整个流水线的所有内容;
agent
是声明式流水线中必须的关键字,它指定一个执行器或者代理节点用来执行流水线;
stage{}
描述要执行的任务的语法块。一个stage块包含一个steps;
steps{}
是声明式流水线的特定语法,它描述了在这个 stage 中要运行的步骤;
sh
用来执行shell命令 ;
由上面的简单示例可以发现,声明式限制了用户使用更严格和预定义的结构, 使其成为更简单的持续交付流水线的理想选择。而脚本式提供了很少的限制, 以至于对脚本和语法的唯一限制往往是由Groovy子集本身定义的,而不是任何特定于流水线的系统, 这使他成为权利用户和那些有更复杂需求的人的理想选择。 但是在后续使用中会发现,在使用某些插件的情况下,使用脚本式流水线会比声明式流水线更加灵活好用。
流水线的代码定义了整个的交付和部署过程,在使用使用过程中,流水线通常包括测试(test)、构建(build)和交付部署(Deploy)应用程序等步骤 。一个完整的 pipeline
脚本由一系列pipeline块组成, 这些块的主要组成部分如下:
node和agent关键字都是用来指定jenkins的代理节点 ,它是jenkins环境的一部分并且可以用来执行pipeline。node
是脚本化流水线语法的关键部分,agent是声明式流水线语法的关键部分
stages
块定义了在整个流水线中的执行任务的不同子集(比如 “Build”, “Test” 和 “Deploy” 阶段),每一个子集通常是一段代码块,在以后可能会遇到stage,一个stages可以包含多个stage。
一个单一的任务, 它告诉Jenkins 在特定的阶段要做什么。 通常放在stage下面,也是由一段代码或者一个模块构成。
了解了基本概念,下面对前面提到的两种类型的pipeline语法进行一个简单的介绍。
所有有效的声明式流水线代码必须包含在一个 pipeline
块中, 比如:
pipeline {
....
}
在声明式流水线中有效的基本语句和表达式遵循与 Groovy的语法同样的规则, 但是有以下例外:
pipeline {}
。agent
,声明式流水线设置代理节点的指令,用于指定执行pipeline脚本的slave节点或其他机器。agent
部分可以放在 pipeline
块的顶层被定义, 也可以放在 stage 块下定义。
参数
为了适用各种可能的代理节点, agent
部分支持一些不同类型的参数。这些参数可以应用在pipeline
块的顶层, 也可以应用在stage
指令内部。
在任何可用的代理上执行流水线或stage。例如: agent any
。
当在 pipeline
块的顶部没有配置全局的agent代理时, 该关键字将会被应用到整个流水线中,并且每个 stage
部分都需要定义自己的 agent
部分。如果指定了agent不为none,并且在stage也定了agent,则默认使用在stage中定义的agent。
可以通过lable
关键字指定设置了label
的Jenkins节点。 例如: agent { label 'jenkins-slave1' }
,该jenkins-slave1
为在系统中添加的jenkins slave节点,并且该节点的标签为jenkins-slave1
。
agent { node { label 'labelName' } }
和 agent { label 'labelName' }
效果是一样的, 但是 node
允许额外的选项 (比如 customWorkspace
,下面会说到)。
使用给定的镜像启动一个容器作为全局或某个stage执行的环境。该镜像将在指定的node或者通过label
关键字指定的节点上动态的生成容器来执行流水线操作。也可以理解为jenkins的动态slave节点。比如: agent { docker 'maven:3-alpine' }
。
docker
关键字也可以添加 args
参数,添加的参数可能包含直接传递到 docker run
时调用的参数,比如挂载目录。
agent {
docker {
image 'maven:3-alpine'
label 'my-defined-label'
args '-v /tmp:/tmp'
}
}
除了上面直接使用docker镜像启动容器以外,还可以使用通过 Dockerfile
构建的容器。 通常将Dockerfile
放到源代码仓库的根目录下 : agent { dockerfile true }
。
如果Dockerfile不在根目录下,也可以在其它目录下构建, 需要使用 dir
参数来指定dockerfile目录:
agent { dockerfile {dir 'someSubDir' } }
如果 Dockerfile
有另一个名称, 你可以使用 filename
选项指定该文件名。
如果构建时需要传递参数到dockerfile,可以使用 additionalBuildArgs
选项提交,比如:
agent { dockerfile {additionalBuildArgs '--build-arg foo=bar' } }
将上面的综合起来使用docker命令为 docker build -f Dockerfile.build --build-arg version=1.0.2 ./build/
,使用pipeline代码为:
agent {
dockerfile {
filename 'Dockerfile.build'
dir 'build'
label 'my-defined-label'
additionalBuildArgs '--build-arg version=1.0.2'
}
}
该关键字用于在kubenretes集群内动态的启动一个pod作为jenkins的slave节点去执行流水线操作,流水线执行完毕后pod自动销毁,官网给出的示例如下:
agent {
kubernetes {
label podlabel
yaml """
kind: Pod
metadata:
name: jenkins-slave
spec:
containers:
- name: kaniko
image: gcr.io/kaniko-project/executor:debug
imagePullPolicy: Always
command:
- /busybox/cat
tty: true
volumeMounts:
- name: aws-secret
mountPath: /root/.aws/
- name: docker-registry-config
mountPath: /kaniko/.docker
restartPolicy: Never
volumes:
- name: aws-secret
secret:
secretName: aws-secret
- name: docker-registry-config
configMap:
name: docker-registry-config
"""
}
看着有些复杂凌乱,但实际使用kubernetes agent
的时候,如果用到脚本式语法,可能就会比这个简单的多。
agent的一些常见选项
有一些选项关键字可应用于有多个 agent
的pipeline。
该选项用于全局流水线或个别的 stage
。该选项对 node
, docker
和 dockerfile
都可用,但是如果使用 node
参数时需要使用lable。
自定义工作区,可以应用在 agent
的所有流水线或者一些 stage
。自定义工作区存在于节点工作区根目录下, 它既可以是一个相对路径, 也可以是一个绝对路径。比如:
agent {
node {
label 'my-defined-label'
customWorkspace '/some/other/path'
}
}
该选项对 node
, docker
和 dockerfile
有用 。
示例
在指定的slave节点上构建服务
pipeline {
agent none
stages {
stage('Build') {
agent { node { label 'master' } }
steps {
sh 'hostname'
}
}
stage('Test') {
agent { node { label 'slave1' } }
steps {
sh 'hostname'
}
}
}
}
在一个给定的容器镜像(maven:3-alpine
)上启动一个容器并执行定义在流水线中的所有步骤 。
pipeline {
agent { docker 'maven:3-alpine' }
stages {
stage('build') {
steps {
sh 'mvn clean install'
}
}
}
}
在指定的stage阶段根据给定的镜像启动一个容器并执行定义在流水线中的步骤。
pipeline {
agent none
stages {
stage('Build') {
agent { docker 'maven:3-alpine' }
steps {
echo 'Hello, Maven'
sh 'mvn --version'
}
}
stage('Test') {
agent { docker 'openjdk:8-jre' }
steps {
echo 'Hello, JDK'
sh 'java -version'
}
}
}
}
说明
在流水线最顶层定义了 agent none
会强制 stage
部分强制定义他自己的 agent
部分。
包含一个或多个 stage
指令,pipeline所做的所有工作都会封装在一个或多个 stage
指令中。 建议 stages
至少包含一个 stage 指令,示例如下:
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}
需要说明的是,stages指令是声明式脚本中特有的,包括下面即将说到的steps,也是声明式脚本中特有的,脚本式的流水线中只有stage指令。
steps
部分是在给定的 stage
中定义的一个或多个step(代码),它包含一个完整的step列表, 而在step里可以定义环境变量,执行脚本等操作,如下示例:
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
}
steps {
script{
sh 'hostname'
}
}
}
}
}
需要注意的是,在声明式语法中,steps块是必须的。
options
指令用于在流水线内部配置特定与全局pipeline或者特定stage的选项。 流水线提供了许多这样的选项,比如 buildDiscarder
,该参数可以设置保存job的构建记录的历史数量和要保存的时间;该选项除了可以使用内置参数外,也可以使用由插件提供的参数, 比如 podTemplate
。
buildDiscarder
用于设置在UI中显示流水线执行的历史数量和保存的天数。例如: options { buildDiscarder(logRotator(numToKeepStr: '1')) }
。
disableConcurrentBuilds
不允许同时执行流水线。 可被用来防止同时访问共享资源等。 例如: options { disableConcurrentBuilds() }
。
skipDefaultCheckout
在agent
指令中,跳过从源代码库中检出代码步骤。例如: options { skipDefaultCheckout() }
。
skipStagesAfterUnstable
如果构建状态变成UNSTABLE,则跳过该阶段。例如: options { skipStagesAfterUnstable() }
。
checkoutToSubdirectory
将代码保存到工作目录的子目录。例如: options { checkoutToSubdirectory('foo') }
。
timeout
设置流水线运行的超时时间,如果超过该时间,Jenkins将中止流水线。例如: options { timeout(time: 1, unit: 'HOURS') }
。
retry
在执行失败时,重新执行整个流水线的指定次数。 例如: options { retry(3) }
。
timestamps
用于在控制台输出流水线各步骤执行时的当前时间, 例如: options { timestamps() }
。
示例如下:
pipeline {
agent any
options {
timeout(time: 1, unit: 'HOURS')
}
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}
该示例用于设置流水线执行的超时时间。
options
指令除了可以定义全局的选项参数外,也可以定义stage级别的options选项参数。 stage
级别的 options
只能包括 retry
, timeout
, 或 timestamps
等选项,或与 stage
相关的声明式选项,如 skipDefaultCheckout
。
在stage
中定义的options
指令中的参数在进入 agent
之前被调用或在 when
条件出现时进行检查。
可选的stage选项
skipDefaultCheckout
在 agent
指令中跳过默认的从源代码仓库检出代码。例如: options { skipDefaultCheckout() }
。
timeout
设置此阶段的超时时间,如果超过该时间, Jenkins 会终止该阶段。 例如: options { timeout(time: 1, unit: 'HOURS') }
。
retry
在job失败时, 重新执行测次数。 例如: options { retry(3) }
。
timestamps
用于在控制台输出流水线各步骤执行时的当前时间。例如: options { timestamps() }
。
示例如下
pipeline {
agent any
stages {
stage('Example') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
echo 'Hello World'
}
}
}
}
environment
指令用来定义一个或多个由key=value
键值对组成的为所有stage使用的环境变量,至于该环境变量全局的还是特定stage的取决于 environment
指令在流水线内定义的位置。
示例如下:
pipeline {
agent any
environment {
unit_test = 'true'
version = "v1"
JAVA_HOME='/data/jdk'
}
stages {
stage('Example') {
steps('test1') {
script {
if ( unit_test ) {
echo version
}
}
echo "$JAVA_HOME"
}
}
}
}
该示例定义了三个全局的环境变量。
environment
指令也可以通过 credentials()
方法引用事先在jenkins中创建的凭据。该方法支持的类型如下:
Secret Text
指定的环境变量将设置为secret文本内容。
Secret File
指定的环境变量将设置为临时创建的文件文件。
Username and password-
指定的环境变量将被设置为username:password
,另外两个环境变量将被自动定义:MYVARNAME_USR
和MYVARNAME_PSW
。
SSH与Private Key-
指定的环境变量将被设置为临时创建的SSH密钥文件,并且可能会自动定义两个其他环境变量:MYVARNAME_USR
和MYVARNAME_PSW
。
如下示例:
pipeline {
agent any
environment {
CC = 'clang'
}
stages {
stage('test-secret') {
environment {
SERVICE_CREDS = credentials('3d0e85b7-30cd-451d-bf9e-e6d87f6c9686')
SSH_CREDS = credentials('160-ssh')
}
steps {
sh 'printenv'
sh 'echo "Service user is $SERVICE_CREDS_USR"'
sh 'echo "Service password is $SERVICE_CREDS_PSW"'
sh 'echo "SSH user is $SSH_CREDS_USR"'
sh 'echo "SSH passphrase is $SSH_CREDS_PSW"'
}
}
stage('test-usrename-password') {
environment {
SERVICE_CREDS = credentials('auth_harbor')
SSH_CREDS = credentials('160-ssh')
}
steps {
sh 'echo "Service user is $SERVICE_CREDS_USR"'
sh 'echo "Service password is $SERVICE_CREDS_PSW"'
sh 'echo "SSH user is $SSH_CREDS_USR"'
sh 'echo "SSH passphrase is $SSH_CREDS_PSW"'
}
}
}
}
parameters
(参数)指令提供在触发流水线时应该提供的参数列表。这些指定参数的值可通过 params
对象提供给流水线steps,可用的参数类型如下:
string
字符串类型的参数,比如:parameters { string(name: 'DEPLOY_ENV', defaultValue: 'staging', description: '') }
text
文本类型的参数, 可以包含多行内容, 比如: parameters { text(name: 'DEPLOY_TEXT', defaultValue: 'One\nTwo\nThree\n', description: '') }
booleanParam:布尔类型的参数, 比如:parameters { booleanParam(name: 'DEBUG_BUILD', defaultValue: true, description: '') }
choice:选择类型的参数, 比如:parameters { choice(name: 'CHOICES', choices: ['one', 'two', 'three'], description: '') }
password:密码类型测参数, 比如:parameters { password(name: 'PASSWORD', defaultValue: 'SECRET', description: 'A secret password') }
示例如下:
pipeline {
agent any
parameters {
string(name: 'version', defaultValue: 'latest', description: 'the image version')
text(name: 'BIOGRAPHY', defaultValue: '', description: 'Enter some information about the person')
booleanParam(name: 'test', defaultValue: true, description: 'Toggle this value')
choice(name: 'build_number', choices: ['One', 'Two', 'Three'], description: 'the build_number')
password(name: 'PASSWORD', defaultValue: 'mypassword', description: 'Enter a password')
}
stages {
stage('print') {
steps {
echo " ${params.version}"
echo " ${params.BIOGRAPHY}"
echo "${params.test}"
echo "${params.build_number}"
echo "${params.PASSWORD}"
}
}
}
}
说明:
name
为定义的参数的名称,引用参数时通过name引用。
parameters
的语法片段可以在片段生成器(后面详细介绍)中生成,如下所示:
选择好参数类型设置好参数后直接点击Generate Declarative directive
即可。
triggers
(触发器)指令定义了流水线被触发的自动化方法。对于与源代码集成的流水线(pipeline脚本放到源码库),可能不需要 triggers
。 当前可用的触发器是 cron
, pollSCM
和 upstream
。
cron- 接收crontab格式(linux crontabl)的字符串来定义要触发流水线的间隔 。
示例如下:
pipeline {
agent any
triggers {
cron('0 */4 * * 1-5')
}
stages {
stage('test') {
steps {
echo 'Hello World'
}
}
}
}
该pipeline会定时触发执行
pollSCM
接收cron样式的字符串来定义一个固定的间隔,在这个间隔中,Jenkins会检查新的源代码更新。如果源码存在更改,,流水线就会被重新触发。
例如:
pipeline{
agent any
triggers{
pollSCM('5 10 * * *')
}
stages{
stage('test-code'){
steps{
echo "周期性检查代码测试"
}
}
}
}
upstream
接受逗号分隔的job名称。 当字符串中的任何job以最小阈值结束时,流水线被重新触发。例如:
pipeline{
agent any
triggers{
upstream(upstreamProjects: 'job1,job2', threshold: hudson.model.Result.SUCCESS)
}
stages{
stage('test-upstream'){
steps{
echo "当job1或job2执行成功时,触发该流水线"
}
}
}
}
其中hudson.model.Result
可包含以下属性:
ABORTED
:任务被手动中止FAILURE
:构建失败SUCCESS
:构建成功UNSTABL
:存在一些错误,但构建没失败NOT_BUILT
:多阶段构建时,前面阶段问题导致后面阶段无法执行tools(工具),用来定义自动安装或者已经在jenkins系统中配置的工具。如果指定 agent none
,该操作被忽略。
支持的工具包括maven,jdk,gradle等,示例如下:
pipeline {
agent any
tools {
maven 'apache-maven-3.5'
jdk 'jdk1.8'
}
stages {
stage('Example') {
steps {
sh 'mvn --version'
}
}
}
}
需要注意的是,apache-maven-3.5
该名称为在Global Tool Configuration
中定义的maven工具的名称。
when
指令允许流水线根据给定的条件决定是否应该执行stage。 when
指令必须包含至少一个条件, 如果 when
指令包含多个条件, 所有的子条件必须都返回True,stage才能执行。 这与子条件在 allOf
条件下嵌套的情况相同。
when包含诸多内置条件,使用如 not
, allOf
或 anyOf
的嵌套条件可以构建更复杂的条件结构,内置的条件如下:
branch
当正在构建的分支与给定的分支匹配时,执行这个stage,例如:
when { branch 'master' }
。
注意,这只适用于多分支流水线。
pipeline {
agent any
stages {
stage('Example Deploy') {
when {
branch 'production'
}
steps {
echo 'Deploying'
}
}
}
}
当指定的环境变量是给定的值时,执行这个steps 例如:
when { environment name: 'DEPLOY_TO', value: 'production' }
pipeline {
agent any
stages {
stage('Example Deploy') {
when {
branch 'production'
environment name: 'DEPLOY_TO', value: 'production'
}
steps {
echo 'Deploying'
}
}
}
}
当指定的Groovy表达式结果为true时,执行这个stage 例如:
when { expression { return params.DEBUG_BUILD } }
pipeline {
agent any
stages {
stage('Example Deploy') {
when {
expression { BRANCH_NAME ==~ /(production|staging)/ }
}
steps {
echo 'Deploying'
}
}
}
}
当嵌套条件是错误时,执行这个stage,必须包含一个条件,例如:
when { not { branch 'master' } }
当所有的嵌套条件都正确时,执行这个stage,必须包含至少一个条件,例如:
when { allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } }
pipeline {
agent any
stages {
stage('Example Deploy') {
when {
allOf {
branch 'production'
environment name: 'DEPLOY_TO', value: 'production'
}
}
steps {
echo 'Deploying'
}
}
}
}
当至少有一个嵌套条件为真时,执行这个stage,必须包含至少一个条件,例如:
when { anyOf { branch 'master'; branch 'staging' } }
pipeline {
agent any
stages {
stage('Example Deploy') {
when {
branch 'production'
anyOf {
environment name: 'DEPLOY_TO', value: 'production'
environment name: 'DEPLOY_TO', value: 'staging'
}
}
steps {
echo 'Deploying'
}
}
}
}
equals
当期望值等于实际值时执行stage,比如:
when { equals expected: 2, actual: currentBuild.number }
,
when { equals expected: 2, actual: currentBuild.number }
tag
如果TAG_NAME
变量匹配给定的值,则执行stage。比如:
when { tag "release-*" }
。
如果提供了空值,则在TAG_NAME
变量存在时(与buildingTag()相同)将执行stage。
beforeagent
默认情况下,如果定义了某个stage的agent代理,在进入该stage
的 agent
后,该 stage
的 when
条件将会被做判断。但是,在when语法块中可以通过 beforeAgent
参数来更改此条件。 如果 beforeAgent
被设置为 true
, 那么就会首先对 when
条件进行评估 , 并且只有在 when
条件验证为真时才会进入 agent
。
pipeline {
agent none
stages {
stage('deploy-pro') {
agent {
label "some-label"
}
when {
beforeAgent true
branch 'master'
}
steps {
echo 'Deploying'
}
}
}
}
该示例表示只有当分支为master时,才会进入deploy-pro
阶段,这样避免了进入agent中拉取代码,从而提高pipeline执行效率。
声明式流水线的stage可以在他们内部声明多个嵌套stage,某些条件下可以让它们并行执行。
注意,一个stage必须只有一个 steps
或 parallel
的stage。 嵌套stage本身不能包含进一步的 parallel
stage, 任何包含 parallel
的stage不能包含 agent
或 tools
, 因为他们没有相关 steps
。
另外, 通过添加 failFast true
到包含 parallel
的 stage
中, 当其中一个进程失败时,会强制所有的 parallel
阶段都被终止。
如下示例:
pipeline {
agent any
stages {
stage('Non-Parallel Stage') {
steps {
echo 'This stage will be executed first.'
}
}
stage('Parallel Stage') {
when {
branch 'master'
}
failFast true
parallel {
stage('Branch A') {
agent {
label "for-branch-a"
}
steps {
echo "On Branch A"
}
}
stage('Branch B') {
agent {
label "for-branch-b"
}
steps {
echo "On Branch B"
}
}
stage('Branch C') {
agent {
label "for-branch-c"
}
stages {
stage('Nested 1') {
steps {
echo "In stage Nested 1 within Branch C"
}
}
stage('Nested 2') {
steps {
echo "In stage Nested 2 within Branch C"
}
}
}
}
}
}
}
}
除了上面的failFast true
方法外,也可以使用parallelsAlwaysFailFast()
方法。
pipeline {
agent any
options {
parallelsAlwaysFailFast()
}
stages {
stage('Non-Parallel Stage') {
steps {
echo 'This stage will be executed first.'
}
}
stage('Parallel Stage') {
when {
branch 'master'
}
parallel {
stage('Branch A') {
......
}
stage('Branch B') {
......
}
stage('Branch C') {
agent {
label "for-branch-c"
}
stages {
stage('Nested 1') {
steps {
echo "....."
}
}
stage('Nested 2') {
steps {
echo "...."
}
}
}
}
}
}
}
}
post
指令可以定义一个或多个steps ,它根据流水线的完成情况而运行。post
支持的条件如下:
always
无论流水线或stage的完成状态如何,在 post
部分定义的steps都会运行。
changed
只有当前流水线或stage的完成状态与它之前的运行状态不同时,在 post
部分定义的steps才会运行。
failure
只有当前流水线或stage的完成状态为”failure”,在 post
部分定义的steps才会运行。 通常web UI是红色。
success
只有当前流水线或stage的完成状态为”success”,在 post
部分定义的steps才会运行。常web UI是蓝色或绿色。
unstable
只有当前流水线或stage的完成状态为”unstable”,在 post
部分定义的steps才会运行。通常由于测试失败,向远程服务器拷贝文件时连接服务器失败等原因造成。通常web UI是黄色。
aborted
只有当前流水线或stage的完成状态为”aborted”,在 post
部分定义的steps才会运行, 通常由于流水线被手动的终止。通常web UI是灰色。
了解完post执行的条件,下面看一个示例:
pipeline {
agent any
stages {
stage('test') {
steps {
echo 'Hello World'
}
}
}
post {
always {
echo 'I will always say Hello again!'
}
}
}
该示例表示无论stages执行结果如何,定义的post部分都会运行。
也可以根据执行结果加上判断,比如:
post {
always {
script{
if (currentBuild.currentResult == "ABORTED" || currentBuild.currentResult == "FAILURE" || currentBuild.currentResult == "UNSTABLE" ){
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']]
)
}
}
}
}
该示例在流水线执行失败或者强制终止后发送邮件给指定的邮件接收者。
有关声明式语法介绍就到这里,下一节会通过对比来介绍一下脚本式语法的相关内容。
© 2019 - 2023 Liangliang Lee. Powered by gin and hexo-theme-book.