Skip to content

Jenkins Pipeline核心语法

一、Jenkins Pipeline基础语法

1.1 什么是Pipeline

Pipeline是Jenkins的一个核心特性,Pipeline提供了一组可扩展的工具, 用于将"简单到复杂"的交付流程以代码的形式实现和集成到Jenkins中。 Jenkins在运行Pipeline任务的时候会按照Jenkinsfile中定义的代码顺序执行。 Jenkinsfile类似于Dockerfile,具有一套特定的语法。

1.2 如何使用Pipeline

1.2.1安装Pipeline插件

在创建Pipeline类型的作业的时候,需要提前安装好pipeline插件,不然可能会出现找不到pipeline类型的作业。 进入插件管理, 搜索关键字"pipeline" 。安装后重启一下。 当Jenkins重启成功后,我们创建一个流水线类型的作业。 编写流水线代码

1.3 如何编写/运行Pipeline?

Jenkinsfile是一个文本文件,包含了Jenkins Pipeline的定义。它可以被提交到项目的源代码控制仓库中(Jenkinsfile,比如我们后面要说到的共享库),也可以直接写在Jenkins的配置页面中。 基本示例:

groovy
pipeline {
    agent any
    
    stages {
        stage('Build') {
            steps {
                echo 'Building..'
            }
        }
        stage('Test') {
            steps {
                echo 'Testing..'
            }
        }
        stage('Deploy') {
            steps {
                echo 'Deploying....'
            }
        }
    }
}

  • 构建完成✅
  • 查看构建日志
  • 流水线回放功能

💡Tips

借助回放可以修改上次构建所使用的Jenkinsfile代码, 进行更改后可以立即运行进行调试。

1.4 Pipeline 开发工具

选择任意pipeline类型的作业,点击“流水线语法”即可进入pipeline开发工具页面。

  • 片段生成器 在这里可以找到每个插件以及Jenkins内置的方法的使用方法。有些方法来源于插件,则需要先安装相关的插件才能使用哦。
  • 声明式语法生成器 还是选择任意pipeline类型的作业,点击“流水线语法”即可进入pipeline开发工具页面,选择左侧Declarative Directive Generator
  • 全局变量参考 提供已安装好的Jenkins插件和Jenkins内置的全局变量清单

1.5 Pipeline的基础语法介绍

1.5.1 Pipeline

Pipeline是声明式Pipeline的顶层组件:

groovy
pipeline {
    // 所有的声明式Pipeline内容
}

1.5.2 agent构建节点

Jenkins采用分布式架构,分为server节点和agent节点。server节点也是可以运行构建任务的,一般使其主要来做任务的调度。agent节点专门用于任务的执行。 随着现在容器的盛行,agent节点可以分为静态节点和动态节点。 静态节点是固定的一台vm虚机或者容器。动态节点是随着任务的构建来自动创建agent节点。

  • 参数:
    • any: 运行在任一可用节点。
    • none:当pipeline全局指定agent为none,则每个stage中定义的agent运行(stage必须指定)
    • label:在指定的标签的节点运行。(标签=分组)
    • node:支持自定义流水线的工作目录。
groovy
## 运行在任一可用节点。
pipeline {
	agent any
}

## 在指定的标签的节点运行
pipeline {
	agent { label "label Name" }
}


## 自定义节点
pipeline {
  agent { 
     node {
        label "labelName",
        customWorkspace "/opt/agent/workspace"
     }
  }
}

1.5.3 Stages构建阶段

  • 关系: stages > stage > steps > script
  • 定义:
    • stages:包含多个stage阶段
    • stage:包含多个steps步骤
    • steps: 包含一组特定的脚本 (加上script后就可以实现在声明式脚本中嵌入脚本式语法)
groovy
pipeline {
	agent { label "build" }
  
  stages {
  		stage("build") {
      		steps {
          		echo "hello"
          }
      }
   }
}

💡Tips

扩展:当pipeline全局指定agent为none,在阶段中定义agent

groovy
pipeline {

  agent none 
  
  stages{
  	stage('Build'){
    	agent { label "build" }
        steps {
            echo "building......"
        }
     }
  }
}

1.5.4 Stage

定义概念性的不同的构建阶段:

groovy
stage('Build') {
    steps {
        sh 'make'
    }
}

1.5.5 Post构建后操作

定义Pipeline或stage完成后的操作:

  • 状态:
    • always: 不管什么状态总是执行
    • success: 仅流水线成功后执行
    • failure: 仅流水线失败后执行
    • aborted: 仅流水线被取消后执行
    • unstable:不稳定状态,单侧失败等等
groovy
pipeline {
    
    .....
        
    .....
        
    post {
        always{
            script{
                println("流水线结束后,经常做的事情")
            }
        }
        
        success{
            script{
                println("流水线成功后,要做的事情")
            }
        
        }
        failure{
            script{
                println("流水线失败后,要做的事情")
            }
        }
        
        aborted{
            script{
                println("流水线取消后,要做的事情")
            }
        
        }
    }
}

我们可以根据地铁线路图来理解pipeline :

  • ​pipeline​​:整条地铁 1 号线的「运营体系」(从规划到运行的整体框架)。
  • ​​agent​​:执行运输的「地铁列车」(承载任务运行的载体)。
  • ​​stages​​:地铁 1 号线的「完整站点路线」(从起点到终点的所有站点顺序规划)。
  • ​​stage​​:路线中的「单个站点」对应 Pipeline 中一个具体的任务步骤)。
  • ​​post​​:列车完成「全程运行(所有站点)」后的「收尾操作」(例如:到达终点站后清客、检查车辆状态、为下一班次做准备等)。 南京轨道交通一号线线路图

1.6 声明式管道与脚本式管道

Jenkins Pipeline支持两种语法:声明式(Declarative)和脚本式(Scripted),是两种不同的语法风格,主要区别体现在​​结构化程度​​、​​语法约束​​和​​适用场景​​上。 以下通过具体代码示例和对比说明两者的差异。

1.6.1 声明式Pipeline

  • 强制使用 stages 划分阶段,每个阶段的 steps 必须明确
  • 更严格的语法结构
  • 更容易读写
  • 从Jenkins 2.5开始引入
groovy
pipeline {
  agent any  // 必须指定执行节点
  stages {
    stage('Hello') {  // 必须用 stage 划分阶段
      steps {
        sh 'echo "声明式:Hello World"'  // 步骤必须在 steps 块内
      }
    }
  }
}

1.6.2 脚本式Pipeline

  • 基于Groovy语言
  • 提供更大的灵活性
  • 无强制结构,用 node 替代 agent,步骤更自由
groovy
node {  // 用 node 替代 agent(可选,但通常保留)
  stage('Hi') {  // stage 可选(但习惯保留)
    sh 'echo "脚本式:Hi Jenkins"'  // 步骤直接写,无需 steps 块
  }
  // 直接嵌入 Groovy 逻辑(声明式做不到)
  def msg = '动态消息'
  sh "echo ${msg}"  // 直接拼接变量(声明式需用 env 或特定块)
}

1.6.3 声明式与脚本式核心差异

  • 声明式像「填表格」(必须按 pipeline > agent > stages > steps 结构填写);
  • 脚本式像「写代码」(用 Groovy 自由组合,node/stage/sh 随意嵌套)。

💡Tips

在声明式Pipeline中也可以执行脚本式Pipeline代码:

groovy
script {
    def browsers = ['chrome', 'firefox']
    for (int i = 0; i < browsers.size(); ++i) {
        echo "Testing the ${browsers[i]} browser"
    }
}

二、Pipeline高级语法介绍

2.1 Environment

定义环境变量: 通过键值对key:valued的格式定义流水线在运行时的环境变量, 分为流水线级别和阶段级别。

groovy
pipeline {
    environment {
     	NAME = "srebro"
        base_env = "prod"
    }
}
groovy
pipeline {
.....
.....
    stages{
        stage('Build') {
        environment{
            VERSION="test"
        }
        steps{
            Script {
               echo "${VERSION}"
                }
            }
        }
    }
}

2.2 Options 运行时选项

Pipeline特定选项

