Pipeline 语法

1.Sections

agent

agent 部分指定整个 Pipeline 或特定阶段在 Jenkins 环境中执行的位置,具体取决于该 agent 部分的放置位置。该部分必须在 pipeline 块内的顶层定义 ,但阶段级使用是可选的。

需要
参数 如下面所描述的
允许 在顶级pipeline块和每个stage块中。
参数

为了支持 Pipeline 作者可能拥有的各种用例,该 agent 部分支持几种不同类型的参数。这些参数可以应用于pipeline 块的顶层,也可以应用在每个 stage指令内。

  • any

在任何可用的 agent上执行 Pipeline 或 stage。例如:agent any

  • none

当在 pipeline 块的顶层应用时,将不会为整个 Pipeline 运行分配全局 agent,并且每个 stage 部分将需要包含其自己的 agent 部分。例如:agent none

  • label

使用提供的 label 在 Jenkins 环境中可用的代理上执行 Pipeline 或 stage。例如:agent { label 'my-defined-label' }

  • node
agent { node { label 'labelName' } }
// 等同于
agent { label 'labelName' }

node 允许其他选项(如customWorkspace)。

  • docker

定义此参数时,执行 Pipeline 或 stage 时会动态供应一个 docker 节点去接受 Docker-based 的 Pipelines。 docker 还可以接受一个 args,直接传递给 docker run 调用。例如:agent { docker 'maven:3-alpine' }

agent {
    docker {
        image 'maven:3-alpine'
        label 'my-defined-label'
        args  '-v /tmp:/tmp'
    }
}
  • dockerfile

使用从 Dockerfile 源存储库中包含的容器来构建执行 Pipeline 或 stage 。为了使用此选项,Jenkinsfile 必须从Multibranch Pipeline或 “Pipeline from SCM" 加载。
默认是在 Dockerfile 源库的根目录:agent { dockerfile true }。如果 Dockerfile 需在另一个目录中建立,请使用以下dir选项:agent { dockerfile { dir 'someSubDir' } }。您可以通过docker build ...使用 additionalBuildArgs 选项,如 agent { dockerfile { additionalBuildArgs '--build-arg foo=bar' } }。

常用选项

这些是可以应用两个或多个 agent 实现的几个选项。除非明确说明,否则不需要。

  • label

    一个字符串。标记在哪里运行 pipeline 或 stage。此选项适用于 node、docker 和 dockerfile,并且 node 是必需的。

  • customWorkspace

    一个字符串。自定义运行的工作空间内。它可以是相对路径,在这种情况下,自定义工作区将位于节点上的工作空间根目录下,也可以是绝对路径。例如:

agent {
    node {
        label 'my-defined-label'
        customWorkspace '/some/other/path'
    }
}
  • reuseNode

    一个布尔值,默认为 false。如果为 true,则在同一工作空间中。此选项适用于 docker 和 dockerfile,并且仅在 individual stage 中使用 agent 才有效。例如:

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent { docker 'maven:3-alpine' } 
    stages {
        stage('Example Build') {
            steps {
                sh 'mvn -B clean verify'
            }
        }
    }
}

Stage-level agent 部分

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

定义 Pipeline 或 stage 运行结束时的操作。post-condition 块支持 post 部件:always,changed,failure,success,unstable,和 aborted。这些块允许在 Pipeline 或 stage 运行结束时执行步骤,具体取决于 Pipeline 的状态。

需要 No
参数 None
允许 在顶级pipeline块和每个stage块中。
conditions 项
  • always

    运行,无论 Pipeline 运行的完成状态如何。

  • changed

    只有当前 Pipeline 运行的状态与先前完成的 Pipeline 的状态不同时,才能运行。

  • failure

    仅当当前 Pipeline 处于“失败”状态时才运行,通常在 Web UI 中用红色指示表示。

  • success

    仅当当前 Pipeline 具有“成功”状态时才运行,通常在具有蓝色或绿色指示的 Web UI 中表示。

  • unstable

    只有当前 Pipeline 具有“不稳定”状态,通常由测试失败,代码违例等引起,才能运行。通常在具有黄色指示的Web UI 中表示。

  • aborted

    只有当前 Pipeline 处于“中止”状态时,才会运行,通常是由于 Pipeline 被手动中止。通常在具有灰色指示的Web UI 中表示。

例如:

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Example') {
            steps {
                echo 'Hello World'
            }
        }
    }
    post { 
        always { 
            echo 'I will always say Hello again!'
        }
    }
}

通常,该post部分应放在Pipeline末端。

stages

包含一个或多个 stage 的序列,Pipeline 的大部分工作在此执行。建议 stages 至少包含至少一个 stage 指令,用于连接各个交付过程,如构建,测试和部署等。

需要
参数 没有
允许 只有一次,在pipeline块内。

例如:

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Example') {
            steps { 
                echo 'Hello World'
            }
        }
    }
}

steps

steps 包含一个或多个在 stage 块中执行的 step 序列。

需要
参数 没有
允许 在每个stage块内。

