Groovy 字符串插值不应该与凭据一起使用。
Groovy 字符串插值可以通过特殊字符将恶意命令注入命令解释器。所以要使用单引号('),避免 Groovy 插值。

官网地址:Pipeline Syntax

Sections

pipeline

声明式流水线是 Jenkins 流水线1的一个相对较新的补充,它在流水线子系统之上提供了一种更加简化和固执己见的语法。

声明式管道必须包含在 pipeline {} 模块里面

pipeline {
    /* insert Declarative Pipeline here */
}

agent

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

顶级和阶段级代理之间的差异

在将代理添加到顶层或阶段级时存在一些细微差别,这是在应用 options 指令时出现的。

顶级代理

在管道最外层声明的 agents 中,在进入代理后调用选项。例如:当使用 timeout 时,它将仅应用于代理内的执行。

node("myAgent") {
    timeout(unit: 'SECONDS', time: 5) {
        stage("One"){
            sleep 10
            echo 'hello'
        }
    }
}
阶段级代理

agents 内声明的代理中,在进入代理和检查任何 when 条件之前调用选项。在这种情况下,当使用 timeout 时,它在分配代理之前应用。

timeout(unit: 'SECONDS', time: 5) {
    stage("One"){
        node {
            sleep 10
            echo 'Hello'
        }
    }
}

此超时将包括代理设置时间。由于超时包括代理供应时间,因此在代理分配延迟的情况下,管道可能会失败。

Parameters

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

any

在任何可用代理上执行管道或阶段。例如:agent any

none

当在 pipeline 块的顶部没有全局代理,该参数将会被分配到整个流水线的运行中并且每个 stage 部分都需要包含他自己的 agent 部分。比如: agent none

label

在提供了标签的 Jenkins 环境中可用的代理上执行流水线或阶段。 例如: agent { label 'my-defined-label' }

也可以使用标签条件。例如:agent { label 'my-label1 && my-label2' }agent { label 'my-label1 || my-label2' }

node

agent { node { label 'labelName' } } 行为与 agent { label 'labelName' } 相同,但 node 允许附加选项(例如:customWorkspace)。

docker

使用给定的容器执行管道或阶段,该容器将在预先配置为接受基于 Docker 的管道的节点上或在与可选定义的参数匹配的节点上动态配置。还可以选择接受一个参数,该参数可能包含直接传递给调用的参数,以及一个选项,即使图像名称已经存在,也会强制执行。例如:labeldockerargsdocker runalwaysPulldocker pullagent { docker 'maven:3.8.1-adoptopenjdk-11' }

agent {
    docker {
        image 'maven:3.8.1-adoptopenjdk-11'
        label 'my-defined-label'
        args  '-v /tmp:/tmp'
    }
}

docker 还可以选择接受 registryUrlregistryCredentialsId 参数,这将有助于指定要使用的 Docker Registry 及其凭据。该参数 registryCredentialsId 可以单独用于 docker hub 内的私有存储库。例如:

agent {
    docker {
        image 'myregistry.com/node'
        label 'my-defined-label'
        registryUrl 'https://myregistry.com/'
        registryCredentialsId 'myPredefinedCredentialsInJenkins'
    }
}

dockerfile

Dockerfile 使用从源存储库中包含的容器构建的容器执行管道或阶段。为了使用此选项,Jenkinsfile 必须从 Multibranch Pipeline 或来自 SCM 的 Pipeline 加载。通常这是 Dockerfile 在源存储库的根目录中:agent { dockerfile true }。如果 Dockerfile 在另一个目录中构建 a,请使用 dir 选项:agent { dockerfile { dir 'someSubDir' } }。如果您 Dockerfile 有其他名称,则可以使用 filename 选项指定文件名。您可以使用选项将其他参数传递给 docker build …​ 命令 additionalBuildArgs,例如: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'
        args '-v /tmp:/tmp'
    }
}

dockerfile 还可以选择接受 registryUrlregistryCredentialsId 参数,这将有助于指定要使用的 Docker Registry 及其凭据。例如:

agent {
    dockerfile {
        filename 'Dockerfile.build'
        dir 'build'
        label 'my-defined-label'
        registryUrl 'https://myregistry.com/'
        registryCredentialsId 'myPredefinedCredentialsInJenkins'
    }
}

kubernetes

在 Kubernetes 集群上部署的 pod 内执行管道或阶段。为了使用此选项,Jenkinsfile 必须从 Multibranch Pipeline 或来自 SCM 的 Pipeline 加载。Pod 模板在 kubernetes {} 块内定义。例如:如果您想要一个里面有 Kaniko 容器的 pod,您可以这样定义它:

agent {
    kubernetes {
        defaultContainer 'kaniko'
        yaml '''
kind: Pod
spec:
  containers:
  - name: kaniko
    image: gcr.io/kaniko-project/executor:debug
    imagePullPolicy: Always
    command:
    - sleep
    args:
    - 99d
    volumeMounts:
      - name: aws-secret
        mountPath: /root/.aws/
      - name: docker-registry-config
        mountPath: /kaniko/.docker
  volumes:
    - name: aws-secret
      secret:
        secretName: aws-secret
    - name: docker-registry-config
      configMap:
        name: docker-registry-config
'''
   }
}