groovy
options {

    timeout(time: 1, unit: 'HOURS')     //设定流水线的超时时间(可用于阶段级别)
    disableConcurrentBuilds() //禁止并行构建   
    options { buildDiscarder(logRotator(numToKeepStr: '1')) } //设置构建保留策略,保留最近的记录
    options { skipDefaultCheckout() }   //跳过默认的代码检出
    options { retry(3) }   //设置重试次数(可用于阶段级别)
    options { timestamps() } //设置时间戳输出(可用于阶段级别)
}
  • 案例参考
groovy
pipeline{
    options{
        disableConcurrentBuilds()
        skipDefaultCheckout()
        timeout(time: 1, unit: 'HOURS')
    }
    stages{
        stage('Build') {
            options{
                timeout(time: 3, unit: 'MINUTES')
                retry(3)
                timestamps()
            }
            steps{
                script{
                    ehco "hello"
                }
            }
        }
    }
}

⚠️

如果存在下面的👇报错提示,需要安装插件Timestamper

groovy
WorkflowScript: 21: Invalid option type "timestamps". Valid option types: [authorizationMatrix, buildDiscarder, catchError, checkoutToSubdirectory, disableConcurrentBuilds, disableResume, durabilityHint, lock, overrideIndexTriggers, parallelsAlwaysFailFast, preserveStashes, quietPeriod, rateLimitBuilds, retry, script, skipDefaultCheckout, skipStagesAfterUnstable, timeout, waitUntil, warnError, withChecks, withContext, withCredentials, withEnv, wrap, ws] @ line 21, column 3.
   		timestamps()
     ^

2.3 Parameters流水线参数

  • 定义: 流水线在运行时设置的参数,UI页面的参数。所有的参数都存储在params对象中。
  • 将web ui页面中定义的参数,以pipeline的方式定义。
  • 参数类型:
    • string:字符串参数
    • boolean:布尔参数
    • choice:选择参数
    • password:密码参数
    • text:多行文本参数
    • file:文件参数
    • credentials:凭证参数
    • run :运行参数
    • gitGit Parameter: git参数

groovy
parameters {
    string(name: 'VERSION', defaultValue: 'V1.0.0', description: '版本')
    booleanParam(name: 'DEBUG_BUILD', defaultValue: true, description: '')
    choice(name: 'BUILD_TYPE', choices: ['debug', 'release'], description: '')
    password(name: 'PASSWORD', defaultValue: '123456', description: '密码')
    text(name: 'DESCRIPTION', defaultValue: '描述', description: '')
    file(name: 'FILE', description: '文件')
    credentials(name: 'CREDENTIALS', description: '凭证')
    gitParameter branch: '', branchFilter: '.*', defaultValue: 'main', description: '构建分支', name: 'GIT_BRANCH', quickFilterEnabled: false, selectedValue: 'NONE', sortMode: 'NONE', tagFilter: '*', type: 'GitParameterDefinition' //依赖于 Git Parameter 插件
    run(name: 'RUN', description: '运行')
}

⚠️

配置了parameters流水线参数,需要先构建一次,渲染下流水线的参数化构建

2.4 Triggers

构建触发器:

groovy
triggers {
    cron('H */4 * * 1-5') //cron 定时触发,每周一至周五,每 4 小时触发一次构建(具体分钟由 H 随机确定,避免任务扎堆)
    pollSCM('H */4 * * 1-5')  //轮询代码变更触发构建,含义与上面的 cron 触发器一致,每周一至周五,每 4 小时检查一次代码仓库是否有更新。
}

Demo 案例

groovy
pipeline {
    agent any
    triggers {
        cron('H */7 * * 1-5') //cron 定时触发,每周一至周五,每 7 小时触发一次构建
    }
    stages {
        stage('build') {
            steps {
                echo 'Hello World'
            }
        }
    }
}

2.5 Tools

自动安装和放入PATH的工具,指的是在全局工具配置中配置的工具。

groovy
tools {
    maven 'apache-maven-3.8.1'
    jdk 'jdk11'
}

2.6 Input

人工输入:

  • 可用于人工卡点确认
  • 参数化构建
