一、stage

stage指令位于stages下,包含一个steps、一个agent(可选)或其他特定的stage指令。流水线中实际执行的指令都在stage中配置,所以在流水线中,至少有一个stage。配置示例如下:

pipeline {
    agent any

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

二、Input

input字段可以实现在流水线中进行交互式操作,比如选择要部署的环境、是否继续执行某个阶段等。

配置Input支持以下选项:

  • message:必选,需要用户进行 input 的提示信息,比如:“是否发布到生产环境?”
  • id:可选,input 的标识符,默认为 stage 的名称;
  • ok:可选,确认按钮的显示信息,比如:“确定”、“允许”;
  • submitter:可选,允许提交 input 操作的用户或组的名称,如果为空,任何登录用户均 可提交 input;
  • parameters:提供一个参数列表供 input 使用。

假如需要配置一个提示消息为“还继续么”、确认按钮为“继续”、提供一个 PERSON 的变 量的参数,并且只能由登录用户为 alice 和 bob 提交的 input 流水线:

pipeline {
    agent any

    stages {
        stage('Example') {
            input {
                message "还继续么?"
                ok "继续"
                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 指令允许流水线根据给定的条件决定是否应该执行该 stage,when 指令必须包含至少 一个条件。如果 when 包含多个条件,所有的子条件必须都返回 True,stage 才能执行。

When 也可以结合 not、allOf、anyOf 语法达到更灵活的条件匹配。

目前比较常用的内置条件如下:

  • branch:当正在构建的分支与给定的分支匹配时,执行这个 stage,例如:when { branch 'master' }。注意,branch 只适用于多分支流水线;
  • changelog:匹配提交的 changeLog 决定是否构建,例如: when { changelog '.^\[DEPENDENCY\] .+$' };
  • environment:当指定的环境变量和给定的变量匹配时,执行这个 stage,例如:when { environment name: 'DEPLOY_TO', value: 'production' };
  • equals:当期望值和实际值相同时,执行这个 stage,例如:when { equals expected: 2, actual: currentBuild.number };
  • expression:当指定的 Groovy 表达式评估为 True,执行这个 stage,例如:when { expression { return params.DEBUG_BUILD } };
  • tag:如果 TAG_NAME 的值和给定的条件匹配,执行这个 stage,例如:when { tag "release-*" };
  • not:当嵌套条件出现错误时,执行这个 stage,必须包含一个条件,例如:when { not { branch 'master' } };
  • allOf:当所有的嵌套条件都正确时,执行这个 stage,必须包含至少一个条件,例如: when { allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } };
  • anyOf:当至少有一个嵌套条件为 True 时,执行这个 stage,例如:when { anyOf { branch 'master'; branch 'staging' } }。

示例 1:当分支为 production 时,执行 Example Deploy 步骤:

pipeline {
    agent any

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

        stage('Example Deploy') {
            when {
                branch 'production'
            }
            steps {
                echo 'Deploying'
            }
        }
    }
}

也可以同时配置多个条件,比如分支是 production,而且 DEPLOY_TO 变量的值为 production 时,才执行 Example Deploy:

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

也可以使用 anyOf 进行匹配其中一个条件即可,比如分支为 production,DEPLOY_TO 为 production 或 staging 时执行 Deploy:

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

也可以使用 expression 进行正则匹配,比如当 BRANCH_NAME 为 production 或 staging,并 且 DEPLOY_TO 为 production 或 staging 时才会执行 Example Deploy:

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

默认情况下,如果定义了某个 stage 的 agent,在进入该 stage 的 agent 后,该 stage 的 when 条件才会被评估,但是可以通过一些选项更改此选项。比如在进入stage的agent前评估 when, 可以使用beforeAgent,当 when为true时才进行该stage。

目前支持的前置条件如下:

  • beforeAgent:如果 beforeAgent 为 true,则会先评估 when 条件。在 when 条件为 true 时,才会进入该 stage;
  • beforeInput:如果 beforeInput 为 true,则会先评估 when 条件。在 when 条件为 true 时,才会进入到 input 阶段;
  • beforeOptions:如果 beforeInput 为 true,则会先评估 when 条件。在 when 条件为 true 时,才会进入到 options 阶段;

注意:beforeOptions 优先级大于 beforeInput 大于 beforeAgent

示例1:配置一个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'
            }
        }
    }
}

示例2:配置一个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'
            }
        }
    }
}

示例3:配置一个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}"
            }
        }
    }
}

steps包含一个完整的script步骤列表,是流水线真正指定操作的位置,比如构建命令、部署命令等。script步骤需要scripted-pipeline块并在声明式流水线中执行,对于大多数用例来说,script步骤并不是必要的。

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

四、Parallel

在声明式流水线中可以使用 Parallel 字段,即可很方便的实现并发构建,比如对分支 A、B、 C 进行并行处理:

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

设置 failFast 为 true 表示并行流水线中任意一个 stage 出现错误,其它 stage 也会立即终止。 也可以通过 options 配置在全局:

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