您需要 aws-secret 为 Kaniko 创建一个秘密,以便能够使用 ECR 进行身份验证。这个秘密应该包含 ~/.aws/credentials。另一个卷是一个 ConfigMap,它应该包含您的 ECR 注册表的端点。例如:

{
      "credHelpers": {
        "<your-aws-account-id>.dkr.ecr.eu-central-1.amazonaws.com": "ecr-login"
      }
}

参考以下示例:https://github.com/jenkinsci/kubernetes-plugin/blob/master/examples/kaniko.groovy

Common Options

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

label

一个字符串。该标签用于运行 Pipeline 或个别的 stage。

此选项对 node、docker 和 dockerfile 有效,并且对于 node 是必需的。

customWorkspace

一个字符串。在自定义工作区运行应用了 agent 的流水线或个别的 stage,而不是默认的。它可以是相对路径,在这种情况下,自定义工作区将位于节点上的工作区根目录下,也可以是绝对路径。例如:

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

此选项对 node、docker 和 dockerfile 有效。

reuseNode

布尔值,默认为 false。如果为 true,则在同一工作区中的 Pipeline 顶层指定的节点上运行容器,而不是完全在新节点上运行。

此选项对 dockerdockerfile 有效,并且只有当使用在个别的 stageagent 上才会有效。

args

一个字符串。要传递给的运行时参数 docker run

此选项对 dockerdockerfile 有效。

示例 1:Docker 代理,声明式管道

pipeline {
    agent { docker 'maven:3.8.1-adoptopenjdk-11' }
    
    stages {
        stage('Example Build') {
            steps {
                sh 'mvn -B clean verify'
            }
        }
    }
}
  • 3.8.1-adoptopenjdk-11:在给定名称和标签 (maven:3.8.1-adoptopenjdk-11)的新创建容器中执行此管道中定义的所有步骤。

示例 2:阶段级代理部分

pipeline {
    agent none 
    
    stages {
        stage('Example Build') {
            agent { docker 'maven:3.8.1-adoptopenjdk-11' }
            
            steps {
                echo 'Hello, Maven'
                sh 'mvn --version'
            }
        }
        
        stage('Example Test') {
            agent { docker 'openjdk:8-jre' } 
            
            steps {
                echo 'Hello, JDK'
                sh 'java -version'
            }
        }
    }
}
  • agent none 在 Pipeline 的顶层进行定义可确保不会不必要地分配 Executor 。使用 agent none 还强制每个 stage 部分包含自己的 agent 部分。
  • 使用此镜像在新创建的容器中执行此阶段的步骤。
  • 使用与上一阶段不同的镜像在新创建的容器中执行此阶段中的步骤。

post

post 部分定义了在管道或阶段运行完成时运行的一个或多个附加步骤(取决于该 post 部分在管道中的位置)。post 可以支持以下任何后置条件块:alwayschangedfixedregressionabortedfailuresuccessunstableunsuccessfulcleanup。这些条件块允许根据管道或阶段的完成状态在每个条件内执行步骤。条件块按如下所示的顺序执行。

Conditions

always

无论 Pipeline 或阶段的完成状态如何,都允许在 post 部分运行该步骤。

changed

只有当前 Pipeline 或阶段的完成状态与它之前的运行不同时,才允许在 post 部分运行该步骤。

fixed

只有当前 Pipeline 或阶段的运行成功并且之前的运行失败或不稳定时才运行该步骤。

regression

只有当前 Pipeline 或阶段的运行处于失败、不稳定或中止且上一次运行成功时才运行该步骤。

aborted

只有当前 Pipeline 或阶段的运行处于 “中止” 状态时才运行该步骤,通常是由于流水线被手动中止。这通常在 Web UI 中用灰色表示。

failure

只有当前 Pipeline 或阶段的运行处于 “失败” 状态时才运行该步骤,通常在 Web UI 中用红色表示。

success

只有当前 Pipeline 或阶段的运行处于 “成功” 状态时才运行步骤,通常在 Web UI 中以蓝色或绿色表示。

unstable

只有当前 Pipeline 或阶段的运行处于 “不稳定” 状态时才运行步骤,这通常是由测试失败、代码违规等引起的。这通常在 Web UI 中用黄色表示。

unsuccessful

只有当前 Pipeline 或阶段的运行没有 “成功” 状态时才运行步骤。这通常在 Web UI 中表示,具体取决于前面提到的状态。

cleanup

在评估 post 所有其他条件后运行此条件中的步骤,无论管道或阶段的状态如何。

示例 3:Post 部分,声明性管道

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

按照惯例,该 post 部分应放置在管道的末端。后置条件块包含与步骤部分相同的步骤。

stages

该部分包含一系列一个或多个阶段指令,stages 是流水线描述的大部分 “工作” 所在的位置。建议至少为持续交付过程的每个离散部分(例如:构建、测试和部署)stages 包含一个阶段指令。

示例 4:阶段,声明式管道

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

stages 部分通常遵循诸如 agentoptions 等指令。

steps

steps 部分在给定的 stage 指令中执行的定义了一系列的一个或多个 steps

示例 5:单步声明式管道

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

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

Directives

environment

environment 指令指定了一系列键值对,这些键值对将被定义为所有步骤或特定阶段步骤的环境变量,具体取决于 environment 指令在管道中的位置。

