Appearance
全局配置
Appearance
Jenkins 流水线 (或简单的带有大写"P"的"Pipeline") 是一套插件,它支持实现和集成 continuous delivery pipelines 到Jenkins。 更多信息参见官方文档
流水线提供了一组可扩展的工具,通过 (Pipeline domain-specific language (DSL) syntax)[https://www.jenkins.io/zh/doc/book/pipeline/syntax/].对从简单到复杂的交付流水线 "作为代码" 进行建模。
流水线是用户定义的一个CD流水线模型 。流水线的代码定义了整个的构建过程, 他通常包括构建, 测试和交付应用程序的阶段 。
另外 , pipeline 块是 声明式流水线语法的关键部分.
节点是一个机器 ,它是Jenkins环境的一部分 and is capable of执行流水线。
另外, node
块是 脚本化流水线语法的关键部分.
stage 块定义了在整个流水线的执行任务的概念性地不同的的子集(比如 "Build", "Test" 和 "Deploy" 阶段), 它被许多插件用于可视化 或Jenkins流水线目前的 状态/进展.
本质上 ,一个单一的任务, a step 告诉Jenkins 在特定的时间点要做_what_ (或过程中的 "step")。 举个例子,要执行shell命令 ,请使用 sh 步骤: sh 'make'。当一个插件扩展了流水线DSL, [1] 通常意味着插件已经实现了一个新的 step。
Jenkinsfile (Declarative Pipeline)
pipeline {
// 在任何可用的代理上,执行流水线或它的任何阶段。
agent any
stages {
// 定义 "Build" 阶段。
stage('Build') {
steps {
// 执行与 "Build" 阶段相关的步骤。
}
}
// 定义"Test" 阶段。
stage('Test') {
steps {
// 执行与"Test" 阶段相关的步骤。
}
}
// 定义 "Deploy" 阶段。
stage('Deploy') {
steps {
// 执行与 "Deploy" 阶段相关的步骤。
}
}
}
}
在脚本化流水线语法中, 一个或多个 node 块在整个流水线中执行核心工作。 虽然这不是脚本化流水线语法的强制性要求, 但它限制了你的流水线的在node
块内的工作做两件事:
通过在Jenkins队列中添加一个项来调度块中包含的步骤。 节点上的执行器一空闲, 该步骤就会运行。
创建一个工作区(特定为特定流水间建立的目录),其中工作可以在从源代码控制检出的文件上完成。
Jenkinsfile (Scripted Pipeline)
// node 是脚本化流水线的一种特定语法,它指示 Jenkins 在任何可用的代理/节点上执行流水线 (和包含在其中的任何阶段)这实际上等效于 声明式流水线特定语法的`agent`。
node { // 在任何可用的代理上,执行流水线或它的任何阶段。
// 定义 "Build" 阶段。 stage 块 在脚本化流水线语法中是可选的。 然而, 在脚本化流水线中实现 stage 块 ,可以清楚的显示Jenkins UI中的每个 stage 的任务子集。
stage('Build') {
// 执行与 "Build" 阶段相关的步骤。
}
// 定义 "Test" 阶段。
stage('Test') {
// 执行与 "Test" 阶段相关的步骤。
}
// 定义 "Deploy" 阶段。
stage('Deploy') {
// 执行与 "Deploy" 阶段相关的步骤。
}
}
Jenkinsfile (Declarative Pipeline)
// pipeline 是声明式流水线的一种特定语法,他定义了包含执行整个流水线的所有内容和指令的 "block" 。
pipeline {
// agent是声明式流水线的一种特定语法,它指示 Jenkins 为整个流水线分配一个执行器 (在节点上)和工作区。
agent any
stages {
// stage 是一个描述 stage of this Pipeline的语法块。如 above所述, 在脚本化流水线语法中,stage 块是可选的。
stage('Build') {
// steps 是声明式流水线的一种特定语法,它描述了在这个 stage 中要运行的步骤。
steps {
// sh 是一个执行给定的shell命令的流水线 step (由 Pipeline: Nodes and Processes plugin提供)
sh 'make'
}
}
stage('Test'){
steps {
sh 'make check'
// junit 是另一个聚合测试报告的流水线 step (由 JUnit plugin提供)。
junit 'reports/**/*.xml'
}
}
stage('Deploy') {
steps {
sh 'make publish'
}
}
}
}
pipeline {
agent any
environment {
CODING_DOCKER_REG_HOST = "${CCI_CURRENT_TEAM}-docker.pkg.${CCI_CURRENT_DOMAIN}"
CODING_DOCKER_IMAGE_NAME = "${PROJECT_NAME.toLowerCase()}/${DOCKER_REPO_NAME}/${DOCKER_IMAGE_NAME}"
}
stages {
stage("检出") {
steps {
checkout(
[$class: 'GitSCM',
branches: [[name: GIT_BUILD_REF]],
userRemoteConfigs: [[
url: GIT_REPO_URL,
credentialsId: CREDENTIALS_ID
]]]
)
}
}
stage('安装依赖') {
steps {
sh "npm install"
}
}
stage('单元测试') {
steps {
sh "npm test"
}
post {
always {
// 收集测试报告
junit 'reports/**/*.xml'
}
}
}
stage('依赖漏洞扫描') {
steps {
npmAuditInDir(directory: '/', collectResult: true)
}
}
stage('构建镜像并推送到 CODING Docker 制品库') {
steps {
script {
docker.withRegistry(
"${CCI_CURRENT_WEB_PROTOCOL}://${CODING_DOCKER_REG_HOST}",
"${CODING_ARTIFACTS_CREDENTIALS_ID}"
) {
def dockerImage = docker.build("${CODING_DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_VERSION}", "-f ${DOCKERFILE_PATH} ${DOCKER_BUILD_CONTEXT}")
dockerImage.push()
}
}
}
}
stage("部署到远端服务") {
steps {
script {
def remoteConfig = [:]
remoteConfig.name = "my-remote-server"
remoteConfig.host = "${REMOTE_HOST}"
remoteConfig.port = "${REMOTE_SSH_PORT}".toInteger()
remoteConfig.allowAnyHosts = true
withCredentials([
sshUserPrivateKey(
credentialsId: "${REMOTE_CRED}",
keyFileVariable: "privateKeyFilePath"
),
usernamePassword(
credentialsId: "${CODING_ARTIFACTS_CREDENTIALS_ID}",
usernameVariable: 'CODING_DOCKER_REG_USERNAME',
passwordVariable: 'CODING_DOCKER_REG_PASSWORD'
)
]) {
// SSH 登录用户名
remoteConfig.user = "${REMOTE_USER_NAME}"
// SSH 私钥文件地址
remoteConfig.identityFile = privateKeyFilePath
// 请确保远端环境中有 Docker 环境
sshCommand(
remote: remoteConfig,
command: "docker login -u ${CODING_DOCKER_REG_USERNAME} -p ${CODING_DOCKER_REG_PASSWORD} ${CODING_DOCKER_REG_HOST}",
sudo: true,
)
sshCommand(
remote: remoteConfig,
command: "docker rm -f nodejs-express-app | true",
sudo: true,
)
// DOCKER_IMAGE_VERSION 中涉及到 GIT_LOCAL_BRANCH / GIT_TAG / GIT_COMMIT 的环境变量的使用
// 需要在本地完成拼接后,再传入到远端服务器中使用
DOCKER_IMAGE_URL = sh(
script: "echo ${CODING_DOCKER_REG_HOST}/${CODING_DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_VERSION}",
returnStdout: true
)
sshCommand(
remote: remoteConfig,
command: "docker run -d -p 3000:3000 --name nodejs-express-app ${DOCKER_IMAGE_URL}",
sudo: true,
)
echo "部署成功,请到 http://${REMOTE_HOST}:3000 预览效果"
}
}
}
}
}
}
所有有效的声明式流水线必须包含在一个 pipeline 块中, 比如
pipeline {
/* insert Declarative Pipeline here */
}
流水线顶层必须是一个 block, 特别地: pipeline
没有分号作为语句分隔符,,每条语句都必须在自己的行上。
块只能由 节段, 指令, 步骤, 或赋值语句组成。
agent 部分支持一些不同类型的参数。这些参数应用在pipeline
块的顶层, 或 stage 指令内部。
- any: 在任何可用的代理上执行流水线或阶段。例如: agent any
- none: 当在 pipeline 块的顶部没有全局代理, 该参数将会被分配到整个流水线的运行中并且每个 stage 部分都需要包含他自己的 agent 部分。比如: agent none
- label: 在提供了标签的 Jenkins 环境中可用的代理上执行流水线或阶段。 例如: agent { label 'my-defined-label' }
- node: agent { node { label 'labelName' } } 和 agent { label 'labelName' } 一样, 但是 node 允许额外的选项 (比如 customWorkspace )。
- docker: 使用给定的容器执行流水线或阶段。该容器将在预置的 node上,或在匹配可选定义的`label` 参数上,动态的供应来接受基于Docker的流水线。 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 必须从多个分支流水线中加载, 或者加载 "Pipeline from SCM." 通常,这是源代码仓库的根目录下的 Dockerfile : agent { dockerfile true }. 如果在另一个目录下构建 Dockerfile , 使用 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'
}
}
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 部分定义一个或多个steps ,这些阶段根据流水线或阶段的完成情况而 运行(取决于流水线中 post 部分的位置). post 支持以下 post-condition 块中的其中之一: always, changed, failure, success, unstable, 和 aborted。 这些条件块允许在 post 部分的步骤的执行取决于流水线或阶段的完成状态。 按照惯例, post 部分应该放在流水线的底部。 Post-condition 块包含与 steps 部分相同的steps。
- always:无论流水线或阶段的完成状态如何,都允许在 post 部分运行该步骤。
- changed:只有当前流水线或阶段的完成状态与它之前的运行不同时,才允许在 post 部分运行该步骤。
- failure:只有当前流水线或阶段的完成状态为"failure",才允许在 post 部分运行该步骤, 通常web UI是红色。
- success:只有当前流水线或阶段的完成状态为"success",才允许在 post 部分运行该步骤, 通常web UI是蓝色或绿色。
- unstable:只有当前流水线或阶段的完成状态为"unstable",才允许在 post 部分运行该步骤, 通常由于测试失败,代码违规等造成。通常web UI是黄色。
- aborted:只有当前流水线或阶段的完成状态为"aborted",才允许在 post 部分运行该步骤, 通常由于流水线被手动的aborted。通常web UI是灰色。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
post {
always {
echo 'I will always say Hello again!'
}
}
}
包含一系列一个或多个 stage 指令, stages 部分是流水线描述的大部分"work" 的位置。 建议 stages 至少包含一个 stage 指令用于连续交付过程的每个离散部分,比如构建, 测试, 和部署。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}
steps 部分在给定的 stage 指令中执行的定义了一系列的一个或多个steps。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}
environment 指令制定一个 键-值对序列,该序列将被定义为所有步骤的环境变量,或者是特定于阶段的步骤, 这取决于 environment 指令在流水线内的位置。
该指令支持一个特殊的助手方法 credentials() ,该方法可用于在Jenkins环境中通过标识符访问预定义的凭证。 对于类型为 "Secret Text"的凭证, credentials() 将确保指定的环境变量包含秘密文本内容。 对于类型为 "SStandard username and password"的凭证, 指定的环境变量指定为 username:password ,并且两个额外的环境变量将被自动定义 :分别为 MYVARNAME_USR 和 MYVARNAME_PSW 。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
// 顶层流水线块中使用的 environment 指令将适用于流水线中的所有步骤。
environment {
CC = 'clang'
}
stages {
stage('Example') {
// 在一个 stage 中定义的 environment 指令只会将给定的环境变量应用于 stage 中的步骤。
environment {
// environment 块有一个 助手方法 credentials() 定义,该方法可以在 Jenkins 环境中用于通过标识符访问预定义的凭证。
AN_ACCESS_KEY = credentials('my-prefined-secret-text')
}
steps {
sh 'printenv'
}
}
}
}
options 指令允许从流水线内部配置特定于流水线的选项。 流水线提供了许多这样的选项, 比如 buildDiscarder,但也可以由插件提供, 比如 timestamps.
- buildDiscarder: 为最近的流水线运行的特定数量保存组件和控制台输出。例如: options { buildDiscarder(logRotator(numToKeepStr: '1')) }
- disableConcurrentBuilds: 不允许同时执行流水线。 可被用来防止同时访问共享资源等。 例如: options { disableConcurrentBuilds() }
- overrideIndexTriggers: 允许覆盖分支索引触发器的默认处理。 如果分支索引触发器在多分支或组织标签中禁用, options { overrideIndexTriggers(true) } 将只允许它们用于促工作。否则, options { overrideIndexTriggers(false) } 只会禁用改作业的分支索引触发器。
- skipDefaultCheckout: 在`agent` 指令中,跳过从源代码控制中检出代码的默认情况。例如: options { skipDefaultCheckout() }
- skipStagesAfterUnstable: 一旦构建状态变得UNSTABLE,跳过该阶段。例如: options { skipStagesAfterUnstable() }
- checkoutToSubdirectory: 在工作空间的子目录中自动地执行源代码控制检出。例如: options { checkoutToSubdirectory('foo') }
- timeout: 设置流水线运行的超时时间, 在此之后,Jenkins将中止流水线。例如: options { timeout(time: 1, unit: 'HOURS') }
- retry: 在失败时, 重新尝试整个流水线的指定次数。 例如: options { retry(3) }
- timestamps: 预谋所有由流水线生成的控制台输出,与该流水线发出的时间一致。 例如: options { timestamps() }
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
options {
// 指定一个小时的全局执行超时, 在此之后,Jenkins 将中止流水线运行。
timeout(time: 1, unit: 'HOURS')
}
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}
stage 的 options 指令类似于流水线根目录上的 options 指令。然而, stage -级别 options 只能包括 retry, timeout, 或 timestamps 等步骤, 或与 stage 相关的声明式选项,如 skipDefaultCheckout。
- skipDefaultCheckout: 在 agent 指令中跳过默认的从源代码控制中检出代码。例如: options { skipDefaultCheckout() }
- timeout: 设置此阶段的超时时间, 在此之后, Jenkins 会终止该阶段。 例如: options { timeout(time: 1, unit: 'HOURS') }
- retry: 在失败时, 重试此阶段指定次数。 例如: options { retry(3) }
- timestamps: 预谋此阶段生成的所有控制台输出以及该行发出的时间一致。例如: options { timestamps() }
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example') {
options {
// 指定 Example 阶段的执行超时时间, 在此之后,Jenkins 将中止流水线运行。
timeout(time: 1, unit: 'HOURS')
}
steps {
echo 'Hello World'
}
}
}
}
parameters 指令提供了一个用户在触发流水线时应该提供的参数列表。这些用户指定参数的值可通过 params 对象提供给流水线步骤。
- 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 指令定义了流水线被重新触发的自动化方法。对于集成了源( 比如 GitHub 或 BitBucket)的流水线, 可能不需要 triggers ,因为基于 web 的集成很肯能已经存在。 当前可用的触发器是 cron, pollSCM 和 upstream。
- cron: 接收 cron 样式的字符串来定义要重新触发流水线的常规间隔 ,比如: `triggers { cron('H */4 * * 1-5') }`
- pollSCM: 接收 cron 样式的字符串来定义一个固定的间隔,在这个间隔中,Jenkins 会检查新的源代码更新。如果存在更改, 流水线就会被重新触发。例如: `triggers { pollSCM('H */4 * * 1-5') }`
- upstream: 接受逗号分隔的工作字符串和阈值。 当字符串中的任何作业以最小阈值结束时,流水线被重新触发。例如: `triggers { upstream(upstreamProjects: 'job1,job2', threshold: hudson.model.Result.SUCCESS) }`
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
triggers {
cron('H */4 * * 1-5')
}
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}
stage 指令在 stages 部分进行,应该包含一个 实际上, 流水巷所做的所有实际工作都将封装进一个或多个 stage 指令中。
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
}
定义自动安装和放置 PATH 的工具的一部分。如果 agent none 指定,则忽略该操作。
支持工具:maven/jdk/gradle
Jenkinsfile (Declarative Pipeline)
pipeline {
agent any
tools {
maven 'apache-maven-3.0.1'
}
stages {
stage('Example') {
steps {
sh 'mvn --version'
}
}
}
}
stage 的 input 指令允许你使用 input step提示输入。 在应用了 options 后,进入 stage 的 agent 或评估 when 条件前, stage 将暂停。 如果 input 被批准, stage 将会继续。 作为 input 提交的一部分的任何参数都将在环境中用于其他 stage。
- message: 必需的。 这将在用户提交 input 时呈现给用户。
- id: input 的可选标识符, 默认为 stage 名称。
- ok: `input`表单上的"ok" 按钮的可选文本。
- submitter: 可选的以逗号分隔的用户列表或允许提交 input 的外部组名。默认允许任何用户。
- submitterParameter: 环境变量的可选名称。如果存在,用 submitter 名称设置。
- parameters: 提示提交者提供的一个可选的参数列表。 更多信息参见 [parameters]。
Jenkinsfile (Declarative Pipeline)
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 指令包含多个条件, 所有的子条件必须返回True,阶段才能执行。 这与子条件在 allOf 条件下嵌套的情况相同 (参见下面的示例)。
使用诸如 not, allOf, 或 anyOf 的嵌套条件可以构建更复杂的条件结构 can be built 嵌套条件可以嵌套到任意深度。
默认情况下, 如果定义了某个阶段的代理,在进入该stage
的 agent 后该 stage 的 when 条件将会被评估。但是, 可以通过在 when 块中指定 beforeAgent 选项来更改此选项。 如果 beforeAgent 被设置为 true, 那么就会首先对 when 条件进行评估 , 并且只有在 when 条件验证为真时才会进入 agent 。
- branch: 当正在构建的分支与模式给定的分支匹配时,执行这个阶段, 例如: when { branch 'master' }。注意,这只适用于多分支流水线。
- environment: 当指定的环境变量是给定的值时,执行这个步骤, 例如: when { environment name: 'DEPLOY_TO', value: 'production' }
- expression: 当指定的Groovy表达式评估为true时,执行这个阶段, 例如: when { expression { return params.DEBUG_BUILD } }
- not: 当嵌套条件是错误时,执行这个阶段,必须包含一个条件,例如: 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'
}
}
}
}
Jenkinsfile (Declarative Pipeline)
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'
}
}
}
}
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"
}
}
}
}
}
}
Jenkinsfile (Scripted Pipeline)
node {
stage('Example') {
if (env.BRANCH_NAME == 'master') {
echo 'I only execute on the master branch'
} else {
echo 'I execute elsewhere'
}
}
}
Jenkinsfile (Scripted Pipeline)
node {
stage('Example') {
try {
sh 'exit 1'
}
catch (exc) {
echo 'Something failed, I should sound the klaxons!'
throw
}
}
}
声明式流水线的阶段可以在他们内部声明多隔嵌套阶段, 它们将并行执行。 注意,一个阶段必须只有一个 steps 或 parallel 的阶段。 嵌套阶段本身不能包含进一步的 parallel 阶段, 但是其他的阶段的行为与任何其他 stage 相同。 任何包含 parallel 的阶段不能包含 agent 或 tools 阶段, 因为他们没有相关 steps。
另外, 通过添加 failFast true 到包含 parallel 的 stage 中, 当其中一个进程失败时,你可以强制所有的 parallel 阶段都被终止。
Jenkinsfile (Declarative Pipeline)
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"
}
}
}
}
}
}