一、Jenkins pipeline 总体介绍
pipeline 是一套运行于jenkins上的工作流框架,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂流程编排与可视化。
pipeline 是jenkins2.X 最核心的特性, 帮助jenkins 实现从CI 到 CD与 DevOps的转变
pipeline 提供一组可扩展的工具, 通过 pipeline domain specific language syntax 可以到达pipeline as code 目的
pipiline as code : jenkinsfile 存储在项目的 源代码库
为什么要使用pipeline
1、代码: pipeline 以代码的形式实现,通过被捡入源代码控制, 使团队能够编译,审查和迭代其cd流程
2 可连续性: jenkins 重启 或者中断后都不会影响pipeline job
3.停顿: pipeline 可以选择停止并等待人工输入或者批准,然后在继续pipeline运行
4.多功能: pipeline 支持现实世界的复杂CD要求, 包括fork、join子进程,循环和并行执行工作的能力
5.可扩展: pipeline 插件支持其DSL的自动扩展以及其插件集成的多个选项。
pipeline 支持两种语法
- Declarative 声明式
- Scripted pipeline 脚本式
二、.语法比较
PipelineQ 支持两种语法:声明式和脚本式,
1、相同点:
都是"Pipeline as code"的有效实现方式:都能够使用内置于 Pipeline 或由插件提供的steps;都可以使用共享库
2、不同点:
声明式语法
Declarative pipeline鼓励声明式编程模型,通过严格和预定义的结构限制了用户可用的内容,使其变得更加简单、容易上手
一般情况下声明式的流水线已经可以满足我们的需要,可读性更强。所有的脚本都是在 pipeline {}内。
但是有个 Open Issue,就是 pipeline {} 中代码行数超过一定范围, 会出现 Method code too large! error in pipeline Script ,而 Scripted Pipeline 脚本式就没有行数限制。
脚本式语法
Scripted Pipeline 遵循更命令式的编程模型。就结构和语法的唯一限制往往由 GroovyQ 本身定义,而不是任何特定于 Pipeline 的系统 ,这使其具有极大的灵活性和可扩展性,成为高级用户和具有更复杂要求的用户的理想选择。
建议直接使用声明式语法,学习成本较低,适合大部分人入门。
三、声明式语法介绍
1、 语法结构
1.1、Sections(部分)
pipeline:代表整条流水线,包含整条流水线的逻辑。
agent:指定pipeline运行的节点,可为整个pipeline或特定stage指定运行环境,取决于所定义位置。
stages:pipeline中多个stage的容器,至少包含一个stage,是pipeline的主体部分。
steps:stage中的一个或多个具体步骤(step)的容器,steps部分至少包含一个步骤。
scripts:在Declarative Pipeline中,可采用script指令来执行Scripted Pipeline中的一些脚本
post:运行后处理步骤,根据定义的位置不同,可依据pipeline或stage的运行结果执行差异化步骤。
1.2、Directives(指令)
environment:环境变量,可定义为全局变量或特定stage中的局部变量,取决于所定义位置。
tools:构建工具,可为整个pipeline或特定stage指定在jenkins全局工具中定义过的工具的环境变量,支持maven、jdk、gradle等。
options:定义pipeline运行时的配置选项。如历史构建记录数量保留,超时时间,失败重试等操作。
triggers:触发器,定义pipeline运行的触发方式。
parameters:参数,为流水线运行时设置的参数列表。
stage:表示Pipeline的一个阶段,如checkout阶段,Build阶段,test阶段等,一个Pipeline中至少需要一个Stage。
input:交互输入,pipeline运行到input时会自动暂停,根据输入值评估是否继续。
when:条件判断,允许流水线根据给定的条件决定是否应该执行阶段。
2、语法详解
声明式pipeline 基本语法和表达式遵循 groovy语法,但是有以下例外:
1)声明式pipeline 必须包含在固定格式的pipeline{} 块内
2)每个声明语句必须独立一行, 行尾无需使用分号
3)块(Blocks{}) 只能包含章节(Sections),指令(Directives),步骤(Steps),或者赋值语句
4)属性引用语句被视为无参数方法调用。 如input()
块(Blocks{})
由大括号括起来的语句: 如 Pipeline{}, Sections{}, parameters{}, script{}
章节(Sections)
通常包括一个或者多个指令或步骤 如 agent,post,stages,steps
步骤(steps)
执行脚本式pipeline, 如script{}
3、Sections (部分)
3.1 agent
指定流水线的执行节点(Jenkins agent)
是否必须 | 必须存在,agent必须在pipeline块内的顶层定义,但是stage内是否使用为可选 |
参数 | any / none / label / node / docker / dockerfile / kubernetes |
描述 | 指定整个Pipeline或特定stage将在Jenkins环境中执行的位置,具体取决于该agent 部分的放置位置 |
参数说明
参数1:any(任何)
作用:在任何可用的代理上执行Pipeline或stage。
代码示例
pipeline {
agent any
}
上面这种是最简单的,如果你Jenkins平台环境只有一个master,那么这种写法就最省事情.
参数2:none(没有)
作用:当在pipeline块的顶层应用时,将不会为整个Pipeline运行分配全局代理,并且每个stage部分将需要包含其自己的agent部分。
代码示例:
pipeline {
agent none
stages {
stage(‘Build’){
agent {
label ‘具体的节点名称’
}
}
}
}
参数3:label(标签)
作用:使用提供的标签在Jenkins环境中可用的代理机器上执行Pipeline或stage内执行。
代码示例:
agent {
label 'my-label1 && my-label2'
}
参数4:node(节点)
作用:和上面label功能类似,但是node运行其他选项,例如customWorkspace
代码示例:
pipeline {
agent {
node {
label ‘xxx-agent-机器’
customWorkspace "${env.JOB_NAME}/${env.BUILD_NUMBER}"
}
}
}
参数5:docker
作用:动态供应一个docker节点去执行pipeline或stage,docker还可以接受一个args,直接传递给docker run调用。
代码示例:
agent {
docker {
image 'maven:3-alpine'
label 'my-defined-label'
args '-v /tmp:/tmp'
registryUrl 'https://myregistry.com/'
registryCredentialsId 'myPredefinedCredentialsInJenkins'
}
}
参数6:dockerfile
作用:使用从Dockerfile源存储库中包含的容器构建的容器执行Pipeline或stage,Jenkinsfile 必须从多分支 Pipeline或 SCM Pipeline加载。
代码示例:
agent {
// 等同于 to "docker build -f Dockerfile.build --build-arg version=1.0.2 ./build/
dockerfile {
filename 'Dockerfile.build'
// 如果要Dockerfile在另一个目录中构建,请使用以下dir选项
dir 'build'
label 'my-defined-label'
additionalBuildArgs '--build-arg version=1.0.2'
args '-v /tmp:/tmp'
// 同样也接受registryUrl和registryCredentialsId参数
registryUrl 'https://myregistry.com/'
registryCredentialsId 'myPredefinedCredentialsInJenkins'
}
}
参数7:kubernetes
作用:在Kubernetes集群上部署的Pod内执行 Pipeline或stage,同样Jenkinsfile 必须从多分支 Pipeline或 SCM Pipeline加载,Pod模板在kubernetes {} 块内定义。
3.2、 stages
包含一系列一个或多个 stage
指令, stages
部分是流水线描述的大部分 “work” 的位置。建议 stages
至少包含一个 stage
指令用于连续交付过程的每个离散部分,比如构建, 测试, 和部署。
是否必须 | 是,包括顺序执行的一个或者多个stage命令 |
参数 | 无 |
常用选项 | 构建后操作的内置判定条件always,changed,failure,sucess,unstable,aborted |
允许 | pipeline块内,有且仅有一次 |
参考案例
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}
3.3、stage
作用域 | 被stages包裹,作用在自己的stage包裹范围内 |
是否必须: | 必须 |
参数 | 需要一个string参数,表示此阶段的工作内容 |
备注 | stage内部可以嵌套stages,内部可单独制定运行的agent |
Jenkins 将会按照 Stages 中描述的顺序从上往下的执行。Stages 中可以包括任意多个 Stage,而 Stage 与 Stages 又能互相嵌套,除此以外还有 parallel 指令可以让内部的 Stage 并行运行。实际上可以把 Stage 当作最小单元,Stages 指定的是顺序运行,而 parallel 指定的是并行运行
参考案例
pipeline {
agent none
stages {
stage('Sequential') {
stages {
stage('In Sequential 1') {
steps {
echo "In Sequential 1"
}
}
stage('In Sequential 2') {
steps {
echo "In Sequential 2"
}
}
stage('Parallel In Sequential') {
parallel {
stage('In Parallel 1') {
steps {
echo "In Parallel 1"
}
}
stage('In Parallel 2') {
steps {
echo "In Parallel 2"
}
}
}
}
}
}
}
}
3.4、steps
是否必须 | 是,steps位于stage指令块内部,包括一个或者多个step |
参数 | 无 |
说明 | 仅有一个step的情况下可以忽略关键字step及其{} |
注意:
1.字符串的处理
Groovy 语法中有不同的字符串类型,其中单引号 ‘abc’ 是 Plain 字符串,不会转义 ${WROKSPACE} 这样的变量,而双引号 “abc” 会做这样的转换。此外还有三单引号 ‘’’ xxx ‘’’ 支持跨行字符串,三双引号 “”" 同理。
2.调用函数的 () 可以省略
使得函数调用形如 updateGitlabCommitStatus name: ‘build’, state: ‘success’,通过 , 来分割不同的参数,支持换行。
3.可以在声明式流水线中通过 script 来插入一段 groovy 脚本
steps中的一些常用操作
error:抛出异常,中断整个pipeline
timeout: 超时
waitUntil: 循环运行闭包内容,直到返回true,通常与timeout一起使用
retry:失败重试
sleep:睡眠,默认单位秒
参考案例
pipeline{
agent any
stages{
stage('stash'){
parallel('测试') {
stage('轮询') {
steps{
timeout(time:10, unit:"SECONDS"){ #超时
waitUntil{
script{
def rs = sh script: 'docker version', returnStatus: true
return (rs == 0)
}
}
}
}
}
stage('重试') {
steps{
retry(3){
script{
sh script: 'curl https://www.baidu.com', returnStatus: true
}
sleep(3)
}
}
}
stage('错误') {
steps{
retry(3){
error("执行失败")
}
}
}
}
}
}
}
3.5、post
定义Pipeline或stage运行结束时的操作, 比如消息通知、执行其他job等
post 部分定义一个或多个 steps ,这些阶段根据流水线或阶段的完成情况而 运行(取决于流水线中 post 部分的位置). post 支持以下 post-condition 块中的其中之一: always, changed, failure, success, unstable, 和 aborted。这些条件块允许在 post 部分的步骤的执行取决于流水线或阶段的完成状态。经常用于一些测试完毕后的清理和通知操作。文档中给出了一系列的情况,比较常用的是 always,success 和 failure
是否必须 | 否,用于pipeline的最外层或者stage{}中 |
参数 | always / changed / fixed / regression / aborted / failure / success / unstable / unsuccessful / cleanup |
参数说明
always
无论Pipeline或阶段的运行完成状态如何,都运行post部分中的步骤。
changed
仅当当前Pipeline的运行完成状态与上一次运行不同时,才运行post部分中的步骤。
fixed
仅当当前Pipeline的运行成功且上一次运行失败或不稳定时,才运行post部分中的步骤。
regression
仅当当前Pipeline的运行状态为失败、不稳定或中止,并且上一次运行成功时,才运行post部分中的步骤。
aborted
仅当当前Pipeline的运行状态为"aborted"时才运行post部分中的步骤,通常是由于手动中止Pipeline导致的。在Web界面中通常以灰色表示。
failure
仅当当前Pipeline或阶段的运行状态为"failed"时才运行post部分中的步骤,通常在Web界面中以红色表示。
success
仅当当前Pipeline或阶段的运行状态为"success"时才运行post部分中的步骤,通常在Web界面中以蓝色或绿色表示。
unstable
仅当当前Pipeline的运行状态为"unstable"时才运行post部分中的步骤,通常由测试失败、代码违规等引起。在Web界面中通常以黄色表示。
unsuccessful
仅当当前Pipeline或阶段的运行状态不为"success"时才运行post部分中的步骤。在Web界面中根据前面提到的状态进行表示(对于阶段,如果构建本身不稳定,可能会触发此条件)。
cleanup
在评估了其他所有后置条件后,无论Pipeline或阶段的状态如何,都运行此后置条件中的步骤,与pipeline和stage运行结果无关。。
特殊说明:cleanup和always的区别在于,cleanup会在其他任意一个post执行之后执行。
参考案例
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
post {
always {
echo 'I will always say Hello again!'
}
failure {
echo 'I will say failure when build is in failure state!'
}
success {
echo 'I will say success when build is in success state!'
}
}
}
4、Declarative Pipeline(声明式)指令
指令是帮助pipeline更容易的执行命令,可以理解为一个封装好的公共函数和方法,提供给pipeline使用
1、environment 环境变量
声明一个全局变量或者步骤内部的局部变量
需要 | 不是必须出现的指令,environment定义了一组全局的环境变量键值对 |
参数 | 无 |
说明 | 存在于pipeline{}或者stage指令内, |
environment指令指定了一组键值对,这些键值对将根据environment指令在Pipeline中的位置,定义为所有步骤或特定阶段的步骤的环境变量。
该指令支持一个特殊的辅助方法credentials(),它可以用于通过Jenkins环境中的标识符访问预定义的凭据。
credentials()支持的凭据类型:
Secret Text
指定的环境变量将设置为Secret Text的内容。
Secret File
指定的环境变量将设置为临时创建的File文件的位置。
Username and password
指定的环境变量将设置为username:password,并自动定义两个附加的环境变量:MYVARNAME_USR和MYVARNAME_PSW。
SSH with Private Key
指定的环境变量将设置为临时创建的SSH密钥文件的位置,并自动定义两个附加的环境变量:MYVARNAME_USR和MYVARNAME_PSW(包含密码)。
参考案例
pipeline {
agent any
environment {
CC = 'clang'
}
stages {
stage('Example Username/Password') {
environment {
SERVICE_CREDS = credentials('my-predefined-username-password')
}
steps {
sh 'echo "Service user is $SERVICE_CREDS_USR"'
sh 'echo "Service password is $SERVICE_CREDS_PSW"'
sh 'curl -u $SERVICE_CREDS https://myservice.example.com'
}
}
stage('Example SSH Username with private key') {
environment {
SSH_CREDS = credentials('my-predefined-ssh-creds')
}
steps {
sh 'echo "SSH private key is located at $SSH_CREDS"'
sh 'echo "SSH user is $SSH_CREDS_USR"'
sh 'echo "SSH passphrase is $SSH_CREDS_PSW"'
}
}
}
}
2、options 配置选项
options指令允许从Pipeline内部配置特定于Pipeline的选项。Pipeline提供了一系列选项,例如buildDiscarder,也可以由插件提供,例如timestamps。
必填 | 不 |
参数 | 没有 |
允许 | 在块内,或(有一定的限制)在指令内。pipelinestage |
可用的选项 options
buildDiscarder
保留最近运行的特定数量的Pipeline的构件和控制台输出。例如:options { buildDiscarder(logRotator(numToKeepStr: '1')) }
checkoutToSubdirectory
在工作区的一个子目录中执行自动源代码控制检出。例如:options { checkoutToSubdirectory('foo') }
disableConcurrentBuilds
禁止并发执行Pipeline。可以防止同时访问共享资源等。例如:options { disableConcurrentBuilds() } 将构建排队,当Pipeline中已经有一个正在执行的构建时,或 options { disableConcurrentBuilds(abortPrevious: true) } 以中止正在运行的构建并开始新的构建
disableResume
如果控制器重新启动,则不允许管道恢复。例如:options { disableResume() }
newContainerPerStage
与docker或dockerfile顶级代理一起使用。指定时,每个阶段将在同一节点上的新容器实例中运行,而不是所有阶段在同一容器实例中运行。
overrideIndexTriggers
允许覆盖分支索引触发器的默认处理。如果在多分支或组织标签处禁用分支索引触发器,options { overrideIndexTriggers(true) } 将仅为此作业启用它们。否则,options { overrideIndexTriggers(false) } 将仅为此作业禁用分支索引触发器。
preserveStashes
保留已完成构建的存储库,以用于阶段重新启动。例如:options { preserveStashes() } 以保留最近完成的构建的存储库,或 options { preserveStashes(buildCount: 5) } 以保留最近完成的五个构建的存储库。
quietPeriod
设置Pipeline的静默时间(以秒为单位),覆盖全局默认值。例如:options { quietPeriod(30) }
retry
在失败时,重试整个Pipeline指定的次数。例如:options { retry(3) }
skipDefaultCheckout
在agent指令中默认跳过从源代码控制中检出代码。例如:options { skipDefaultCheckout() }
skipStagesAfterUnstable
一旦构建状态变为UNSTABLE,则跳过阶段。例如:options { skipStagesAfterUnstable() }
timeout
设置Pipeline运行的超时时间,在此之后Jenkins应中止Pipeline。例如:options { timeout(time: 1, unit: 'HOURS') }
timestamps
在Pipeline运行生成的所有控制台输出前面加上该行发出的时间。例如:options { timestamps() }
parallelsAlwaysFailFast
为管道中的所有后续并行阶段设置failfast为true。例如:options { parallelsAlwaysFailFast() }
disableRestartFromStage
完全禁用经典Jenkins UI和Blue Ocean中可见的“从阶段重新启动”选项。例如:options { disableRestartFromStage() }。此选项不能在阶段内部使用。
参考案例
pipeline {
agent any
options {
timeout(time: 1, unit: 'HOURS')
}
stages {
stage('Example1') {
options {
timeout(time: 1, unit: 'HOURS')
}
steps {
echo 'Hello World'
}
}
stage('Example2') {
steps {
echo 'Hello World'
}
}
}
}
3、parameters 参数
parameters :定义pipeline 的专有参数列表
不是必须出现的指令
作用域:被最外层pipeline所包裹,并且只能出现一次,参数可被全局使用
好处:使用parameters好处是能够使参数也变成code,达到pipeline as code,pipeline中设置的参数会自动在job构建的时候生成,形成参数化构建
parameters指令提供了在触发Pipeline时用户应提供的参数列表。这些用户指定的参数的值可以通过params对象在Pipeline步骤中使用。
每个参数都有一个名称和值,具体取决于参数类型。当构建开始时,这些信息会作为环境变量导出,允许构建配置的后续部分访问这些值。例如,在像bash和ksh这样的POSIX shell中使用${PARAMETER_NAME}语法,在PowerShell中使用${Env:PARAMETER_NAME}语法,在Windows的cmd.exe中使用%PARAMETER_NAME%语法。
可用的参数 Parameters
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: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
text(name: 'BIOGRAPHY', defaultValue: '', description: 'Enter some information about the person')
booleanParam(name: 'TOGGLE', defaultValue: true, description: 'Toggle this value')
choice(name: 'CHOICE', choices: ['One', 'Two', 'Three'], description: 'Pick something')
password(name: 'PASSWORD', defaultValue: 'SECRET', description: 'Enter a password')
}
stages {
stage('Example') {
steps {
echo "Hello ${params.PERSON}"
echo "Biography: ${params.BIOGRAPHY}"
echo "Toggle: ${params.TOGGLE}"
echo "Choice: ${params.CHOICE}"
echo "Password: ${params.PASSWORD}"
}
}
}
}
4、triggers 触发器是自动化运行pipeline的方法
triggers
指令定义了Pipeline应该重新触发的自动化方式。目前可用的触发器有cron、pollSCM和upstream。
cron
作用:以指定的时间来运行pipeline
用法:triggers { cron('*/1 * * * *') }
pollSCM
作用:以固定的时间检查代码仓库更新(或者当代码仓库有更新时)自动触发pipeline构建,。如果存在新的更改,Pipeline将重新触发
用法:triggers { pollSCM('H */4 * * 1-5') }或者triggers { pollSCM() }(后者需要配置post-commit/post-receive钩子)
upstream
作用:接受一个逗号分隔的作业字符串和一个阈值。当字符串中的任何作业以最小阈值完成时,Pipeline将重新触发。
用法::triggers { upstream(upstreamProjects: 'job1,job2', threshold: hudson.model.Result.SUCCESS) }
参考案例
pipeline{
agent any
//说明:当test_8或者test_7运行成功的时候,自动触发
triggers { upstream(upstreamProjects: 'test_8,test_7', threshold: hudson.model.Result.SUCCESS) }
stages{
stage("stage1"){
steps{
echo "hello"
}
}
}
}
Jenkins cron 语法
Jenkins的cron语法遵循cron实用程序的语法(有一些小的差异)。具体而言,每行由5个由TAB或空格分隔的字段组成:
分钟,MINUTE,0-59
小时,HOUR,0-23
月份中的日期,DOM,-31
月份,MONTH,1-12
星期几,DOW,0-7(0和7表示星期日)
为了在一个字段中指定多个值,可以使用以下运算符。按优先顺序排列:
* 表示所有有效值
M-N 表示一个值范围
M-N/X 或 */X 表示以X为间隔在指定范围或整个有效范围内进行步进
A,B,…,Z 枚举多个值
为了使定时任务在系统上产生均匀的负载,应尽可能使用符号H(代表“哈希”)。例如,对于十几个每天执行的作业,使用0 0 * * * 将在午夜产生大量的负载峰值。相比之下,使用H H * * * 仍然每天执行每个作业一次,但不会同时执行,更好地利用有限的资源。
H符号可以与范围一起使用。例如,H H(0-7) * * * 表示在凌晨12:00到上午7:59之间的某个时间。您还可以在H中使用步进间隔,可以有范围也可以没有范围。
H符号可以被视为范围内的随机值,但实际上它是作业名称的哈希值,而不是随机函数,因此对于任何给定的项目,该值保持稳定。
请注意,在月份的日期字段中,短周期(例如*/3或H/3)在大多数月份的末尾可能无法保持一致,这是由于月份长度的变化。例如,*/3将在长月份的1日、4日、……31日运行,然后在下个月的下一天再次运行。哈希值始终选择在1-28范围内,因此H/3将在月底产生3到6天之间的运行间隔。较长的周期也会有不一致的长度,但影响可能相对较不明显。
空行和以#开头的行将被忽略为注释。
此外,还支持@yearly、@annually、@monthly、@weekly、@daily、@midnight和@hourly作为别名。这些别名使用哈希系统进行自动平衡。例如,@hourly与H * * * *相同,表示在整点的任何时间可能执行。@midnight实际上表示在凌晨12:00 AM和2:59 AM之间的某个时间。
参考案例
每隔十五分钟执行一次(可能在:07、:22、:37、:52)
triggers{ cron('H/15 * * * *') }
每隔十分钟在每小时的前半部分执行一次(三次,可能在:04、:14、:24)
triggers{ cron('H(0-29)/10 * * * *') }
每隔两个小时的45分钟执行一次,从上午9:45开始,每个工作日结束于下午3:45。
triggers{ cron('45 9-16/2 * * 1-5') }
在工作日的上午9点到下午5点之间的每两个小时时间段内执行一次(可能在上午10:38、下午12:38、下午2:38、下午4:38)
triggers{ cron('H H(9-16)/2 * * 1-5') }
每个月的1日和15日执行一次,除了12月
triggers{ cron('H H 1,15 1-11 *') }
5、stage(阶段)
stage指令位于stages部分,并应包含一个steps部分、一个可选的agent部分或其他特定于阶段的指令。实际上,Pipeline执行的所有实际工作都将包含在一个或多个stage指令中。
6、tools(工具)
tools指令定义了自动安装并放置在PATH上的工具。如果指定了agent none,则会忽略这个部分。引用的工具需要在管理页面的全局工具配置里配置过
支持的tools
maven
jdk
gradle
工具名称必须在Jenkins的“管理Jenkins”→“工具”下进行预配置
参考案例
pipeline {
agent any
tools {
maven 'apache-maven-3.0.1'
}
stages {
stage('Example') {
steps {
sh 'mvn --version'
}
}
}
}
7、input (输入)
在一个stage上使用input指令可以提示输入。在应用任何选项之后,在进入该阶段的agent块或评估该阶段的when条件之前,该阶段将暂停。等待用户输入,根据用户输入进行下一步动作。作为输入提交的任何参数将在整个阶段的环境中可用。
构建过程中由用户输入相关数据,以进行下一步操作(不常用)
配置选项
message 消息
必填。当用户提交 .input
id
此输入的可选标识符。默认值基于阶段名称
ok
输入表单上“确定”按钮的可选文本。
submitter (提交人)
允许提交此输入的用户或外部组名的可选逗号分隔列表。默认为允许任何用户。
submitterParameter(提交人参数)
要使用提交者名称设置的环境变量的可选名称(如果存在)
parameters (范围)
提示提交者提供的可选参数列表。
8、when
when指令允许Pipeline根据给定的条件确定是否应执行该阶段。when指令必须包含至少一个条件。如果when指令包含多个条件,所有子条件必须返回true才能执行该阶段。这与将子条件嵌套在allOf条件中的效果相同(参考下面的示例)。如果使用anyOf条件,请注意,一旦找到第一个“true”条件,条件将跳过剩余的测试。
可以使用嵌套条件构建更复杂的条件结构:not、allOf或anyOf。嵌套条件可以嵌套到任意深度。
内置when条件
branch 判断分支名称是否符合预期
当正在构建的分支与给定的分支模式(ANT样式路径通配符)匹配时执行该阶段,例如:when { branch 'master' }。请注意,这仅适用于多分支流水线。
可以在属性之后添加可选参数,以指定如何计算匹配项的任何模式
EQUALS 用于简单的字符串比较
GLOB(默认值) 用于ANT样式路径通配符(与例如changeset相同)
REGEXP 用于正则表达式匹配
例如:when { branch pattern: "release-\\d+", comparator: "REGEXP"}
buildingTag
当构建正在生成一个标签时执行该阶段。例如:when { buildingTag() }
changelog (更改日志)
如果构建的SCM更改日志包含给定的正则表达式模式,则执行该阶段,例如:when { changelog '.*^\\[DEPENDENCY\\] .+$' }
changeset (变更集)
如果构建的SCM更改集包含一个或多个与给定模式匹配的文件,则执行该阶段。示例:when { changeset "**/*.js" }
可以在属性之后添加可选参数,以指定如何计算匹配项的任何模式:comparator
EQUALS用于简单的字符串比较
GLOB(默认值)用于ANT样式路径通配符(不区分大小写,可以使用caseSensitive参数关闭)。
REGEXP用于正则表达式匹配
例如:when { changeset pattern: ".TEST\\.java", comparator: "REGEXP" } 或 when { changeset pattern: "*/*TEST.java", caseSensitive: true }
changeRequest(变更请求)
如果当前构建是针对“更改请求”(也称为 GitHub 和 Bitbucket 上的拉取请求、GitLab 上的合并请求、Gerrit 中的更改等),则执行该阶段。 如果未传递任何参数,则阶段将对每个更改请求运行,例如:。when { changeRequest() }
通过向更改请求添加带有参数的筛选器属性,可以使该阶段仅在匹配的变更请求上运行。可能的属性有id、target、branch、fork、url、title、author、authorDisplayName和authorEmail。每个属性对应一个CHANGE_*环境变量,例如:when { changeRequest target: 'master' }。
environment
当指定的环境变量设置为给定值时执行该阶段,例如:when { environment name: 'DEPLOY_TO', value: 'production' }
equals
当期望值等于实际值时执行该阶段,例如:when { equals expected: 2, actual: currentBuild.number }
expression
当指定的Groovy表达式求值为true时执行该阶段,例如:when { expression { return params.DEBUG_BUILD } }
tag
如果TAG_NAME变量与给定的模式匹配,则执行该阶段。例如:when { tag "release-*" } 如果提供了空模式,则该阶段将在TAG_NAME变量存在时执行(与buildingTag()相同)。
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' } }
triggeredBy
当给定的参数触发当前构建时,执行该阶段。例如:
when { triggeredBy 'SCMTrigger' }
when { triggeredBy 'TimerTrigger' }
when { triggeredBy 'BuildUpstreamCause' }
when { triggeredBy cause: "UserIdCause", detail: "vlinde" }
多个条件
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'
}
}
}
}
嵌套条件
pipeline {
agent any
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
when {
expression { BRANCH_NAME ==~ /(production|staging)/ }
branch 'production'
anyOf {
environment name: 'DEPLOY_TO', value: 'production'
environment name: 'DEPLOY_TO', value: 'staging'
}
}
steps {
echo 'Deploying'
}
}
}
}
5、Parallel(并行)
声明式Pipeline里面可以包含Parallel并行部分,Parallel可以包含多个并行的stage。
此外,您可以通过将failFast true添加到包含并行项的阶段中,强制所有并行阶段在其中任何一个失败时都被中止。
添加failfast的另一种方法是向pipeline定义中添加一个选项:parallelsAlwaysFailFast()。
四、script(脚本)Pipeline 语法介绍
脚本化管道与声明性管道一样,构建在底层管道子系统之上。与声明式不同,脚本化管道实际上是一种通用的 DSL用Groovy构建。 Groovy 语言提供的大多数功能都可供脚本化管道的用户使用,这意味着它可以是一个非常富有表现力和灵活性的工具,人们可以使用它来编写持续交付管道。
最外层有node{}包裹
可直接使用groovy语句
参考案例
node{ //最外层用node包裹
stage("build"){
// build env
}
stage("test"){
// todo test
}
stage("depoly"){
// deploy project
}
}
在声明式中使用脚本
在声明式的pipeline中默认无法使用脚本语法,但是pipeline提供了一个脚本环境入口:script{},通过使用script来包裹脚本语句,即可使用脚本语法
参考案例
条件判断:
pipeline {
agent any
stages {
stage('stage 1') {
steps {
script{
if ( "1" =="1" ) {
echo "lalala"
}else {
echo "oooo"
}
}
}
}
}
}
异常处理
pipeline {
agent any
stages {
stage('stage 1') {
steps {
script{
try {
sh 'exit 1'
}
catch (exc) {
echo 'Something failed'
}
}
}
}
}
}
五、Flow Control(流程控制)
Scripted Pipeline从Jenkinsfile的顶部向下顺序执行,就像Groovy或其他语言中的大多数传统脚本一样。因此,提供流程控制依赖于Groovy表达式,例如if/else条件语句,例如:
node {
stage('Example') {
if (env.BRANCH_NAME == 'master') {
echo 'I only execute on the master branch'
} else {
echo 'I execute elsewhere'
}
}
}
Scripted Pipeline的另一种流程控制方式是使用Groovy的异常处理支持。当步骤由于任何原因失败时,它们会抛出异常。在错误处理中,必须使用Groovy中的try/catch/finally块,例如:
node {
stage('Example') {
try {
sh 'exit 1'
}
catch (exc) {
echo 'Something failed, I should sound the klaxons!'
throw
}
}
}