该指令支持一种特殊的辅助方法 credentials(),可用于在 Jenkins 环境中通过其标识符访问预定义的凭据。

Supported Credentials Type

Secret Text

指定的环境变量将设置为 Secret Text 内容

Secret File

指定的环境变量将设置为临时创建的 File 文件的位置

Username and password

指定的环境变量将被设置为 username:password 并自动定义另外两个环境变量分别为:MYVARNAME_USRMYVARNAME_PSW

SSH with Private Key

指定的环境变量将设置为临时创建的 SSH 密钥文件的位置,并且可能会自动定义两个额外的环境变量:MYVARNAME_USRMYVARNAME_PSW(保存密码)。

不支持的凭据类型会导致管道失败并显示消息为:org.jenkinsci.plugins.credentialsbinding.impl.CredentialNotFoundException: No suitable binding handler could be found for type <unsupportedType>.

示例 6:秘密文本凭证,声明性管道

pipeline {
    agent any
    
    environment { 
        CC = 'clang'
    }
    
    stages {
        stage('Example') {
            environment { 
                AN_ACCESS_KEY = credentials('my-predefined-secret-text') 
            }
            
            steps {
                sh 'printenv'
            }
        }
    }
}
  • 顶层流水线块中使用的 environment 指令将适用于流水线中的所有步骤。
  • 在一个 stage 中定义的 environment 指令只会将给定的环境变量应用于 stage 中的步骤。
  • environment 块有一个助手方法 credentials() 定义,该方法可以在 Jenkins 环境中用于通过标识符访问预定义的凭证。

示例 7:用户名和密码凭证

pipeline {
    agent any
    
    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://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"'
            }
        }
    }
}

options

options 指令允许从流水线本身配置流水线特定的选项。Pipeline 提供了许多这些选项,例如:buildDiscarder,但它们也可能由插件提供,例如:timestamps

可用选项

buildDiscarder

为最近 Pipeline 运行特定数量保留工件和控制台输出。例如:options { buildDiscarder(logRotator(numToKeepStr: '1')) }

options {
        buildDiscarder logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '5', daysToKeepStr: '5', numToKeepStr: '10')
    }
  • artifactDaysToKeepStr:保留构建工件的天数
  • artifactNumToKeepStr:保留构建工件的最大数
  • daysToKeepStr:保留构建的天数
  • numToKeepStr:保留构建的最大数

checkoutToSubdirectory

在工作区的子目录中执行自动源代码控制检出。例如:options { checkoutToSubdirectory('foo') }

disableConcurrentBuilds

禁止管道的并发执行。可用于防止同时访问共享资源等。例如:options { disableConcurrentBuilds() }

disableResume

如果控制器重新启动,则不允许管道恢复。例如:options { disableResume() }

newContainerPerStage

与 docker 或 dockerfile 顶级代理一起使用。指定后,每个阶段将在同一节点上的新容器实例中运行,而不是所有阶段都在同一容器实例中运行。

overrideIndexTriggers

允许覆盖分支索引触发器的默认处理。如果在多分支或组织标签处禁用分支索引触发器,options { overrideIndexTriggers(true) } 则仅针对该作业启用它们。否则,options { overrideIndexTriggers(false) } 将仅禁用此作业的分支索引触发器。

preserveStashes

保留已完成构建的存储,以用于阶段重新启动。例如:options { preserveStashes() } 保留最近完成的构建中的存储,或 options { preserveStashes(buildCount: 5) } 保留五个最近完成的构建中的存储

quietPeriod

设置管道的静默期(以秒为单位),覆盖全局默认值。例如:options { quietPeriod(30) }

retry

失败时,重试整个管道指定的次数。例如:options { retry(3) }

skipDefaultCheckout

agent 默认情况下,在指令中跳过从源代码管理中检出代码。例如:options { skipDefaultCheckout() }

skipStagesAfterUnstable

一旦构建状态变为 UNSTABLE,就跳过阶段。例如:options { skipStagesAfterUnstable() }

timeout

为流水线运行设置一个超时时间,之后 Jenkins 应该中止流水线。例如:options { timeout(time: 1, unit: 'HOURS') }

示例 8:全局超时,声明式管道

pipeline {
    agent any
    
    options {
        timeout(time: 1, unit: 'HOURS') 
    }
    
    stages {
        stage('Example') {
            steps {
                echo 'Hello World'
            }
        }
    }
}
  • 为 Example 阶段指定一小时的执行超时,之后 Jenkins 将中止流水线运行。

timestamps

将在此阶段生成的所有控制台输出添加到发出该行的时间。例如:options { timestamps() }

parallelsAlwaysFailFast

为管道中的所有后续并行阶段设置 failfast true。例如:options { parallelsAlwaysFailFast() }

stage options

stageoptions 指令类似于流水线根目录上的 options 指令。然而,stage-级别 options 只能包括 retrytimeouttimestamps 等步骤, 或与 stage 相关的声明式选项,如:skipDefaultCheckout

stageoptions 指令中的步骤在进入 agent 之前被调用或在 when 条件出现时进行检查。

Available Stage Options

skipDefaultCheckout

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

timeout