例如:

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Example') {
            steps { 
                echo 'Hello World'
            }
        }
    }
}

steps 部分必须包含一个或多个步骤。

2.Directives

environment

environment 指令指定一系列键值对,这些键值对将被定义为所有 step 或 stage-specific step 的环境变量,具体取决于 environment 指令在 Pipeline 中的位置。

该指令支持一种特殊的方法 credentials(),可以通过其在 Jenkins 环境中的标识符来访问预定义的凭据。对于类型为 “Secret Text” 的凭据,该 credentials() 方法将确保指定的环境变量包含 Secret Text 内容;对于“标准用户名和密码”类型的凭证,指定的环境变量将被设置为 username:password。

需要 没有
参数 没有
允许 pipeline块内或stage指令内。

例如

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    environment { 
        CC = 'clang'
    }
    stages {
        stage('Example') {
            environment { 
                AN_ACCESS_KEY = credentials('my-prefined-secret-text') 
            }
            steps {
                sh 'printenv'
            }
        }
    }
}

options

options 指令允许在 Pipeline 本身内配置 Pipeline 专用选项。Pipeline 本身提供了许多选项,例如buildDiscarder,但它们也可能由插件提供,例如 timestamps。

需要 No
参数 None
允许 只有一次,在pipeline块内。

可用选项:

  • buildDiscarder

    pipeline 保持构建的最大个数。例如:

    options { buildDiscarder(logRotator(numToKeepStr: '1')) }
    
  • disableConcurrentBuilds

    不允许并行执行 Pipeline,可用于防止同时访问共享资源等。例如:

    options { disableConcurrentBuilds() }
    
  • skipDefaultCheckout

    agent指令中默认跳过来自源代码控制的代码。例如:options { skipDefaultCheckout() }

  • skipStagesAfterUnstable

    一默认跳过来自源代码控制的代码。例如:

    options { skipDefaultCheckout() }
    
  • timeout

    设置Pipeline运行的超时时间。例如:

    options { timeout(time: 1, unit: 'HOURS') }
    
  • retry

    失败后,重试整个 Pipeline 的次数。例如:

    options { retry(3) }
    
  • timestamps

    预定义由Pipeline生成的所有控制台输出时间。例如:

    options { timestamps() }
    

例如

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    options {
        timeout(time: 1, unit: 'HOURS') 
    }
    stages {
        stage('Example') {
            steps {
                echo 'Hello World'
            }
        }
    }
}

指定一个小时的全局执行超时,之后 Jenkins 将中止 Pipeline 运行。

parameters

parameters 指令提供用户在触发 Pipeline 时的参数列表。这些参数值通过该 params 对象可用于 Pipeline 步骤,具体用法如下

需要 No
参数 None
允许 只有一次,在pipeline块内。

可用参数

  • String

    字符串类型的参数,例如:

    parameters { string(name: 'DEPLOY_ENV', defaultValue: 'staging', description: '') }
    
  • booleanParam

    一个布尔参数,例如:

    parameters { booleanParam(name: 'DEBUG_BUILD', defaultValue: true, description: '') }
    

例如

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    parameters {
        string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
    }
    stages {
        stage('Example') {
            steps {
                echo "Hello ${params.PERSON}"
            }
        }
    }
}

triggers

triggers 指令定义了 Pipeline 自动化触发的方式。对于与源代码集成的 Pipeline,如 GitHub 或 BitBucket,trigger s可能不需要基于 webhook 的集成也已经存在。目前只有两个可用的触发器:cron 和 pollSCM。

需要 No
参数 None
允许 只有一次,在pipeline块内。
  • cron

    接受一个cron风格的字符串来定义Pipeline触发的常规间隔,例如:

    triggers { cron('H 4/* 0 0 1-5') }
    
  • pollSCM

    接受一个cron风格的字符串来定义Jenkins检查SCM源更改的常规间隔。如果存在新的更改,则Pipeline将被重新触发。例如:

    triggers { pollSCM('H 4/* 0 0 1-5') }
    

例如

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    triggers {
        cron('H 4/* 0 0 1-5')
    }
    stages {
        stage('Example') {
            steps {
                echo 'Hello World'
            }
        }
    }
}

stage

stage 指令在 stages 部分中,应包含 stop 部分,可选 agent 部分或其他特定于 stage 的指令。实际上,Pipeline完成的所有实际工作都将包含在一个或多个 stage 指令中。

需要 至少一个
参数 一个强制参数,一个用于 stage 命名的字符串。
允许 stages部分内。

例如

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Example') {
            steps {
                echo 'Hello World'
            }
        }
    }
}

tools

通过 tools 可自动安装工具,并放置环境变量到 PATH。如果 agent none,这将被忽略。

需要 No
参数 None
允许 pipeline块或stage块内。
支持的工具
  • maven
  • jdk
  • gradle

例如:

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    tools {
        maven 'apache-maven-3.0.1' 
    }
    stages {
        stage('Example') {
            steps {
                sh 'mvn --version'
            }
        }
    }
}