groovy
pipeline {
    parameters {
      choice choices: ['maven-3.6.3', 'maven-3.9.10'], description: 'maven版本', name: 'maven_version'
    }
	
	agent {
        label "${maven_version}"
    }
	
    stages {
		stage('拉取代码'){
			steps{
                script {
                     checkout scmGit(branches: [[name: '*/main']], extensions: [], userRemoteConfigs: [[credentialsId: 'a11aa99b-7bba-48fd-bd01-46b68732578a', url: 'http://code.srebro.cn/opforge/maven-demo.git']])
                }
			}
		}
		
        stage('打印maven版本') {
            steps {
                sh 'java -version'
                sh 'mvn -v'
            }
        }
		
        stage('构建(maven)') {
            steps {
                script {
                    sh "mvn clean package -Dmaven.test.skip=true"
                }
            }
        }
		
        stage('部署') {
            input {
                message "是否继续发布"
				submitter "alice,bob"
                ok "Yes, we should."
                parameters {
				  choice choices: ['UAT', 'FAT', 'PROD'], description: '选择发布的环境:[UAT/FAT/PROD]', name: 'ENVTYPE'
				}
            }
            steps {
                echo "Deploy to  ${ENVTYPE}, doing......."
            }
        }
    }
}

2.7 When

条件执行:

  • 根据输入的构建参数判断
  • 根据条件判断(not/allOf/anyOf)
groovy
pipeline {
    agent any
	parameters {
    string(name: 'ENVTYPE', defaultValue: 'UAT', description: '选择发布类型:[UAT/FAT/PROD]')
    }
	
    stages {
        stage('Build') {
            steps {
                echo 'build......'
            }
        }
     stage('Deploy') {
            when {
                environment name: 'ENVTYPE', value: 'UAT'
            }
            steps {
                echo 'Deploying.......'
            }
        }
    }
}

when 其他条件
groovy
###  allOf 条件全部成立
 when {
     allOf {
         environment name: 'NODE_AGENT', value: 'slave'
         environment name: 'DEPLOY_ENV', value: 'prod'
     }
 }


### anyOf 条件其中一个成立
when {
     anyOf {
         environment name: 'NODE_AGENT', value: 'slave'
         environment name: 'DEPLOY_ENV', value: 'dev'
     }
 }

2.8 Script

在声明式Pipeline中执行脚本式Pipeline代码:

groovy
script {
    def browsers = ['chrome', 'firefox']
    for (int i = 0; i < browsers.size(); ++i) {
        echo "Testing the ${browsers[i]} browser"
    }
}

2.9 parallel 阶段并行

场景: 自动化测试,多主机并行发布。

groovy
pipeline {
    agent any
    stages {
        stage('Parallel Stage') {
            failFast true
            parallel {
                stage('windows') {
                    agent {
                        label "master"
                    }
                    steps {
                        echo "windows"
                    }
                }
                stage('linux') {
                    agent {
                        label "build"
                    }
                    steps {
                        echo "linux"
                    }
                }
            }
        }
    }
}

⚠️

FAQ:如何解决并发构建中的同一节点,workspace问题?

groovy
env.nworkspace = "/home/application/${JOB_NAME}-${UUID.randomUUID().toString()}"


pipeline{
	agent{
  	node{
    	label "build"
      customWorkspace "${env.nworkspace}"
    }
  }
 
  stages{
  	stage("build"){
    
    	steps{
      	echo "${env.nworkspace}"
      }
    }
  
  }
}

三、全局变量参考

在流水线语法中,可以参考到全局环境变量的使用

3.1 内置全局变量

这些变量由 Jenkins 核心系统自动生成,无需额外配置,适用于所有类型的流水线(声明式/脚本式)。