设置此阶段的超时时间,在此之后,Jenkins 会终止该阶段。例如:options { timeout(time: 1, unit: 'HOURS') }

示例 9:阶段超时,声明式管道

pipeline {
    agent any
    
    stages {
        stage('Example') {
            options {
                timeout(time: 1, unit: 'HOURS') 
            }
            
            steps {
                echo 'Hello World'
            }
        }
    }
}
  • 为 Example 阶段指定一小时的执行超时,之后 Jenkins 将中止流水线运行。

retry

失败时,重试此阶段指定的次数。例如:options { retry(3) }

timestamps

将在此阶段生成的所有控制台输出添加到发出该行的时间。例如:options { timestamps() }

parameters

该 parameters 指令提供了用户在触发管道时应提供的参数列表。这些用户指定参数的值通过 params 对象可用于管道步骤。

Available Parameters

string

字符串类型的参数,例如:parameters { string(name: 'DEPLOY_ENV', defaultValue: 'staging', description: '') }

text

一个文本参数,可以包含多行,换行使用 \n,例如: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') }

示例 10:参数,声明式管道

pipeline {
    agent any
    
    parameters {
        string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
        text(name: 'BIOGRAPHY', defaultValue: 'my demo', 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}"
            }
        }
    }
}

triggers

注意:需要手动触发一次任务,让 Jenkins 加载 pipeline 后,trigger 指令才会生效。

triggers 指令定义了重新触发管道的自动化方式。对于与 GitHub 或 BitBucket 等源集成的管道,triggers 可能没有必要,因为基于 webhook 的集成可能已经存在。当前可用的触发器 cronpollSCMupstream

cron

接受一个 cron 风格的字符串来定义管道应该被重新触发的定期间隔,例如:triggers { cron('H */4 * * 1-5') }

pollSCM

接受 pollSCM 样式的字符串来定义 Jenkins 应检查新源更改的定期间隔。如果存在新的更改,管道将被重新触发。例如:triggers { pollSCM('H */4 * * 1-5') }

upstream

接受逗号分隔的作业字符串和阈值。当字符串中的任何作业以最小阈值完成时,管道将被重新触发。例如:triggers { upstream(upstreamProjects: 'job1,job2', threshold: hudson.model.Result.SUCCESS) }

hudson.model.Result 是一个枚举,包括以下值:

  • ABORTED:任务被手动中止。
  • FAILURE:构建失败。
  • SUCCESS:构建成功。
  • UNSTABLE:存在一些错误,但不至于构建失败。
  • NOT_BUILT:在多阶段构建时,前面阶段的问题导致后面阶段无法执行。

示例 11:触发器,声明式管道

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

Jenkins cron 语法

Jenkins cron 语法遵循 cron 实用程序的语法(略有不同)。具体来说,每一行由 5 个字段组成,由 TAB 或空格分隔:

MINUTEHOURDOMMONTHDOW
一小时内的分钟数 (0–59)一天中的小时 (0–23)月份中的某天 (1–31)月份 (1–12)星期几 (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 AM(午夜)到 7:59 AM 之间的某个时间。您还可以使用带 H、或不带范围的步长间隔。

该 H 符号可以被认为是一个范围内的随机值,但它实际上是作业名称的散列,而不是随机函数,因此该值对于任何给定项目都保持稳定。

请注意,对于月份字段,由于月份长度不同,短周期(例如:*/3H/3 不会在大多数月份结束时始终如一)工作。例如:*/3 将在长月的第 1、4、…31 天运行,然后在下个月的第二天再次运行。哈希值始终在 1-28 范围内选择,因此 H/3 在月底运行之间会产生 3 到 6 天的间隔。(较长的周期也会有不一致的长度,但效果可能相对不太明显。)

空行和以 # 开头的行将作为注释被忽略。

此外,还支持 @yearly@annually@monthly@weekly@daily@midnight@hourly 作为方便的别名。这些使用哈希系统进行自动平衡。例如:@hourlyH * * * * 并且可能表示一小时内的任何时间相同。@midnight 实际上是指 12:00 AM 到 2:59 AM 之间的某个时间。

表 1:Jenkins cron 语法示例

要求语法
每十五分钟一次(可能在 :07, :22, :37, :52)triggers{ cron('H/15 * * * *') }
每小时前半段每十分钟一次(三次,可能在 :04, :14, :24)triggers{ cron('H(0-29)/10 * * * *') }
每两小时一次,时间为每个工作日上午 9 点 45 分至下午 3 点 45 分,整点后 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') }
除 12 月外,每月 1 日和 15 日每天一次triggers{ cron('H H 1,15 1-11 *') }

stage

stage 指令位于该 stages 部分中,并且应该包含一个步骤部分、一个可选 agent 部分或其他特定于阶段的指令。实际上,流水线完成的所有实际工作都将包含在一个或多个 stage 指令中。

示例 12:阶段,声明式管道

pipeline {
    agent any

    stages {
        stage('Example') {
            steps {
                echo 'Hello World'
            }
        }
    }
}

tools

定义用于自动安装和放置在 PATH。如果指定 agent none,则忽略。

支持的工具

  • maven
  • jdk
  • gradle

示例 13:工具,声明式管道

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

工具名称必须在 Jenkins 中的 Manage Jenkins → Global Tool Configuration 下预先配置。

input

stageinput 指令允许您使用 input step 提示输入。在应用了 options 后,进入 stageagent 或评估 when 条件前,stage 将暂停。如果 input 被批准, stage 将会继续。作为 input 提交的一部分的任何参数都将在环境中用于其他 stage

配置选项

message

必需的。这将在用户提交 input 时呈现给用户。

id

input 的可选标识符,默认为 stage 名称。

ok

input 表单上的 ok 按钮的可选文本。

submitter

可选的以逗号分隔的用户列表或允许提交 input 的外部组名。默认允许任何用户。

不能有空格

submitterParameter

环境变量的可选名称。如果存在,用 submitter 名称设置。

parameters

提示提交者提供的一个可选的参数列表。

示例 14:输入步骤,声明性管道

pipeline {
    agent any
    
    stages {
        stage('Example') {
            input {
                message "Should we continue?"
                ok "Yes, we should."
                submitter "alice,bob"
                parameters {
                    string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
                }
            }
            
            steps {
                echo "Hello, ${PERSON}, nice to meet you."
            }
        }
    }
}

when

when 指令允许管道根据给定条件确定是否应执行阶段。该 when 指令必须至少包含一个条件。如果 when 指令包含多个条件,则所有子条件都必须返回 true 才能执行阶段。这就像子条件嵌套在 allOf 条件中一样(参见下面的示例)。如果使用 anyOf 条件,请注意一旦找到第一个 “真” 条件,该条件就会跳过剩余的测试。

可以使用嵌套条件构建更复杂的条件结构:notallOfanyOf。嵌套条件可以嵌套到任意深度。

内置条件

branch

当正在构建的分支与给定的分支模式(ANT 样式路径 glob)匹配时执行阶段,例如:when { branch 'master' }。请注意,这仅适用于多分支管道。

可以在属性之后添加可选参数 comparator,以指定如何评估任何模式以进行匹配:EQUALS 对于简单的字符串比较,GLOB(默认)对于 ANT 样式路径 glob(example 与 changeset 相同),或 REGEXP 对于正则表达式匹配。例如:when { branch pattern: "release-\\d+", comparator: "REGEXP"}

buildingTag

在构建 build 标签时执行阶段。例子:when { buildingTag() }

changelog

如果构建的 SCM 更改日志包含给定的正则表达式模式,则执行该阶段,例如:when { changelog '.*^\\[DEPENDENCY\\] .+$' }

changeset

如果构建的 SCM 变更集包含一个或多个与给定模式匹配的文件,则执行该阶段。例子:when { changeset "**/*.js" }

可以在属性之后添加可选参数 comparator 以指定如何评估任何模式以进行匹配:EQUALS 对于简单的字符串比较,GLOB(默认)对于 ANT 样式路径 glob 不区分大小写,这可以使用参数关闭,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' }

可以在属性之后添加可选参数 comparator 以指定如何评估任何模式以进行匹配:EQUALS 用于简单的字符串比较(默认),GLOB 用于 ANT 样式路径 glob(example 与 changeset 相同)或 REGEXP 用于正则表达式匹配。例子:when { changeRequest authorEmail: "[\\w_-.]+@example.com", comparator: 'REGEXP' }

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 } } 请注意,从表达式返回字符串时,必须将它们转换为 “布尔值” 或返回 null 计算结果为 false。简单地返回 “0” 或 “false” 仍将评估为 “true”。

tag

TAG_NAME 如果变量与给定模式匹配,则执行该阶段。示例:when { tag "release-*" }。如果提供了空模式,则如果 TAG_NAME 变量存在(与 buildingTag() 相同),则阶段将执行。

可以在属性之后添加可选参数 comparator,以指定如何评估任何模式以进行匹配:EQUALS 对于简单的字符串比较,GLOB(默认)对于 ANT 样式路径 glob(example 与 changeset 相同),或 REGEXP 对于正则表达式匹配。例如:when { tag pattern: "release-\\d+", comparator: "REGEXP"}

not

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

allOf

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

anyOf

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

triggeredBy

当前构建被给定的参数触发时执行阶段。例如:

  • when { triggeredBy ‘SCMTrigger’ }
  • when { triggeredBy ‘TimerTrigger’ }
  • when { triggeredBy ‘BuildUpstreamCause’ }
  • when { triggeredBy cause: “UserIdCause”, detail: “vlinde” }

在进入 stageagent 前评估 when

默认情况下, 如果定义了某个阶段的代理,在进入该 stageagent 后该 stagewhen 条件将会被评估。但是, 可以通过在 when 块中指定 beforeAgent 选项来更改此选项。 如果 beforeAgent 被设置为 true, 那么就会首先对 when 条件进行评估 , 并且只有在 when 条件验证为真时才会进入 agent

在指令 input 之前进行评估 when

默认情况下,如果定义了一个阶段,则不会在进入 input 之前评估的 when 条件。但是,这可以通过 beforeInputwhen 块中指定选项来更改。如果 beforeInput 设置为 true,将首先评估 when 条件,只有当 when 条件评估为 true 时才会进入 input

beforeAgent true 优先于 beforeInput true

在指令 options 之前进行评估 when