工具名称必须在 Jenkins 管理 Jenkins全局工具配置中配置

when

when 指令允许 Pipeline 根据给定的条件确定是否执行该阶段。该 when 指令必须至少包含一个条件。如果 when指令包含多个条件,则所有子条件必须为 stage 执行返回 true。这与子条件嵌套在一个 allOf 条件中相同(见下面的例子)。

需要 No
参数 None
允许 stage指令内
内置条件
  • branch

    当正在构建的分支与给出的分支模式匹配时执行,例如:when { branch 'master' }。请注意,这仅适用于多分支 Pipeline。

  • environment

    当指定的环境变量设置为给定值时执行,例如: when { environment name: 'DEPLOY_TO', value: 'production' }

  • expression

    当指定的 Groovy 表达式求值为 true 时执行,例如: when { expression { return params.DEBUG_BUILD } }

  • not

    当嵌套条件为false时执行。必须包含一个条件。例如:when { not { branch 'master' } }

  • allOf

    当所有嵌套条件都为真时执行。必须至少包含一个条件。例如:when { allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } }

  • anyOf

    当至少一个嵌套条件为真时执行。必须至少包含一个条件。例如:when { anyOf { branch 'master'; branch 'staging' } }

例如

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Example Build') {
            steps {
                echo 'Hello World'
            }
        }
        stage('Example Deploy') {
            when {
                branch 'production'
            }
            steps {
                echo 'Deploying'
            }
        }
    }
}
Jenkinsfile (Declarative Pipeline)
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'
            }
        }
    }
}
Jenkinsfile (Declarative Pipeline)
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'
            }
        }
    }
}
Jenkinsfile (Declarative Pipeline)
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'
            }
        }
    }
}
Jenkinsfile (Declarative Pipeline)
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'
            }
        }
    }
}

3.Steps

Declarative Pipeline 可以使用 Pipeline Steps reference 中的所有可用步骤 ,并附加以下仅在 Declarative Pipeline 中支持的步骤。

script

script步骤需要一个script Pipeline,并在Declarative Pipeline中执行。对于大多数用例,script在Declarative Pipeline中的步骤不是必须的,但它可以提供一个有用的加强。

例如

Jenkinsfile (Declarative Pipeline)
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"
                    }
                }
            }
        }
    }
}

4.Scripted Pipeline

Groovy 脚本不一定适合所有使用者,因此 jenkins 创建了 Declarative pipeline,为编写 Jenkins 管道提供了一种更简单、更有主见的语法。但是不可否认,由于脚本化的 pipeline 是基于 groovy 的一种 DSL 语言,所以与Declarative pipeline 相比为 jenkins 用户提供了更巨大的灵活性和可扩展性。

Flow Control

pipeline 脚本同其它脚本语言一样,从上至下顺序执行,它的流程控制取决于 Groovy 表达式,如 if/else 条件语句,举例如下:

Jenkinsfile (Scripted Pipeline)
node {
    stage('Example') {
        if (env.BRANCH_NAME == 'master') {
            echo 'I only execute on the master branch'
        } else {
            echo 'I execute elsewhere'
        }
    }
}

pipelin e脚本流程控制的另一种方式是 Groovy 的异常处理机制。当任何一个步骤因各种原因而出现异常时,都必须在 Groovy 中使用 try/catch/finally语句块进行处理,举例如下:

Jenkinsfile (Scripted Pipeline)
node {
    stage('Example') {
        try {
            sh 'exit 1'
        }
        catch (exc) {
            echo 'Something failed, I should sound the klaxons!'
            throw
        }
    }
}

Steps

正如文档开始所言,pipeline 最核心和基本的部分就是 “step”,从根本上来说,steps 作为 Declarative pipeline和 Scripted pipeline 语法的最基本的语句构建块来告诉 jenkins 应该执行什么操作。
Scripted pipeline 没有专门将 steps 作为它的语法的一部分来介绍,但是在 Pipeline Steps reference 这篇文档中对 pipeline 及其插件涉及的 steps 做了很详细的介绍。如有需要可参考 jenkins 官网对该部分的介绍 Pipeline Steps reference。

Differences from plain Groovy

由于 pipeline 的一些个性化需求,比如在重新启动 jenkins 后要求 pipeline 脚本仍然可以运行,那么 pipeline 脚本必须将相关数据做序列化,然而这一点 Groovy并不能完美的支持,例如

collection.each { item -> /* perform operation */ }

语法比较

共同点:

  • 两者都是 pipeline 代码的持久实现,都能够使用 pipeline 内置的插件或者插件提供的 steps,两者都可以利用共享库扩展。

区别:

  • 两者不同之处在于语法和灵活性。Declarative pipeline 对用户来说,语法更严格,有固定的组织结构,更容易生成代码段,使其成为用户更理想的选择。但是 Scripted pipeline 更加灵活,因为 Groovy 本身只能对结构和语法进行限制,对于更复杂的 pipeline 来说,用户可以根据自己的业务进行灵活的实现和扩展。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350

推荐阅读更多精彩内容