Pipeline 简介
Jenkins2.x 的核心是使用 pipeline 来构建项目,也就是流水线,将 Jenkins1.0 版本中基于表单的配置信息比如 JDK/SVN 以及参数的配置都转变成了代码,即 pipeline as Code。
传统的表单方式有以下缺点:
- 需要大量的 web 表单交互,有时候需要进行很多次的切换,比较繁琐。
- 不能进行版本管理。
- 可重用性差。
而采用 pipeline 的方式,项目的所有流程和配置都写在 Jenkinsfile 文件中,移植时只要将此文件拷贝即可,无须繁琐的配置;而且 pipeline 可以很直观的看到每个阶段的构建情况,再结合上 Blue Ocean 可以进行强大的流水线监控,方便、直观、及时地获取到构建结果。
在 Jenkins 中,把每一段管道比作是不同的 Job,不同 Job 的链接就需要用到 Pipeline 插件。Jenkins 的工作流程可以简单概括为 build-deploy-test-release,每个流程之间我们都可以用 Pipeline 来连接,大致如下效果图:
Jenkins pipeline 是基于 Groovy 语言实现的一种 DSL(Domain-Specific Language,领域特定语言),可以理解为适用于 Jenkins 的编程语言。
pipeline 支持两种语法:脚本式语法(scripted pipeline)和声明式语法(declarativepipeline)。早期的 pipeline plugin 只支持脚本式语法,声明式语法是在 pipeline2.5 之后新增加的,相对而言,声明式语法更简单,即使没有 groovy 语言的基础也能进行基本的操作。Jenkins 社区的动向也是偏向于声明式语法,所以以声明式语法为例进行说明。
Pipeline 基本结构
pipeline{agent anystages{stage('build'){steps{echo 'build steps'}}}
}
以上是最最基本的一个 pipeline 结构,具体的含义如下:
- pipeline:后面用一对 {} 也就是闭包,表示整条流水线,里面是流水线中具体的处理流程。
- agent:用来指定整个流水线或者某一个阶段在哪个机器节点上执行。如果是 any 的话表示该流水线或者阶段可以运行在任意一个定义好的节点上。这个指令必须要有,而且一般会放在顶层 pipeline{...} 的下一层,在 stage{...} 中也可以使用 agent,但是一般不这么用。
- stages:后面跟一对 {},类似于一个容器,封装了一个或多个 stage,也就是将不同的阶段组织在一起;例如 build 是一个 stage, test 是第二个 stage,deploy 是第三个 stage。通过 stage 隔离,让 Pipeline 代码读写非常直观。
- stage:后面跟一对 {},流水线中的某个阶段,其中封装了多个执行步骤,每个阶段都需要有个名称。
- steps:封装了在一个阶段中的一个或多个具体的执行步骤。在本例中 echo 就是一个步骤。
接下来我们一一介绍上面提到的 pipeline 中包含的最基本的几个 section,以及另外一些可选的 section。
agent
用来指定 pipeline 的执行节点,一般放在顶层的 pipeline 中。agent 部分支持几种不同的参数以此来适应不同的应用场景。
1)any
作用:表示可以在任意的节点或者代理上执行此 pipeline。
代码示例:
pipeline {agent any
}
2)none
作用:在 pipeline 的顶层应用中使用此参数的话表示不会为整个 pipeline 指定执行的节点,需要在每个 stage 部分用 pipeline 指定执行的节点。
代码示例:
pipeline {agent nonestages {stage('test'){agent {label '具体的节点名称'}}}
}
3)label
作用:在标签指定的可用代理上执行 pipeline 或 stage,比如 agent {label "label"} 表示流水线或者阶段可以运行在任何一个具有 label 标签的代理节点上。
代码示例:
pipeline {agent {label '具体的一个节点 label 名称'}
}
4)自定义工作空间
作用:代理节点的标签新增了一个特性,允许为流水线或阶段指定一个自定义的工作空间,用 customWorkspace 指令来指定。和 label 功能类似。
代码示例:
pipeline {agent {node {label "xxx-agent-机器"customWorkspace "${env.JOB_NAME}/${env.BUILD_NUMBER}"}}
}
此处的 node 可以换成 label,但是为了避免 Docker 代理节点中的 label 用法混淆,一般用 node 表示。这种类型的 agent 在实际工作中的使用场景是最多的。
测试代码
pipeline {agent {node {label "xxx-agent-机器"customWorkspace "${env.JOB_NAME}/${env.BUILD_NUMBER}"}} stages {stage ("Build") {bat "dir" //执行windows下的bat命令} stage ('test') {echo ${JAVA_HOME} //打印JAVA_HOME}}
}
可以将以上代码段放到 Jenkinsfile 中或者在 Jenkins ui 中去执行。
POST
post 部分用来指定 pipeline 或者 stage 执行完毕后的一些操作,比如发送邮件、环境清理等。post 部分在 Jenkins 代码中是可选的,可以放到顶层,也就是和 agent 同级,也可以放到stage 中。在 post 代码块中支持多种指令,比如:always、success、failure、aborted、unstable、changed 等等,我们一一来介绍。
1)always
作用:当 pipeline 执行完毕后一定会执行的操作,不管成功还是还失败。比如说文件句柄的关闭或者数据库的清理工作等。
代码示例:
pipeline {agent anystages {stage ("Build") {bat "dir"}} post {always {script {//写相关清除/恢复环境等操作代码}}}
}
2)success
作用:当 pipeline 执行完毕后且构建结果为成功状态时才会执行的操作。
代码示例:
pipeline {agent anystages {stage ("Build") {bat "dir"}} post {success{script {//写相关清除/恢复环境等操作代码}}}
}
3)failure
作用:当 pipeline 执行完毕后且构建结果为失败时执行的操作,比如发送错误日志给相关人员。
4)changed
作用:当 pipeline 执行完毕后且构建状态和之前不一致时执行的操作。
5)aborted
作用:当 pipeline 被手动终止时执行的操作。
6)unstable
作用:当 pipeline 构建结果不稳定时执行的操作。
7)以上命令的组合
在 post 部分是可以包含多个条件块,也就是以上命令的组合,比如:
pipeline {agent anystages {stage ("Build") {bat "dir"}}post {always {script {echo "post always "}} success{script {echo "post success"}} failure{script {echo "post failure"}}}
}
stages/stage/steps
- stages:Pipeline 中单个阶段的操作封装到 stages 中,stages 中可以包含多个 stage。
- stage:一个单独的阶段,实际上所有实际工作都将包含在一个或多个 stage 指令中。stage{…} 里面有一个强制的字符串参数,用来描述这个 stage 的作用,这个字符串参数是不支持变量的,只能你自己取名一个描述字段。
- steps:一个 stage 下至少有一个 steps,一般也就是一个 steps。可以在 steps 下写调用一个或者几个方法,也就是两三行代码。
有以下注意点:
- 在声明式 pipeline 脚本中,有且只有一个 stages。
- 一个 stage{…} 必须有且只有一个 steps{…}, 或者 parallel{…} 或者 stages {…},多层嵌套只支持在最后一个 stage{…} 里面。
- 在声明式语法中只支持 steps,不支持在 steps {…} 里面嵌套写 step{…}。
代码示例:
pipeline {agent anystages {stage