默认情况下,将在进入 options 后评估 whena 的条件(如果已定义)。但是,这可以通过在 when 块中指定 beforeOptions 选项来更改。如果设置为 true,将首先评估 when 条件,并且仅当 when 条件评估为 true 时才会进入。

beforeAgent truebeforeInput true 优先于 beforeOptions true

示例 15:单一条件,声明式管道

pipeline {
    agent any
    
    stages {
        stage('Example Build') {
            steps {
                echo 'Hello World'
            }
        }
        
        stage('Example Deploy') {
            when {
                branch 'production'
            }
            
            steps {
                echo 'Deploying'
            }
        }
    }
}

示例 16:多条件,声明性管道

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'
            }
        }
    }
}

示例 17:嵌套条件(与前面示例相同的行为)

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'
            }
        }
    }
}

示例 18:多重条件和嵌套条件

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'
            }
        }
    }
}

示例 19:表达式条件和嵌套条件

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'
            }
        }
    }
}

示例 20:beforeAgent

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'
            }
        }
    }
}

示例 21:beforeInput

pipeline {
    agent none
    
    stages {

        stage('Example Build') {
            steps {
                echo 'Hello World'
            }
        }
        
        stage('Example Deploy') {
            when {
                beforeInput true
                branch 'production'
            }
            
            input {
                message "Deploy to production?"
                id "simple-input"
            }
            
            steps {
                echo 'Deploying'
            }
        }
    }
}

示例 22:beforeOptions

pipeline {
    agent none
    
    stages {
        stage('Example Build') {
            steps {
                echo 'Hello World'
            }
        }
        
        stage('Example Deploy') {
            when {
                beforeOptions true
                branch 'testing'
            }
            
            options {
                lock label: 'testing-deploy-envs', quantity: 1, variable: 'deployEnv'
            }
            
            steps {
                echo "Deploying to ${deployEnv}"
            }
        }
    }
}

示例 23:triggeredBy

pipeline {
    agent none
    
    stages {
        stage('Example Build') {
            steps {
                echo 'Hello World'
            }
        }
        
        stage('Example Deploy') {
            when {
                triggeredBy "TimerTrigger"
            }

            steps {
                echo 'Deploying'
            }
        }
    }
}

Sequential Stages

声明性管道中的阶段可能有一个 stages 部分,其中包含要按顺序运行的嵌套阶段的列表。请注意,一个阶段必须只有 stepsstagesparallelmatrix 中的一个。如果 stage 指令嵌套在 parallel 块或 matrix 块本身内,则不可能在 stage 指令内嵌套 parallel 块或 matrix 块。然而,parallel 块或 matrix 块中的 stage 指令可以使用 stage 的所有其他功能,包括 agenttoolswhen 等。

示例 24:顺序阶段,声明式管道

pipeline {
    agent none
    
    stages {
        stage('Non-Sequential Stage') {
            agent {
                label 'for-non-sequential'
            }
            
            steps {
                echo "On Non-Sequential Stage"
            }
        }
        
        stage('Sequential') {
            agent {
                label 'for-sequential'
            }
            
            environment {
                FOR_SEQUENTIAL = "some-value"
            }
            
            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"
                            }
                        }
                    }
                }
            }
        }
    }
}

Parallel

声明式流水线的阶段可以在他们内部声明多个嵌套阶段, 它们将并行执行。注意,一个阶段必须只有一个 stepsparallel 的阶段。嵌套阶段本身不能包含进一步的 parallel 阶段, 但是其他的阶段的行为与任何其他 stage 相同。任何包含 parallel 的阶段不能包含 agenttools 阶段, 因为他们没有相关 steps

另外, 通过添加 failFast true 到包含 parallelstage 中,当其中一个进程失败时,您可以强制所有的 parallel 阶段都被终止。添加另一个选项 failfast 是在管道定义中添加一个选项:parallelsAlwaysFailFast()
在脚本式流水线中,failFast true 需要换成 failFast: true

示例 25:并行阶段,声明式管道

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"
                            }
                        }
                    }
                }
            }
        }
    }
}

示例 26: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') {
                    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"
                            }
                        }
                    }
                }
            }
        }
    }
}

Matrix

声明性管道中的阶段可能有一个 matrix 部分,定义要并行运行的 name-value 组合的多维矩阵。我们将这些组合称为矩阵中的 “单元”。矩阵中的每个单元可以包括一个或多个使用该单元的配置顺序运行的阶段。请注意,一个阶段必须只有 stepsstagesparallelmatrix 中的一个。如果 stage 指令嵌套在 parallel 块或 matrix 块本身内,则不可能在 stage 指令内嵌套 parallel 块或 matrix 块。然而,parallel 块或 matrix 块中的 stage 指令可以使用 stage 的所有其他功能,包括包括 agenttoolswhen等。

此外,当任何一个 matrix 单元出现故障时,可以通过将 failFast true 添加到包含矩阵的 stage,强制所有 matrix 单元中止。添加 failfast 的另一个选项是向管道定义添加一个选项:parallelsAlwaysFailFast()

matrix 部分必须包括 axes 部分和 stages 部分。axes 部分定义 matrix 中每个axes 的值。stages 部分定义了在每个单元中顺序运行的 stage 列表。matrix 可能有一个排除部分,用于从 matrix 中删除无效单元格。stage 上可用的许多指令,包括 agenttoolswhen等,也可以添加到 matrix 中,以控制每个单元的行为。

