Pipeline语法
介绍
本文基于入门介绍,仅仅是一个语法参考。至于如何在特定的例子中运用Pipeline语法,请参考Jenkins Pipeline。从插件Pipeline plugin的2.5版本开始,Pipeline支持两种格式的语法。对于它们之间的区别请参考语法对比。
正如在入门介绍里说的,流水线最主要的就是”步骤“。基本上,就是步骤来告诉Jenkins该干什么,它是申明式和脚本式流水线语法的基础。
你可以在流水线步骤参考中,找到一份可用的步骤列表。
申明Pipeline
申明式流水线是最近添加到Jenkins流水线功能中的,这种语法更加简单。
所有合法的申明式流水线必须在 pipeline 代码块中,例如:
pipeline {
/* insert Declarative Pipeline here */
}
在申明式流水线中,基本的语句和表达式是遵循 Groovy语法 ,但是有以下几个例外:
- 流水线的顶层必须是一个代码块: pipeline { }
- 不需分号作为语句的分隔符。每个语句单独占一行
- 只能包括段落、步骤、或者赋值语句
- 属性引用语句被当作无参数的方法调用。例如:input会当作方法input()
段落
在申明式流水线中,通常包括一个或者多个指令或者步骤。
代理agent
代理指定了整个流水线或者特定的阶段的运行环境。它必须在pipeline块的顶层定义,而在阶段中是可选的。
参数
为了支持多种情况的流水线使用场景,代理(agent)支持几种不同类型的参数。这些参数既可以在顶层的pipeline块也可以在每个阶段中使用。
any
在任意可用的代理上执行流水线。例如: agent any
none
当在顶层的pipeline块中使用时,不会有全局的代理分配给整个流水线,每个阶段都需要包含个人的代理。例如:agent none
label
根据Jenkins环境中提供的标签,确定一个可用的代理来chiding流水线或者阶段。例如:agent { label ‘my-defined-label’ }
node
agent { node { label ‘labelName’ } } 和 agent { label ‘labelName’ }一样,但是 node 允许增加选项(例如 customWorkspace)
docker
在指定的容器里执行流水线或者阶段,容器会被动态分配到预先配置好的基于Docker的流水线节点,或者通过label参数来匹配。docker也有一个可选参数args,该参数会直接传递给docker run来执行;还有一个alwaysPull 选项,及时镜像名已经存在了依然会强制执行docker pull。
例如:
agent {
docker 'maven:3-alpine'
}
或者:
agent {
docker {
image 'maven:3-alpine'
label 'my-defined-label'
args '-v /tmp:/tmp'
}
}
dockerfile
由码线中的Dockerfile构建出来的容器,执行流水线或者阶段。为了使用该特性,Jenkinsfile 必须是在多分支流水线或者从SCM中加载。约定Dockerfile 在码线的根目录中,可以是agent { dockerfile true } 。如果Dockerfile 在另外一个目录中,可以使用参数dir :agent { dockerfile { dir ‘someSubDir’ } } 。如果Dockerfile 有其他的名称,你可以通过参数filename 指定文件名称。你可以通过参数additionalBuildArgs 给命令docker build … 传递额外的选项,例如agent { dockerfile { additionalBuildArgs ‘–build-arg foo=bar’ } } 。例如:一个码线有文件build/Dockerfile.build,并需要一个构建参数version:
agent {
// Equivalent to "docker build -f Dockerfile.build --build-arg version=1.0.2 ./build/
dockerfile {
filename 'Dockerfile.build'
dir 'build'
label 'my-defined-label'
additionalBuildArgs '--build-arg version=1.0.2'
}
通用选项Common Options
有一些选项可以在多种代理实现中使用。没有指定的话,就不是必须的。
label
字符串。可以在流水线或者 stage上。
该选项可以在 node,docker 和 dockerfile中使用,但对于 node是必须的。
customWorkspace
字符串。指定工作空间,而不使用默认的。可以是相对于节点上的根工作空间,也可以是绝对路径。例如:
agent {
node {
label 'my-defined-label'
customWorkspace '/some/other/path'
}
}
该选项可以用在 node, docker 和 dockerfile。
reuseNode
布尔值,默认为false。如果为true,则在相同的工作空间中运行,而不是每次创建新的。
该选项可以在 docker 和 dockerfile中使用,而且只有在 agent 配置到单独的 stage中才能使用。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent { docker 'maven:3-alpine' }
stages {
stage('Example Build') {
steps {
sh 'mvn -B clean verify'
}
}
}
}
Jenkinsfile (Declarative Pipeline)
pipeline {
agent none
stages {
stage('Example Build') {
agent { docker 'maven:3-alpine' }
steps {
echo 'Hello, Maven'
sh 'mvn --version'
}
}
stage('Example Test') {
agent { docker 'openjdk:8-jre' }
steps {
echo 'Hello, JDK'
sh 'java -version'
}
}
}
}
- post
- 阶段stages
- 步骤steps
- 指令Directive
- 环境environment
- 选项options
- 参数parameters
- 触发器triggers
- 阶段stage
- 工具tools
- 输入input
- 条件when
指令when 允许流水线根据条件来决定是否要执行特定的阶段。指令when 必须至少包含一个条件。如果指令when 包含多个条件,所有的条件都必须为true才可以会执行该阶段。这和allOf 条件是类似的(请参考下面的例子)。
更复杂的结构可以使用嵌套:not, allOf,或 anyOf。可以嵌套任意深度。
内置条件:
分支branch
当匹配分支名称时执行,例如: when { branch ‘master’ }。这只有在多分支流水线中才可以使用。
环境environment
当指定的环境变量值和给定的一样时执行,例如: when { environment name: ‘DEPLOY_TO’, value: ‘production’ }
表达式expression
当Groovy表达式为true时,例如: when { expression { return params.DEBUG_BUILD } }
not
当嵌套条件值为false时执行。必须包含一个条件。例如: when { not { branch ‘master’ } }
allOf
当嵌套条件为true时执行。必须至少包含一个。例如: when { allOf { branch ‘master’; environment name: ‘DEPLOY_TO’, value: ‘production’ } }
anyOf
当任意一个表达式为true时。必须至少包含一个。例如: when { anyOf { branch ‘master’; branch ‘staging’ } }
在进入阶段的代理节点之前计算when表达式
默认情况下,when 条件是在进入阶段的代理之后计算。然而,通过增加选项beforeAgent 可以改变。如果把选项beforeAgent 设置为true,就会首先计算when 条件,只有在值为true时才会进入。
示例1:
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
when {
branch 'production'
}
steps {
echo 'Deploying'
}
}
}
}
示例2:
pipeline {
agent any
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
when {
branch 'production'
environment name: 'DEPLOY_TO', value: 'production'
}
steps {
echo 'Deploying'
}
}
}
}
示例3:
pipeline {
agent any
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
when {
allOf {
branch 'production'
environment name: 'DEPLOY_TO', value: 'production'
}
}
steps {
echo 'Deploying'
}
}
}
}
示例4:
pipeline {
agent any
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
when {
branch 'production'
anyOf {
environment name: 'DEPLOY_TO', value: 'production'
environment name: 'DEPLOY_TO', value: 'staging'
}
}
steps {
echo 'Deploying'
}
}
}
}
示例5:
pipeline {
agent any
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
when {
expression { BRANCH_NAME ==~ /(production|staging)/ }
anyOf {
environment name: 'DEPLOY_TO', value: 'production'
environment name: 'DEPLOY_TO', value: 'staging'
}
}
steps {
echo 'Deploying'
}
}
}
}
示例6:
pipeline {
agent none
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
agent {
label "some-label"
}
when {
beforeAgent true
branch 'production'
}
steps {
echo 'Deploying'
}
}
}
}
并发parallel
阶段是可以并行执行的。注意,在阶段内必须要只能有一个steps 或 parallel。任何包含parallel 的阶段不能包括agent 或 tools,也不包括steps。
另外,当有一个任务失败后,你可以强制整个并行失败。只要设置参数failFast 为true就可以。
示例:
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"
}
}
}
}
}
}
步骤
脚本
script 可以在申明时的流水线中执行脚本时步骤。大多数情况下 script 是用不到的。
示例:
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
script {
def browsers = ['chrome', 'firefox']
for (int i = 0; i < browsers.size(); ++i) {
echo "Testing the ${browsers[i]} browser"
}
}
}
}
}
}
脚本化流水线
脚本化流水线可以使用普通的Groovy语法,因此,它可以实现很强大的功能。
在Jenkins流水线刚被开发出来时,采用Groovy作为基础。Jenkins已经很长时间内采用嵌入式的Groovy引擎提供了高级脚本功能给管理员和普通用户。也就是说,基于Groovy脚本的流水线指的就是脚本化流水线。