变量名类型描述
BUILD_NUMBER字符串当前构建的唯一编号(从 1 开始递增,重启 Jenkins 后可能重置)。
BUILD_ID字符串当前构建的唯一标识符(默认格式为 YYYYMMDD-HHMMSS,可通过系统配置修改)。
BUILD_DISPLAY_NAME字符串构建的显示名称(默认格式为 #${BUILD_NUMBER},可通过系统配置自定义)。
JOB_NAME字符串当前任务(Job)的名称(不含工作区路径)。
JOB_BASE_NAME字符串JOB_NAME 去除后缀后的基础名称(若任务是通过“复制”创建的,可能包含 -copyN)。
BUILD_TAG字符串构建的标签(默认格式为 jenkins-${JOB_NAME}-${BUILD_NUMBER})。
BUILD_URL字符串当前构建的完整 URL 地址(可用于访问 Jenkins 构建详情页)。
WORKSPACE字符串当前任务的工作区路径(绝对路径,用于访问代码或临时文件)。
NODE_NAME字符串当前执行构建的 Agent 节点名称(如 master 或自定义节点名)。
BUILD_STATUS字符串当前构建的状态(仅在构建完成后有效)。
CAUSE字符串触发当前构建的原因(如手动触发、定时触发、SCM 轮询触发等)。
USER_NAME字符串触发构建的用户名称(若为定时触发则为 SYSTEM)。

3.2 currentBuild 变量(构建实例对象)​

currentBuild 是 Jenkins 流水线中的内置变量,类型为 Run(表示当前构建的实例对象),用于获取构建的详细元数据(如构建号、结果、时间戳、参数等)。

属性名类型描述
number整数(Integer)当前构建的编号(从 1 开始递增)。
result字符串(String)构建结果(仅构建完成后有效):
- SUCCESS(成功)
- FAILURE(失败)
- UNSTABLE(不稳定)
- 构建进行中时为 null。
currentResult字符串(String)构建结果(始终非空):
- SUCCESS、UNSTABLE、FAILURE(即使构建未完成,默认返回 SUCCESS?需验证)。
displayName字符串(String)构建的显示名称(默认格式为 #${BUILD_NUMBER},可自定义)。
fullDisplayName字符串(String)完整显示名称(包含父任务路径),格式为 folder1 » folder2 » foo #123。
projectName字符串(String)当前构建所属项目的名称(不含路径)。
fullProjectName字符串(String)当前构建所属项目的完整名称(含父文件夹路径)。
description字符串(String)构建的附加描述(可通过脚本或插件设置)。
id字符串(String)构建的唯一 ID(默认与 BUILD_NUMBER 一致)。
externalizableId字符串(String)构建的全局唯一标识符(格式为 fullProjectName#number)。
timeInMillis长整型(Long)构建计划启动时间的毫秒时间戳(自 Unix 纪元起)。
startTimeInMillis长整型(Long)构建实际开始运行时间的毫秒时间戳。
duration长整型(Long)构建持续时间(毫秒,仅构建完成后有效)。
durationString字符串(String)构建持续时间的可读格式(如 5 min 0 sec)。
absoluteUrl字符串(String)构建详情页的完整 URL 地址。
keepLog布尔型(Boolean)标记是否保留构建日志(true 表示保留,否则可能被清理)。
changeSets列表(List)来自不同 SCM 检出的变更集列表,每个变更集包含提交记录(commitId、timestamp、msg、author、affectedFiles 等)。
注意:非 @NonCPS 方法中不可序列化访问。
upstreamBuilds列表(List)上游项目的构建列表(其产物作为当前构建的输入)。
buildVariables映射(Map)非 Pipeline 下游构建的构建变量映射;Pipeline 下游构建为结束时 env 中的全局变量(不包含构建参数)。
注意:子 Pipeline 可通过此属性向父 Pipeline 传递变量。
rawBuild对象(hudson.model.Run)底层 Jenkins 的 Run 对象(提供更多原生 API)。
注意:仅在信任库或管理员沙盒外脚本中访问,且不可序列化(需在 @NonCPS 方法中使用)。

demo 演示

groovy
println(env)

env.branchName = "develop"
env.commitID = "${UUID.randomUUID().toString()}"
env.commitID = "${env.commitID.split("-")[0]}"
currentBuild.displayName = "#${env.branchName}-${env.commitID}"
currentBuild.description = "Trigger by user jenkins \n branch: master"

pipeline {

    agent { label "master"}

  stages {
    stage('打印全局变量') {
      steps {
        script {
          // 打印内置变量
          echo "BUILD_NUMBER: ${env.BUILD_NUMBER}"
          echo "JOB_NAME: ${env.JOB_NAME}"
          echo "WORKSPACE: ${env.WORKSPACE}"

          // 打印 currentBuild 属性
          echo "当前构建号: ${currentBuild.number}"
          echo "构建结果: ${currentBuild.result}"  // 仅在构建完成后有值
          echo "构建开始时间(秒): ${currentBuild.startTimeInMillis / 1000}"
        }
      }
    }
  }
}

3.3 流水线中变量定义引用

变量的类型:两种类型的变量。

  • Jenkins系统内置变量 (全局变量)
  • Pipeline中自定义变量(全局/局部变量)

3.3.1 Jenkins系统内置变量引用

  • 双引号字符串

变量会被解析(👍推荐)

示例:echo "当前构建编号:${BUILD_NUMBER}"echo "工作区路径:$WORKSPACE"

  • 单引号字符串

变量不会被解析(仅作为字面量)

示例:sh 'echo 单引号中的变量不会解析:$BUILD_NUMBER'(输出字面量$BUILD_NUMBER)。

  • 脚本块(Script Block)

script标签或sh/bat步骤中,可直接使用变量。

TIP

内置变量的值由Jenkins运行时动态生成,无法手动修改。

3.3.2 Pipeline中自定义变量

Pipeline中自定义变量是用户根据需求手动定义的变量,用于存储临时数据或业务逻辑中的中间值。根据作用域可分为​​局部变量​​和​​全局变量​​。

3.3.2.1 局部变量

局部变量仅在特定作用域(如某个step、stage或script块)内有效,超出作用域后无法访问。

定义方式

  • 使用def关键字声明(适用于声明式流水线的steps或脚本式流水线)。
groovy
pipeline {
    agent any
    stages {
        stage('示例') {
            steps {
                def localVar = '我是局部变量'  // 仅在当前step内有效
                echo "局部变量值:$localVar"    // 正常输出
            }
            post {
                success {
                    echo "Post中访问局部变量:$localVar"  // 报错:变量未定义
                }
            }
        }
    }
}
  • 在script块中使用(脚本式语法,作用域同上)
groovy
script {
    def scriptVar = '脚本块内的变量'
    echo "Script块内:$scriptVar"  // 有效
}
echo "Script块外:$scriptVar"    // 报错
3.3.2.2 全局变量​

全局变量在整个流水线中共享,可在多个stage或step中访问。常见定义方式有两种:

(1) 使用environment块(👍推荐)​​

groovy
pipeline {
    agent any
    environment {
        GLOBAL_VAR = '全局环境变量'       // 字符串类型
        NUM_VAR = 123                   // 数字类型(实际存储为字符串,需转换)
        BOOL_VAR = true                 // 布尔类型(需注意脚本中的类型判断)
    }
    stages {
        stage('Stage1') {
            steps {
                echo "Stage1访问全局变量:$GLOBAL_VAR"  // 输出:全局环境变量
                sh 'echo Shell中访问:${GLOBAL_VAR}'   // Shell脚本中需用${}显式引用
            }
        }
        stage('Stage2') {
            steps {
                echo "Stage2访问全局变量:${GLOBAL_VAR}"  // 跨stage仍有效
            }
        }
    }
}

WARNING

  • environment块只能定义在pipeline顶层或stage内(若在stage内定义,仅该stage及其子步骤有效)。
  • 变量值为字符串类型(即使赋值为数字或布尔值),在需要数值的场景(如条件判断)中需显式转换(如${NUM_VAR.toInteger()})。

​(2) 使用env对象动态赋值​​

groovy
pipeline {
    agent any
    stages {
        stage('动态设置全局变量') {
            steps {
                env.DYNAMIC_VAR = '动态赋值的全局变量'  // 直接操作env对象
            }
        }
        stage('跨stage访问') {
            steps {
                echo "访问动态变量:${env.DYNAMIC_VAR}"  // 输出:动态赋值的全局变量
            }
        }
    }
}

变量作用域总结​

变量类型定义方式作用域范围是否支持跨Stage访问
局部变量def关键字当前step或script块内
全局环境变量environment块或env对象整个流水线(或stage内)是(顶层environment)

总结 Jenkins流水线中的变量分为内置变量(系统预定义)和自定义变量(手动定义)。内置变量用于获取流水线元数据,自定义变量用于业务逻辑数据传递。使用时需注意作用域(局部/全局)和引用方式(双引号解析、Shell语法适配),避免因作用域或类型问题导致流程错误。

最近更新

采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 运维小弟