axes

axes 部分指定了一个或多个 axis 指令。每个都 axis 包含一个 name 和一个列表 values。每个轴的所有值都与其他值组合以生成单元格。

示例 27:具有 3 个单元的单轴

matrix {
    axes {
        axis {
            name 'PLATFORM'
            values 'linux', 'mac', 'windows'
        }
    }
    // ...
}

示例 28:具有 12 个单元的两轴(三乘四)

matrix {
    axes {
        axis {
            name 'PLATFORM'
            values 'linux', 'mac', 'windows'
        }
        
        axis {
            name 'BROWSER'
            values 'chrome', 'edge', 'firefox', 'safari'
        }
    }
    // ...
}

示例 29:具有 24 个单元的三轴矩阵(三乘四乘二)

matrix {
    axes {
        axis {
            name 'PLATFORM'
            values 'linux', 'mac', 'windows'
        }
        
        axis {
            name 'BROWSER'
            values 'chrome', 'edge', 'firefox', 'safari'
        }
        
        axis {
            name 'ARCHITECTURE'
            values '32-bit', '64-bit'
        }
    }
    // ...
}

stages

stages 部分指定在每个单元格中顺序执行的一个或多个 stage

示例 30:具有 3 个单元的单轴,每个单元运行三个阶段 - “构建”、“测试” 和 “部署”

matrix {
    axes {
        axis {
            name 'PLATFORM'
            values 'linux', 'mac', 'windows'
        }
    }
    
    stages {
        stage('build') {
            // ...
        }
        
        stage('test') {
            // ...
        }
        
        stage('deploy') {
            // ...
        }
    }
}

示例 31:具有 12 个单元的两轴(三乘四)

matrix {
    axes {
        axis {
            name 'PLATFORM'
            values 'linux', 'mac', 'windows'
        }
        
        axis {
            name 'BROWSER'
            values 'chrome', 'edge', 'firefox', 'safari'
        }
    }
    
    stages {
        stage('build-and-test') {
            // ...
        }
    }
}

excludes (optional)

可选的 excludes 部分允许作者指定一个或多个 excludes 过滤器表达式,这些表达式选择要从扩展的矩阵单元集(也称为稀疏)中排除的单元。过滤器使用一个或多个 exclude axis 指令的基本指令结构构造,每个指令都有一个 name 和 values 列表。

excludes 中的 axis 指令生成一组组合(类似于生成矩阵单元)。匹配 excludes 组合中所有值的矩阵单元将从矩阵中删除。如果提供了多个 exclude 指令,则分别计算每个指令以删除单元格。

在处理要 excludes 的一长串值时,exclude axis 指令可以使用 notValues 而不是 values。这些将排除与传递给 notValues 的值之一不匹配的单元格。

示例 32:具有 24 个单元的三轴矩阵,不包括 “32 位,mac”(不包括 4 个单元)

matrix {
    axes {
        axis {
            name 'PLATFORM'
            values 'linux', 'mac', 'windows'
        }
        
        axis {
            name 'BROWSER'
            values 'chrome', 'edge', 'firefox', 'safari'
        }
        
        axis {
            name 'ARCHITECTURE'
            values '32-bit', '64-bit'
        }
    }
    
    excludes {
        exclude {
            axis {
                name 'PLATFORM'
                values 'mac'
            }
            
            axis {
                name 'ARCHITECTURE'
                values '32-bit'
            }
        }
    }
    // ...
}

排除 linuxsafari 的组合,并排除使用边缘浏览器的任何非 windows 平台。

例 33:包含 24 个单元格的三轴矩阵,不包括 “32位,mac” 和无效的浏览器组合(不包括 9 个单元格)

matrix {
    axes {
        axis {
            name 'PLATFORM'
            values 'linux', 'mac', 'windows'
        }
        
        axis {
            name 'BROWSER'
            values 'chrome', 'edge', 'firefox', 'safari'
        }
        
        axis {
            name 'ARCHITECTURE'
            values '32-bit', '64-bit'
        }
    }
    
    excludes {
        exclude {
            // 4 cells
            axis {
                name 'PLATFORM'
                values 'mac'
            }
            
            axis {
                name 'ARCHITECTURE'
                values '32-bit'
            }
        }
        
        exclude {
            // 2 cells
            axis {
                name 'PLATFORM'
                values 'linux'
            }
            
            axis {
                name 'BROWSER'
                values 'safari'
            }
        }
        
        exclude {
            // 3 more cells and '32-bit, mac' (already excluded)
            axis {
                name 'PLATFORM'
                notValues 'windows'
            }
            
            axis {
                name 'BROWSER'
                values 'edge'
            }
        }
    }
    // ...
}

Matrix cell-level directives (optional)

Matrix 允许用户通过在 Matrix 自身下添加阶段级指令,有效地配置每个单元的整体环境。这些指令的行为与它们在舞台上的行为相同,但它们也可以接受矩阵为每个单元提供的值。

axisexclude 指令定义组成矩阵的静态单元格集。这组组合是在管道运行开始之前生成的。另一方面,“每单元” 指令在运行时进行评估。

这些指令包括:

  • agent
  • environment
  • input
  • options
  • post
  • tools
  • when

示例 34:完整的矩阵示例,声明性管道

pipeline {
    agent none
    
    parameters {
        choice(name: 'PLATFORM_FILTER', choices: ['all', 'linux', 'windows', 'mac'], description: 'Run on specific platform')
    }
    
    stages {
        stage('BuildAndTest') {
            matrix {
                agent {
                    label "${PLATFORM}-agent"
                }
                
                when { 
                    anyOf {
                        expression { params.PLATFORM_FILTER == 'all' }
                        expression { params.PLATFORM_FILTER == env.PLATFORM }
                    }
                }
                
                axes {
                    axis {
                        name 'PLATFORM'
                        values 'linux', 'windows', 'mac'
                    }
                    
                    axis {
                        name 'BROWSER'
                        values 'firefox', 'chrome', 'safari', 'edge'
                    }
                }
                
                excludes {
                    exclude {
                        axis {
                            name 'PLATFORM'
                            values 'linux'
                        }
                        
                        axis {
                            name 'BROWSER'
                            values 'safari'
                        }
                    }
                    
                    exclude {
                        axis {
                            name 'PLATFORM'
                            notValues 'windows'
                        }
                        
                        axis {
                            name 'BROWSER'
                            values 'edge'
                        }
                    }
                }
                
                stages {
                    stage('Build') {
                        steps {
                            echo "Do Build for ${PLATFORM} - ${BROWSER}"
                        }
                    }
                    
                    stage('Test') {
                        steps {
                            echo "Do Test for ${PLATFORM} - ${BROWSER}"
                        }
                    }
                }
            }
        }
    }
}

Steps

添加了下面列出的步骤,这些步骤只在声明式流水线中 only supported

script

script 步骤采用脚本管道块并在声明性管道中执行该块。对于大多数用例,script 在声明式管道中该步骤应该是不必要的,但它可以提供有用的 “逃生出口”。非平凡大小和/或复杂性的 script 块应该移到共享库中。

示例 35:声明式管道中的脚本块

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"
                    }
                }
            }
        }
    }
}

Scripted Pipeline

Scripted PipelineDeclarative Pipeline 一样,构建在底层 Pipeline 子系统之上。与声明式不同,Scripted Pipeline 实际上是使用 Groovy 构建的通用 DSL2Groovy 语言提供的大多数功能都可供 Scripted Pipeline 的用户使用,这意味着它可以是一个非常富有表现力和灵活的工具,可以用来创建持续交付管道。

Flow Control

Scripted Pipeline 从上到下依次执行 Jenkinsfile,就像 Groovy 或其他语言中的大多数传统脚本一样。因此,提供流控制依赖于 Groovy 表达式,例如:if/else 条件

示例 36:条件语句 if,脚本管道

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

可以管理脚本化管道流控制的另一种方式是使用 Groovy 的异常处理支持。当步骤由于某种原因失败时,它们会抛出异常。错误处理行为必须使用 Groovy 中的 try/catch/finally 块,例如:

示例 37:Try-Catch 块,脚本化管道

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

Steps

正如开头所说的,Pipeline 最基本的部分是 Steps。从根本上说,步骤告诉 Jenkins 要做什么,并作为声明式和脚本化流水线语法的基本构建块。

Scripted Pipeline 没有引入任何特定于其语法的步骤;流水线步骤参考 包含流水线和插件提供的完整步骤列表。

与普通 Groovy 区别

为了提供持久性,这意味着运行管道可以在 Jenkins 控制器重新启动后继续存在,脚本化管道必须将数据序列化回控制器。由于此设计要求,某些 Groovy 惯用语如:collection.each { item → /* perform operation */ } 不完全支持。

语法比较

最初创建 Jenkins Pipeline 时,选择了 Groovy 作为基础。Jenkins 长期以来一直提供嵌入式 Groovy 引擎,为管理员和用户提供高级脚本功能。此外,Jenkins Pipeline 的实现者发现 Groovy 是构建现在称为 “脚本化管道” DSL2 的坚实基础。

由于它是一个功能齐全的编程环境,Scripted Pipeline 为 Jenkins 用户提供了极大的灵活性和可扩展性。Groovy 学习曲线通常不适用于给定团队的所有成员,因此创建声明式管道是为了为创作 Jenkins 管道提供更简单和更有主见的语法。

两者基本上是相同的管道子系统。它们都是 “管道即代码” 的持久实现。他们都能够使用内置于 Pipeline 或由插件提供的步骤。两者都可以使用 共享库

然而,它们的不同之处在于语法和灵活性。声明式通过更严格和预定义的结构限制了用户可用的内容,使其成为更简单的持续交付管道的理想选择。Scripted 提供的限制很少,就结构和语法的唯一限制往往由 Groovy 本身定义,而不是任何特定于 Pipeline 的系统,这使其成为高级用户和具有更复杂要求的用户的理想选择。顾名思义,声明式管道鼓励声明式编程模型3。而脚本化管道遵循更命令式的编程模型4


  1. Version 2.5 of the “Pipeline plugin” introduces support for Declarative Pipeline syntax ↩︎

  2. Domain-specific language ↩︎ ↩︎

  3. Declarative Programming ↩︎

  4. Imperative Programming ↩︎

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