文章目录
- [Pipeline job](#Pipeline job)
- Pipline语法
-
- 声明式Pipeline的结构(区块、指令、步骤)
-
- Pipeline支持的指令
- [Section: agent](#Section: agent)
- [Section: post](#Section: post)
- [Section: stages和steps](#Section: stages和steps)
- Pipeline内置的常用step
- Pipline的常用步骤
- stages和stage
- Pipeline代码片段生成器
- Pipline应用
-
- [在Pipline Job上使用环境变量](#在Pipline Job上使用环境变量)
- [在Pipline Job 的step中使用认证凭据](#在Pipline Job 的step中使用认证凭据)
- [在Pipline Job中构建和推送Docker image](#在Pipline Job中构建和推送Docker image)
- 参数化Pipeline
- 实现交互式功能
- 输入等待超时
Pipeline job
Pipeline是什么
从某种抽象层次上讲,部署流水线(Deployment pipeline)是指从软件版本控制库到用户手中这一过程的自动化表现形式
Jenkins原本就支持pipeline,只不过最初该功能被称为"任务"
- Jenkins 1.x仅支持界面手动配置流水线(Freestyle Job),而2.x则实现了"流水线即代码"(pipeline as a code)
- 使用代码而非UI完成pipeline定义的意义在于
- 更好地版本化:支持版本控制
- 更好地协作:pipeline的修改对所有人可见,支持代码审查
- 更好的可重用性
在Jenkins 2.x中,用于保存pipeline代码并可被Jenkins加载的文件称为Jenkinsfile;
-
流水线既可以在pipeline类型的任务中创建,也可以定义在一个称为Jenkinsfile的外部文件中,它可以同代码
保存在一起
-
Jenkinsfile就是一个文本文件,它是部署流水线概念在Jenkins中的表现形式
流水线语法初步(脚本式、声明式)
Jenkins 2.x支持两种pipeline语法:脚本式语法 和声明式语法
-
脚本式语法:没有固定关键字,纯用 Groovy 语法写,想加什么逻辑就加什么;
-
声明式语法:格式固定,用
pipeline、agent、stages、stage、steps这些固定关键字,像填表格一样写;
groovy
//脚本式流水线: node用于脚本式流水线,从技术层面上来说
//它是一个步骤,代表可以用于流水线中执行活动的资源
node('node01') {
stages {
stage('Build') {
steps {
echo 'Building...'
}
}
stage('Test') {
steps {
echo 'Testing...'
}
}
}
}
//声明式流水线:agent用于声明式流水线,它作为一个指令用于分配节点;
pipeline {
agent {
label 'node01' // 节点标签,对应 Jenkins 中配置的节点名称
}
stages {
stage('Build') {
steps {
echo 'Building...'
}
}
stage('Test') {
steps {
echo 'Testing...'
}
}
}
}
Pipeline的组成
- pipeline实际上就是基于Groovy语言实现的一种DSL(Domain-Specific Language),用于描述代码编译到打包发布的整个流水线是如何进行的
- 一个标准pipeline流水线基本组成元素
| 元素名称 | 核心角色 | 是否必选 | 关键说明 |
|---|---|---|---|
| pipeline | 流水线最外层结构 | 是 | 包裹整条流水线的完整逻辑,是声明式 Pipeline 的固定入口,所有配置需嵌套其中 |
| stages | 所有功能阶段(stage)的容器 流水线中只允许有一个stages | 是 | 用于统一管理多个 stage,确保流水线按阶段顺序执行(不可单独存在,需嵌套在 pipeline 内) |
| stage | 流水线的独立功能阶段(如编译、测试、部署) | 是 | 每个 stage 对应一个具体功能,需嵌套在 stages 内,可包含 steps、post 等子配置 |
| steps | 单个 stage 内的具体执行步骤集合 | 是 | 定义完成该阶段功能的操作(如 sh 执行 Shell 命令、echo 输出日志),与其他配置分隔 |
| agent | 指定流水线的执行位置 | 是 | 分配执行资源(物理机、虚拟机、容器等),通过 label 关联 Jenkins 节点(如 agent { label 'node01' }) |
| post | 流水线 / 单个 stage 执行完成后的附加步骤(如通知、清理) | 否 | 唯一可省略的核心元素,但实际应用中建议配置(如执行成功 / 失败的告警、工作目录清理) |
创建一个pipeline项目
创建pipeline项目时,将首先打开一个基于Web表单形式的新项目配置页面
-
每个主要的配置部分都有一个对应的选项卡
-
底部还会有一个用于输入pipeline code的文本框,这是Jenkins内置的流水线编辑器

Pipline基础及代码示例
groovy
pipeline {
agent any
stages {
stage('Hello') {
steps {
echo 'Hello World'
}
}
}
}
通过左边菜单中的"Build Now"便可触发pipeline的一次运行

- 蓝色条纹:运行中
- 白色:stage尚未执行
- 红色条纹:steps执行失败
- 绿色:stage执行成功
- 浅红色:stage执行成功,但是下游某个stage出现失败
Pipline语法
声明式Pipeline的结构(区块、指令、步骤)
groovy
pipeline{
agent any
stages{
stage('<stage_name>'){
steps{...}
}
}
}
Pipeline声明结构由区块 和指令 组成,每一个区块 又可包含其他的区块 、指令 和步骤 ,以及一些条件的定义
| 类型 | 核心定义 | 作用说明 | 具体示例 |
|---|---|---|---|
| Section(区块) | 用于将某一个时间点需一同运行的条目组织在一起 | 划分 Pipeline 的功能模块,明确不同逻辑单元的执行范围和关联关系 | 1. agent:指定运行代码的节点(如 agent { label 'node01' }) 2. stages:组织所有 stage(如 stages { stage('Build') { ... } }); 3. steps:组织具体执行步骤(如 steps { sh 'mvn package' }); 4. post:封装 stage/pipeline 执行后的步骤(如 post { success { echo '执行成功' } }) |
| Directive(指令) | 负责完成特定功能的语句或代码块 | 提供 Pipeline 的核心配置能力(如环境变量、工具依赖、触发条件等),支撑流程控制 | 1. environment:定义环境变量(如 environment { JAVA_HOME = '/usr/lib/jvm/java-11' }); 2. tools:指定工具及版本(如 tools { maven 'maven-3.8' }); 3. triggers:配置触发方式(如 triggers { cron('H 2 * * *') }); 4. input:设置人工确认步骤(如 input message: '是否继续部署?'); 5. when:定义 stage 执行条件(如 when { branch 'master' }) |
| Steps(步骤) | 标识特定 区块 的名称,内部可包含任何合法的 DSL 语句,是 Pipeline 的执行单元 | 承载具体业务操作,是 Pipeline 的核心执行逻辑(如代码拉取、编译、部署等) | 1. git:拉取代码(git url: 'xxx.git', branch: 'master'); 2. sh/bat:执行 Shell/Batch 命令(sh 'docker build -t app:v1 .'); 3. echo:输出日志(echo '开始编译'); 4. junit:解析测试报告(junit 'target/surefire-reports/*.xml') |

Pipeline支持的指令
Jenkins Pipeline支持指令主要有如下这些
| 指令名称 | 核心功能 | 使用范围 | 关键特性 | 实操示例(精简语法) |
|---|---|---|---|---|
| environment | 定义环境变量,支持 credentials () 引用 Jenkins 凭证 | pipeline/stage 级别 | 全局 / 阶段复用,凭证安全无明文 | 全局:APP_NAME='my-app'、DB_PWD=credentials ('db-cred');阶段:environment { BUILD_PATH='target' } |
| tools | 指定 Maven/JDK/Git 等工具,自动加入 PATH 可直接调用 | pipeline/stage 级别 | 需提前在 Jenkins "全局工具配置" 定义,支持阶段差异化版本 | 全局:tools {jdk 'jdk-11'};阶段:tools { maven '3.8.8' },步骤直接用:java -version |
| parameters | 触发时用户输入参数(字符串 / 选择 / 布尔等) | 仅 pipeline 级别 | 动态传参,支持多参数类型 | parameters { choice('DEPLOY_ENV', ['dev','test','prod']);string('VERSION', 'v1.0') } |
| options | 流水线全局配置(重试 / 超时 / 日志等),支持插件扩展 | 仅 pipeline 级别 | 控制运行规则,需对应插件(如 timestamps) | options { retry(2);timeout(45, 'MINUTES');timestamps();disableConcurrentBuilds() } |
| triggers | 自动触发(定时 / 代码轮询),与 Webhook 互补 | 仅 pipeline 级别 | 无需手动触发,Webhook 场景可省略 | triggers { cron('H 3 * * *');pollSCM('H/30 * * * *') } |
| libraries | 导入共享库,复用通用逻辑(部署脚本 / 工具类) | 仅 pipeline 级别 | 需提前配置共享库,支持指定分支 / 版本 | 开头:@Library ('common-lib@main') _,步骤调用:deployToEnv (app:'my-app', env:'prod') |
| stage | 封装功能阶段,包含 steps 及 when/input 等指令 | 仅 stages 段内 | 核心功能单元,支持嵌套 stage | stage('Build&Test') { stages { stage('Compile') { sh 'mvn compile' } } } |
| input | 暂停流水线,需用户输入 / 确认后继续(stage 专用) | 仅 stage 级别 | 人工干预(如生产审核),支持超时配置 | input (message:' 确认部署生产?', timeout:5, 'MINUTES'),之后执行:sh 'prod-deploy.sh' |
| when | 设定 stage 运行条件,满足才执行(stage 专用) | 仅 stage 级别 | 支持分支 / 参数等条件,可多条件组合 | when { allOf { branch 'master';params.DEPLOY_ENV == 'prod' } } |
Section: agent
| 参数类型 | 核心说明 | 使用场景 | 实操示例(精简语法) |
|---|---|---|---|
| any | 匹配任意可用节点,是最常用的默认配置 | 无需指定特定节点,流水线可在任意节点执行 | pipeline { agent any; stages { ... } }(pipeline 顶端默认配置) |
| none | pipeline 顶端使用时,不定义默认 agent; 需为每个 stage 单独指定 agent | 不同 stage 需在完全不同节点执行(无通用节点) | pipeline { agent none; stages { stage('Build') { agent { label 'build' } ... } } } |
| label | 匹配带有指定标签的节点(节点标签需提前在 Jenkins 配置) | 需固定节点环境(如 "编译节点""部署节点") | pipeline { agent { label 'build-node-01' }; ... }(全局)或 stage { agent { label 'deploy-node' } }(stage 单独指定) |
| node | 功能同 label,额外支持指定自定义工作目录(customWorkspace) | 需固定节点 + 自定义工作目录(如单独存储构建文件) | agent { node { label 'test-node'; customWorkspace '/data/jenkins/workspace' } } |
| docker | 在动态创建的容器中执行,需指定镜像;可匹配 label 节点或预配置容器节点 | 容器化部署、环境一致性要求高(避免节点依赖冲突) | agent { docker { image 'maven:3.8.8'; label 'docker-node'; args '-v /tmp:/tmp' } } |
| dockerfile | 基于指定 Dockerfile 构建镜像,再在容器中执行;要求 Jenkinsfile 从 SCM 加载 | 需自定义容器镜像(非公共镜像),多分支流水线场景 | agent { dockerfile { filename 'Dockerfile'; dir './docker'; label 'build-node' } } |
| kubernetes | 在 K8s 集群的 Pod 中执行;要求 Jenkinsfile 从 SCM 加载,需指定 Pod 模板 | K8s 环境部署、微服务集群场景 | agent { kubernetes { yaml '''apiVersion: v1; kind: Pod; spec: { containers: [{ name: 'maven', image: 'maven:3.8.8' }] }''' } } |
官方文档:https://www.jenkins.io/doc/book/pipeline/syntax/
Section: post
post section在stage或pipeline的尾部定义一些step,并根据其所在stage或pipeline的完成情况来判定是否运行这些step;
| Condition(条件) | 触发规则 | 使用场景 | 实操示例(精简语法) |
|---|---|---|---|
| always | 无论 stage/pipeline 状态如何(成功 / 失败 / 中止),必运行 | 清理资源、通用通知 | pipeline 级:post {always { sh 'rm -rf /tmp/build/*'} };stage 级:post { always { echo "Test 阶段结束" } } |
| changed | 本次与前一次运行状态不同(如前败→今成、前成→今败) | 状态变更告警 | post {changed { echo "流水线状态变更!前次 vs 本次不同"} } |
| fixed | 本次成功,前一次为失败(failed)或不稳定(unstable) | 故障恢复通知 | post {fixed { echo "构建恢复成功!前次失败已修复"} } |
| regression | 前一次成功,本次为失败 / 不稳定 / 中止 | 构建回退告警 | post {regression { echo "构建回退!前次成功,本次异常"} } |
| aborted | 运行被手动中止(Web UI 点击 "中止") | 中止记录、通知负责人 | stage ('Deploy') { post { aborted { echo "部署被中止,负责人:${BUILD_USER}" } } } |
| failure | 运行状态为失败(脚本报错、命令执行失败) | 失败告警、上报故障 | post {failure { sh'send-alert.sh "流水线失败,构建号:${BUILD_NUMBER}"' } } |
| success | 运行状态为成功(无报错,步骤正常完成) | 成功通知、成果归档 | post { success { sh 'cp target/app.war /data/archive/' } } |
| unstable | 测试失败 / 代码冲突,状态为 "不稳定"(Web UI 黄色标识) | 不稳定告警、提醒修复 | post {unstable { echo "流水线不稳定!存在测试失败 / 代码冲突"} } |
| unsuccessful | 非成功状态(失败 + 不稳定 + 中止,等价于!success) | 非成功统一处理(记录日志) | post {unsuccessful { echo "构建异常,日志路径:${WORKSPACE}/logs" } } |
| cleanup | 所有 post 条件执行完毕后,最后运行(无论任何状态) | 最终清理(关容器、删临时文件) | post {success { echo "构建成功"}; cleanup { sh 'docker stop test-container' } } |
Section: stages和steps
| 核心概念 | 核心作用 | 关键说明 |
|---|---|---|
| stages | 封装 pipeline 主体和逻辑的所有 stage 定义,描述 pipeline 中绝大部分实际工作 | 至少需包含一个 stage 指令,用于定义 CD 过程的离散部分(如构建、测试、部署等) |
| steps | 在 stage 中定义一到多个 DSL 语句,完成该 stage 特定功能,是 pipeline 最核心的组成部分 | 1. 除 script 外,几乎是不可拆分的原子操作; 2. 内置大量 step,参考https://www.jenkins.io/doc/pipeline/steps; 3. 部分插件可直接当作 step 使用; 4. script {} 可引入脚本(非必要),复杂脚本应组织为 Shared Libraries 并导入使用; 5. DSL 语句可与 environment 等其他语句分隔开 |
官方文档:https://www.jenkins.io/doc/pipeline/steps/

Pipeline内置的常用step
文件 / 目录相关
| step 名称 | 核心作用 | 关键说明 |
|---|---|---|
| deleteDir | 删除当前目录 | 无额外参数,直接执行删除操作 |
| dir("/path/to/dir") | 切换到指定目录 | 参数为目标目录路径,用于指定后续操作的工作目录 |
| fileExists ("/path/to/dir") | 判断文件或目录是否存在 | 参数为目标文件 / 目录路径,返回布尔值结果 |
| isUnix | 判断当前系统是否为类 Unix 系统 | 无参数,返回布尔值结果 |
| pwd | 打印当前工作目录 | 无参数,输出当前所在的工作目录路径 |
| writeFile | 将指定内容写入目标文件 | 参数包括:file(文件路径,支持相对 / 绝对路径)、text(待写入内容)、encoding(目标文件编码,可选,空值为系统默认,支持 base64) |
| readFile | 读取指定文件的内容 | 参数包括:file(文件路径,支持相对 / 绝对路径)、encoding(读取时使用的编码格式,可选) |
消息或控制
| step 名称 | 核心作用 | 关键说明 |
|---|---|---|
| echo("message") | 打印指定的消息 | 参数为待打印的消息内容 |
| error("message") | 主动报错,并中止当前 pipeline | 参数为报错消息内容 |
| retry(count){} | 重复执行指定次数的代码块 | 参数 count 为执行次数,{} 内为待重复执行的代码块 |
| sleep | 让 pipeline 休眠一段时间 | 参数包括:time(整数值,休眠时长)、unit(时间单位,可选,支持 NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS、MINUTES、HOURS、DAYS) |
| timeout | 限制代码块的超时时长 | 参数包括:time(整数值,超时时长)、unit(时间单位,可选,支持 NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS、MINUTES、HOURS、DAYS)、activity (optional)(布尔类型,true 时无日志活动才算超时) |
| waitUntil | 等待指定条件满足后执行代码块 | 参数包括:initialRecurrencePeriod (optional)(初始重试周期,默认 250ms)、quiet (optional)(是否禁止条件测试日志,默认 false,记入日志),{} 内为待执行代码块 |
发送通知
| step 名称 | 核心作用 | 关键说明 |
|---|---|---|
| 向指定邮箱发送邮件 | 参数包括:subject(邮件标题)、body(邮件正文)、from (optional)(发件人地址列表,逗号分隔)、cc (optional)(抄送地址列表,逗号分隔)、bcc (optional)(密送地址列表,逗号分隔)、charset (optional)(编码格式)、mimeType (optional)(正文 MIME 类型,默认 text/plain)、replyTo (optional)(回件地址,默认 Jenkins 全局配置邮箱) |
Pipline的常用步骤
| step 名称 | 核心作用 | 关键说明 |
|---|---|---|
| sh | 运行 shell 脚本 | 参数包括: ◆ 如果有多个命令需要执行可以使用sh ''' 命令 ''' ◆ script {}:脚本代码块,支持指定脚本解释器(如 "#!/usr/bin/perl"),未指定则使用系统默认解释器,且默认启用 - xe 选项; ◆ encoding (optional):脚本输出日志的编码格式,未定义时使用系统默认; ◆ label (optional):Web UI 中显示的详细描述信息; ◆ returnStdout (optional):布尔型,true 时标准输出作为 step 返回值(不打印到日志),错误仍记入日志; ◆ returnStatus (optional):布尔型,true 时返回 step 执行结果而非状态码,命令执行失败也不返回非零状态码 |
| bat | 执行 Windows 的批处理脚本 | 无额外参数说明,直接运行批处理命令或脚本 |
| node | 在指定的节点上运行后续脚本 | 参数为目标节点标识,用于指定 Pipeline 后续操作的执行节点 |
| ws | 为 Pipeline 分配工作空间 | 无额外参数说明,用于指定或分配 Pipeline 执行的工作目录空间 |
| powershell | 运行指定的 PowerShell 脚本 | 支持 Microsoft PowerShell 3 及以上版本 |
| pwsh | 运行 PowerShell Core 脚本 | 专门用于执行 PowerShell Core 相关脚本 |
stages和stage
| 维度 | 具体内容 |
|---|---|
| 核心作用 | Pipeline 中最重要的 section,描述绝大部分实际工作,定义 CD 过程的离散部分(如构建、测试、部署等) |
| 运行顺序 | 按照内部定义的顺序自下而后执行各个 stage |
| 嵌套规则 | 1. 单个 stage 内部可嵌套 stages {}:内部 stage 以串行(顺序) 方式运行; 2. 单个 stage 内部可嵌套 parallel {}:内部 stage 以并行方式运行 |
| 注意事项 | 1. stage 内部仅能定义 steps、stages、parallel 或 matrix 四者之一; 2. 多层嵌套仅能用于最后一个 stage; 3. 已嵌套在 parallel 或 matrix 内部的 stage,不可再嵌套 parallel 或 matrix; 4. 上述嵌套场景下的 stage,仍可使用 agent、tools、when 等指令,也可嵌套 stages {} 以顺序运行子 stage |
Pipeline代码片段生成器
指令配置段生成器能够帮助用户生成配置指令,包括agent、stages等

Pipline应用
在Pipline Job上使用环境变量
| 核心维度 | 具体内容 |
|---|---|
| 变量分类 | 1. 内置变量(Jenkins 自带); 2. 用户自定义变量(用户手动定义) |
| 定义指令 | 统一使用 environment 指令,定义位置决定作用域 |
| 作用域规则 | 1. 定义在 pipeline{} 顶部:作用域为整个 Pipeline,所有 stage 均可引用; 2. 定义在 stage{} 内部:作用域仅为当前 stage,其他 stage 无法引用; 3. Jenkins 全局环境变量:作用域为所有 Pipeline,默认以 env. 为前缀 |
| 全局变量引用格式 | 1. ${env.<ENV_VAR_NAME>}(推荐,最规范); 2. $env.<ENV_VAR_NAME>;3. ${ENV_VAR_NAME}(简洁,常用) |
groovy
pipeline {
agent any
environment {
APP_NAME = 'my-app'
BUILD_INFO = "构建编号: ${env.BUILD_NUMBER} | 分支: ${env.GIT_BRANCH}"
}
stages{
stage('测试全局变量'){
steps{
echo "引用自定义全局变量: ${APP_NAME}"
echo "引用内置全局变量(格式1): ${env.BUILD_URL}"
echo "引用内置全局变量(格式2): $env.JOB_NAME"
echo "拼接全局变量: ${BUILD_INFO}"
}
}
stage('测试stage局部变量'){
environment{
STAGE_TAG = 'test-001'
}
steps {
echo "引用当前stage局部变量:${STAGE_TAG}"
echo "当前stage仍可引用全局变量:${APP_NAME}"
}
}
}
}
执行结果

在Pipline Job 的step中使用认证凭据
| 凭据类型 | 关键参数 / 说明 |
|---|---|
| Username with password(用户名 + 密码) | 脚本式:credentialsId(凭据 ID)、usernameVariable(用户名变量)、passwordVariable(密码变量) 声明式:变量值自动格式化为 用户名:密码,直接用于需要组合认证的场景 |
| SSH 密钥 | 1.脚本式:keyFileVariable(私钥文件路径)、passphraseVariable(密钥口令)、usernameVariable(SSH 用户名) sshagent():直接传入 credentialsId 列表,自动管理 SSH 代理(推荐) |
| Secret text(秘文) | credentialsId、variable(秘文变量名) 适用于 API 令牌、机器人 Token 等单一字符串秘钥 |
| Secret file(秘文文件) | credentialsId、variable(秘文文件路径变量) 适用于证书、kubeconfig、配置文件等文件类秘钥 |
Git拉取Gitlab代码(SSH密钥)
git拉取操作官方文档:https://www.jenkins.io/doc/pipeline/steps/git/#git-git
groovy
pipeline {
agent any //任意Jenkins节点都能跑
environment{
//仓库地址
GIT_URL = "git@gitlab.chenshiquan.xyz:root/docker-java-hello.git"
//引用内置变量,构建号
BUILD_INFO = "这次构建编号是: ${BUILD_NUMBER}"
}
stages{
//步骤1.拉取代码
stage('拉代码'){
steps{
echo "${BUILD_INFO}" //打印构建号
git(
url: "${GIT_URL}", //URL
branch: "master", //拉取主分支代码
credentialsId: "71751bf3-bc66-48b1-8d7a-7ff7c0ee5c71" //凭据ID
)
echo "代码拉取完成!"
}
}
//步骤2: 简单构建
stage('构建'){
steps{
echo "工作目录是: ${env.WORKSPACE}" //工作目录(内置变量)
sh "echo 构建成功" //使用简单shell命令模拟构建成功
}
}
}
}

Docker登陆Harbor仓库(用户名+密码)
将凭据绑定为变量文档:www.jenkins.io/doc/pipeline/steps/credentials-binding/
场景:Docker 登录 Harbor 仓库
groovy
pipeline {
agent any
environment{
HARBOR_URL = 'harbor.chenshiquan.xyz'
}
stages{
stage('登陆Harbor仓库'){
steps{
withCredentials([
usernamePassword(
//将账号设置为变量
usernameVariable: 'HARBOR_USER',
//将密码绑定为变量
passwordVariable: 'HARBOR_PWD',
//凭证ID用于判断是哪个凭证
credentialsId: 'harbor-key'
)
]){
//密码自动隐藏,日志不会泄露
sh "docker login -u ${HARBOR_USER} -p ${HARBOR_PWD} ${HARBOR_URL}"
}
echo "Harbor登陆成功"
}
}
}
}

调用钉钉机器人发送通知(密钥文本)
https://jenkinsci.github.io/dingtalk-plugin/guide/pipeline.html
Secret text(密钥文本)
场景:调用钉钉机器人发送通知
groovy
pipeline {
agent any
stages {
stage('钉钉通知') {
steps {
withCredentials([string(
credentialsId: 'dingtalk-robot-token', //凭证ID
variable: 'DING_TOKEN' //凭证TOKEN
)]) {
//调用API发送消息
sh '''
curl -X POST "https://oapi.dingtalk.com/robot/send?access_token=${DING_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"msgtype":"text","text":{"content":"hello!"}}'
'''
//content发送消息的内容
}
echo "钉钉通知已发送!"
}
}
}
}

凭证优雅用法
场景:整合凭据到环境变量,全局复用
groovy
pipeline {
agent any
// 直接在environment中定义凭据变量,全局可用
environment {
DING_TOKEN = credentials('dingtalk-robot-token') // Secret text类型
HARBOR_CRED = credentials('harbor-key') // Username with password类型(变量为"用户名:密码"格式)
}
stages {
stage('测试全局凭据变量') {
steps {
// 钉钉通知(直接使用环境变量)
sh '''
curl -X POST "https://oapi.dingtalk.com/robot/send?access_token=${DING_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"msgtype":"text","text":{"content":"hello!测试全局变量"}}'
'''
}
}
}
post {
success {
echo "凭据变量自动掩码:${DING_TOKEN}" // 输出时自动显示为****
}
}
}

在Pipline Job中构建和推送Docker image
事前准备(必须先搞定这 3 件事)
| 准备项 | 作用 | 简单要求(一看就懂) |
|---|---|---|
| Docker 环境 | 构建、推送镜像必须依赖 | Jenkins 运行的机器(agent)上装了 Docker(能跑 docker --version) |
| Docker 仓库(Harbor) | 存放推送的镜像 | 有可用的仓库地址(比如 hub.magedu.com),且有登录账号密码 |
| 项目 Dockerfile | 构建镜像的 "配方" | 项目根目录下有 Dockerfile(不然没法 docker build) |
Pipeline核心步骤
| 阶段名 | 核心操作 | 说明 |
|---|---|---|
| Source(拉代码) | git 拉取项目代码 |
从 Git 仓库把代码拉到 Jenkins 工作目录 |
| Build(编译) | mvn 打包 Java 项目 |
生成可运行的 jar 包(适配 Spring Boot 项目) |
| Test(测试) | mvn test 执行测试 |
可选(不想测试可以删掉这个阶段) |
| Docker Build | docker build 构建镜像 |
用 Dockerfile 把项目打包成镜像,打上标签 |
| Docker Push | 登录 Harbor + 推送镜像 | 先登录仓库,再把镜像推上去(需要账号密码凭据) |
案例
- 替换
GitRepo为你的项目 Git 地址 - 替换
HarborServer为你的 Harbor 地址(比如你的仓库地址.com) - 替换
credentialsId: 'harbor-user-cred'为你 Jenkins 里的 Harbor 账号密码凭据 ID
groovy
pipeline {
agent any // Jenkins 任意节点都能跑
//自定义变量
environment {
GitRepo = "git@gitlab.chenshiquan.xyz:root/docker-java-hello.git" //GitLab地址
HarborServer = "harbor.chenshiquan.xyz" // Harbor地址
ImageName = "library/docker-java-hello" // 镜像名称
DING_TOKEN = credentials('dingtalk-robot-token')
ImageTag = "v1.0"
}
stages {
// 步骤1:拉取代码
stage('拉代码'){
steps{
deleteDir() //清理工作空间缓存
git(
url: "${GitRepo}", //URL
branch: "master", //拉取主分支代码
credentialsId: "71751bf3-bc66-48b1-8d7a-7ff7c0ee5c71" //凭据ID
)
echo "代码拉取完成!"
}
}
// 步骤2:构建 Docker 镜像
stage('构建镜像') {
steps {
// 构建镜像并打标签:仓库地址/镜像名:标签
sh "docker build -t ${HarborServer}/${ImageName}:${ImageTag} ."
}
}
// 步骤4:推送镜像到 Harbor
stage('推送镜像') {
steps {
// 用凭据登录 Harbor
withCredentials([
usernamePassword(
credentialsId: 'harbor-key', //harbor凭据ID
usernameVariable: 'HARBOR_USER', // 用户名变量
passwordVariable: 'HARBOR_PASS' // 密码变量
)
]) {
// 1. 登录 Harbor(日志里密码会显示成 ****,安全)
sh "docker login -u ${HARBOR_USER} -p ${HARBOR_PASS} ${HarborServer}"
// 2. 推送镜像
sh "docker push ${HarborServer}/${ImageName}:${ImageTag}"
// 3. 登出
sh "docker logout ${HarborServer}"
}
}
}
}
post {
success {
// 构建成功通知:包含项目、Git标签、镜像地址
sh '''
curl -X POST "https://oapi.dingtalk.com/robot/send?access_token=${DING_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"msgtype":"text",
"text":{
"content":"hello! 构建成功!\n项目名称:${JOB_NAME}\n镜像地址:'${HarborServer}'/'${ImageName}':'${ImageTag}'\n构建编号:'${BUILD_NUMBER}'"
}
}'
'''
echo "构建成功!钉钉通知已发送"
}
failure {
// 构建失败通知:提示检查日志
sh '''
curl -X POST "https://oapi.dingtalk.com/robot/send?access_token=${DING_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"msgtype":"text",
"text":{
"content":"hello! 构建失败!\n项目名称:${JOB_NAME}\n构建编号:'${BUILD_NUMBER}'\n请登录Jenkins检查日志"
}
}'
'''
echo "构建失败!钉钉通知已发送"
}
}
}
配套的简单 Dockerfile(项目根目录下新建)
dockerfile
FROM harbor.chenshiquan.xyz/library/maven:3-eclipse-temurin-11-alpine AS build
ENV CODE_DIR=/app/code
ARG NAME=test
ENV pord_NAME=${NAME}
WORKDIR ${CODE_DIR}
COPY settings.xml /usr/share/maven/conf/
COPY docker-java-hello ./
RUN mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar \
-Dsonar.projectKey=${pord_NAME} \
-Dsonar.projectName=${pord_NAME} \
-Dsonar.host.url=http://10.0.0.123:9000 \
-Dsonar.sources=. \
-Dsonar.token=squ_6ec3aa500b872c85e62e5705d5fd87e0bea32e4d
FROM harbor.chenshiquan.xyz/library/tomcat:9.0-jdk8
LABEL author=csq destcation="tomcat war包"
COPY --from=build /app/code/target/*.war webapps/ROOT.war
EXPOSE 8080
CMD ["catalina.sh","run"]

参数化Pipeline
| 参数类型 | 用途(我能用它干嘛) | 语法模板(直接抄) | 关键说明 |
|---|---|---|---|
| string(字符串) | 传单行文本(比如环境名、版本号) | parameters { string(name: '参数名', defaultValue: '默认值', description: '说明') } |
最常用,比如传 v1.0.0、dev 这类短文本 |
| text(多行文本) | 传多行内容(比如配置文件、脚本) | parameters { text(name: '参数名', defaultValue: '第一行\n第二行', description: '说明') } |
支持换行,比如传多行的 nginx.conf 配置 |
| booleanParam(布尔) | 选 "是 / 否"(比如是否发布、是否调试) | parameters { booleanParam(name: '参数名', defaultValue: true, description: '说明') } |
只有两个选项:true(是)/false(否),引用时是字符串类型 |
| choice(下拉选项) | 从固定选项里选(比如分支、环境) | parameters { choice(name: '参数名', choices: ['选项1', '选项2'], description: '说明') } |
避免手动输错,比如固定可选分支 main/test |
| password(密码) | 传敏感密码 / 令牌(隐藏显示) | parameters { password(name: '参数名', defaultValue: '默认密码', description: '说明') } |
输入和日志中都会隐藏(显示 ****),安全 |
使用变量拉取master分支v1.0标签
groovy
pipeline {
agent any
// 变量集中定义,修改直接改这里
environment {
GIT_URL = "git@gitlab.chenshiquan.xyz:root/docker-java-hello.git" // SSH 仓库地址
GIT_CRED_ID = "71751bf3-bc66-48b1-8d7a-7ff7c0ee5c71" // SSH 私钥凭据ID(替换为你的实际ID)
TARGET_BRANCH = "master" // 标签所属分支
TARGET_TAG = "v1.0" // 要拉取的标签
}
stages {
stage('拉取 master 分支的 v1.0 标签代码(含子模块)') {
steps {
echo "拉取配置:仓库=${GIT_URL},分支=${TARGET_BRANCH},标签=${TARGET_TAG}"
checkout scmGit(
branches: [[name: "refs/tags/${TARGET_TAG}"]], // 标签完整引用(必选)
extensions: [
// 仅保留子模块核心配置(递归拉取 + 复用主仓库SSH凭据)
submodule(
parentCredentials: true, // 子模块复用主仓库SSH凭据
recursiveSubmodules: true, // 递归拉取所有子模块
reference: ''
)
],
userRemoteConfigs: [[
url: "${GIT_URL}",
credentialsId: "${GIT_CRED_ID}", // 必须是 SSH 私钥类型凭据
// SSH 协议无需额外配置,Jenkins 会自动用凭据中的私钥认证
]]
)
// 可选验证:确保标签属于 master 分支(避免拉错同名标签)
script {
sh "git branch -r --contains refs/tags/${TARGET_TAG} | grep -w origin/${TARGET_BRANCH} || error '标签 ${TARGET_TAG} 不属于 ${TARGET_BRANCH} 分支!'"
}
echo "代码拉取完成!当前版本:${TARGET_TAG}(含所有子模块)"
}
}
}
}

单个参数示例
=示例 1:string(字符串参数)------ 传递部署环境
groovy
pipeline {
agent any
// 定义参数:部署环境(默认 dev)
parameters {
string(
name: 'DEPLOY_ENV', // 参数名(引用时用这个)
defaultValue: 'dev', // 默认值(不填时自动用这个)
description: '请输入部署环境(比如 dev/test/prod)' // 提示用户怎么填
)
}
stages {
stage('打印参数') {
steps {
// 引用参数:用 ${params.参数名}(必写 params.)
echo "本次部署的环境是:${params.DEPLOY_ENV}"
}
}
}
}
//运行效果
//构建时会弹出输入框,默认显示 dev,可改成 test,构建日志会打印 本次部署的环境是:test

示例 2:choice(下拉选项)------ 选择构建分支
groovy
pipeline {
agent any
// 定义参数:下拉选择分支
parameters {
choice(
name: 'BUILD_BRANCH',
choices: ['master', 'test', 'dev'], // 固定选项(用户只能选,不能输)
description: '请选择要构建的分支'
)
}
stages {
stage('拉取代码') {
steps {
echo "正在拉取分支:${params.BUILD_BRANCH}"
git branch: "${params.BUILD_BRANCH}", url: "git@gitlab.chenshiquan.xyz:root/docker-java-hello.git"
}
}
}
}

示例 3:booleanParam(布尔参数)------ 是否发布版本
groovy
pipeline {
agent any
// 定义参数:是否发布(默认不发布)
parameters {
booleanParam(
name: 'IS_PUBLISH',
defaultValue: false, // 默认 false(不发布)
description: '是否将构建结果发布到生产环境(是选true,否选false)'
)
}
stages {
stage('判断是否发布') {
steps {
echo "是否发布:${params.IS_PUBLISH}" // 输出 true 或 false(字符串类型)
// 条件判断:如果是 true,执行发布命令
script {
if (params.IS_PUBLISH == 'true') { // 注意:布尔参数引用后是字符串!
echo "开始发布到生产环境..."
// sh "发布脚本" // 实际发布命令写这里
} else {
echo "仅构建,不发布"
}
}
}
}
}
}
示例 4:password(密码参数)------ 传递 Harbor 密码
groovy
pipeline {
agent any
// 定义参数:Harbor 密码(隐藏显示)
parameters {
password(
name: 'HARBOR_PASS',
defaultValue: '', // 密码默认空,让用户手动输
description: '请输入 Harbor 仓库的登录密码(输入时隐藏)'
)
}
stages {
stage('登录 Harbor') {
steps {
withCredentials([
usernamePassword(
credentialsId: 'harbor-user', // Jenkins 里的用户名凭据(只存用户名)
usernameVariable: 'HARBOR_USER'
)
]) {
// 密码用参数 ${params.HARBOR_PASS},日志中会显示 ****
sh "docker login -u ${HARBOR_USER} -p ${params.HARBOR_PASS} hub.magedu.com"
}
}
}
}
}
//运行效果:
//输入密码时显示圆点 / 星号,日志中密码会被隐藏,避免泄露

示例 5:text(多行文本)------ 传递配置文件内容
groovy
pipeline {
agent any
// 定义参数:多行配置(比如 nginx 配置)
parameters {
text(
name: 'NGINX_CONFIG',
defaultValue: 'server {\n listen 80;\n server_name localhost;\n}', // 换行用 \n
description: '请粘贴 nginx 配置文件内容(支持多行)'
)
}
stages {
stage('生成配置文件') {
steps {
// 将多行参数内容写入文件
sh "echo '${params.NGINX_CONFIG}' > /etc/nginx/conf.d/default.conf"
echo "已生成 nginx 配置文件"
}
}
}
}
//运行效果:
//用户可以粘贴多行配置,Pipeline 会自动生成对应的配置文件。


多参数综合示例
下面的 Pipeline 包含 4 种参数,模拟 "选择分支→输入版本号→是否调试→输入密码" 的完整流程:
groovy
pipeline {
agent any
// 多个参数一起定义(顺序不影响)
parameters {
// 1. 下拉选择分支
choice(
name: 'BRANCH',
choices: ['master', 'test', 'dev'],
description: '请选择构建分支'
)
// 2. 输入版本号(字符串)
string(
name: 'VERSION',
defaultValue: 'v1.0',
description: '请输入版本号'
)
// 3. 是否开启调试(布尔)
booleanParam(
name: 'DEBUG',
defaultValue: false,
description: '是否开启调试模式(true=开启,false=关闭)'
)
// 4. 输入数据库密码(密码类型)
}
stages {
stage('构建前准备') {
steps {
echo "===== 构建参数汇总 ====="
echo "分支:${params.BRANCH}"
echo "版本号:${params.VERSION}"
echo "调试模式:${params.DEBUG}"
}
}
stage('拉取代码') {
steps {
git branch: "${params.BRANCH}", url: "git@gitlab.chenshiquan.xyz:root/java-hello.git"
}
}
stage('构建打包') {
steps {
// 根据调试模式决定是否加调试参数
script {
if (params.DEBUG == 'true') {
sh "mvn clean package -Ddebug" // 开启调试
} else {
sh "mvn clean package" // 正常构建
}
}
}
}
stage('部署') {
steps {
echo "部署 ${params.VERSION} 版本到 ${params.BRANCH} 分支对应的环境..."
}
}
}
}
//运行效果:
//构建时会依次显示参数输入界面(下拉框 + 输入框 + 勾选框 + 密码框),用户填写后,Pipeline 会根据参数执行不同逻辑。

实现交互式功能
| 核心功能 | 支持的输入参数类型 | 变量作用域 | 关键特点 / 语法说明 |
|---|---|---|---|
| 运行时暂停,等待用户手动输入 | string(字符串)、choice(下拉)、booleanParam(布尔)等(同 parameters 指令) | 1. 局部:仅当前 Stage 2. 全局:所有 Stage | 1. 需包裹在 script{} 中(声明式 Pipeline 要求) 2. 用变量接收输入结果,格式为 Map(键 = 参数名,值 = 用户输入) |
| 限定审批人 / 审批组 | (属于 input 自身配置) | 无 | submitter: 'admin,dev组'(仅指定用户 / 组可审批) |
| 记录审批人账号 | (属于 input 自身配置) | 同输入参数 | submitterParameter: 'APPROVER'(自动存储审批人账号到 Map 中) |
| 优雅全局复用 | 所有支持类型 | 所有 Stage | 变量声明在 environment{} 中,或 Pipeline 外部 def 变量 |
示例 1:局部作用域(单参数)------ 仅当前 Stage 可用
场景:构建过程中暂停,让用户输入备注,仅当前 Stage 能引用该输入。
groovy
pipeline {
agent any
stages {
stage('用户输入参数') {
steps {
script {
def userInput = input(
message: '请填写构建相关参数',
parameters: [
string(name: 'REMARK', defaultValue: '常规构建', description: '构建备注'),
string(name: 'VERSION_DESC', defaultValue: 'V1.0.0', description: '版本说明')
]
)
// 多参数存入环境变量
env.BUILD_REMARK = userInput.REMARK
env.VERSION_DESC = userInput.VERSION_DESC
echo "构建备注:${env.BUILD_REMARK}"
echo "版本说明:${env.VERSION_DESC}"
}
}
}
stage('跨Stage复用参数') {
steps {
echo "跨Stage引用 - 备注:${env.BUILD_REMARK}"
echo "跨Stage引用 - 版本:${env.VERSION_DESC}"
}
}
}
}
//运行效果:
//1. 构建到 "用户输入备注" Stage 时,会暂停,弹出输入框;
//2. 用户输入 "修复支付 bug",点击 "确定" 后,Pipeline 继续运行;
//3. 日志打印 "本次构建备注:修复支付 bug",下一个 Stage 无法引用该变量。

示例 2:全局作用域(多参数)------ 跨 Stage 可用
场景:部署前让用户选择目标环境、输入自定义参数,后续所有 Stage 都能引用这些输入(用 Pipeline 外部的 def 变量存储)。
groovy
// 关键:在pipeline{}外部声明变量(全局作用域,所有Stage可引用)
def approvalInfo
pipeline {
agent any
stages {
stage('审批与输入参数') {
steps {
script {
// input接收多参数,结果存入全局变量approvalInfo
approvalInfo = input(
message: '请审批并填写部署参数', // 弹窗标题
ok: '确认提交', // 弹窗确认按钮文字
submitter: 'admin,deploy组', // 仅指定用户/组能审批(可选)
submitterParameter: 'APPROVER', // 自动记录审批人账号,参数名=APPROVER
parameters: [
// 第一个参数:下拉选择目标环境
choice(
name: 'DEPLOY_ENV',
choices: ['dev(开发)', 'test(测试)', 'prod(生产)'],
description: '请选择部署环境(生产环境需谨慎)'
),
// 第二个参数:字符串输入自定义备注
string(
name: 'CUSTOM_PARAM',
defaultValue: '',
description: '可选:输入额外部署参数(比如版本号、配置项)'
)
]
)
}
}
}
stage('执行部署') {
steps {
echo "===== 部署信息汇总 ====="
echo "审批人:${approvalInfo['APPROVER']}" // 引用审批人(自动记录)
echo "目标环境:${approvalInfo['DEPLOY_ENV']}" // 引用下拉选择的环境
echo "自定义参数:${approvalInfo['CUSTOM_PARAM']}" // 引用输入的字符串
echo "开始部署到 ${approvalInfo['DEPLOY_ENV']} 环境..."
// sh "部署脚本 --env ${approvalInfo['DEPLOY_ENV']}" // 实际部署命令
}
}
}
}
//运行效果:
//1. 构建到 "审批与输入参数" Stage 时暂停,弹窗显示下拉框 + 输入框;
//2. 只有 admin 或 "deploy 组" 用户能看到 "确认提交" 按钮,普通用户无法操作;
//3. 用户选择 "test(测试)",输入 "v2.0.1",提交后,"执行部署" Stage 能正常引用所有参数。

示例 3:优雅方式(用环境变量存储 input 参数)
场景:把 input 输入的参数存入 environment 变量,全局可用,语法更简洁(无需在 Pipeline 外部声明 def)。
groovy
pipeline {
agent any
// 环境变量:存储input参数(全局可用)
environment {
// 先声明环境变量,初始值为空
DEPLOY_INFO = ''
}
stages {
stage('获取部署参数') {
steps {
script {
// input结果存入环境变量DEPLOY_INFO(Map类型)
DEPLOY_INFO = input(
message: '填写部署参数',
parameters: [
booleanParam(
name: 'IS_ROLLBACK',
defaultValue: false,
description: '是否回滚(true=回滚,false=正常部署)'
),
string(
name: 'ROLLBACK_VERSION',
defaultValue: 'v1.0.0',
description: '若回滚,输入回滚版本'
)
]
)
}
}
}
stage('判断部署类型') {
steps {
script {
// 引用环境变量中的input参数(env.可省略)
if (DEPLOY_INFO['IS_ROLLBACK'] == 'true') {
echo "执行回滚,目标版本:${DEPLOY_INFO['ROLLBACK_VERSION']}"
// sh "回滚脚本 --version ${DEPLOY_INFO['ROLLBACK_VERSION']}"
} else {
echo "执行正常部署,不回滚"
// sh "部署脚本"
}
}
}
}
}
}
//运行效果
//1. 暂停时用户勾选 "是否回滚" 为 true,输入回滚版本 "v1.9.8";
//2. 后续 Stage 通过 `DEPLOY_INFO['参数名']` 引用,无需关心变量声明位置,语法更统一。

输入等待超时
input步骤与timeout步骤协同使用,可实现超时自动中止pipeline,以避免无限等待
| 参数名称 | 参数说明(新手友好) | 必填性 | 取值示例 |
|---|---|---|---|
| time | 超时等待时长(整数) | 是 | 1(分)、30(秒)、2(时) |
| unit | 时间单位(默认分钟) | 否 | SECONDS(秒)、MINUTES(分)、HOURS(时)、DAYS(天) |
| activity | 按 "无活动" 计时(默认绝对时长) | 否 | true(用户没操作才计时)、false(到点就超时) |
示例 1:基础版(简单确认 + 1 分钟超时)
场景:暂停等待用户点击确认,1 分钟没操作自动失败。
groovy
pipeline {
agent any
stages {
stage('等待确认') {
steps {
echo "1分钟内未点击确认,Pipeline将自动失败"
// 超时配置:1分钟(unit默认MINUTES,可省略)
timeout(time: 1, unit: 'MINUTES') {
// 简单输入:仅确认按钮
input message: '是否继续执行下一步?'
}
echo "用户已确认,继续构建~"
}
}
}
}
//运行效果
//1 分钟内点 "确认":打印后续日志,正常执行;
//1 分钟未操作:Pipeline 失败,日志提示 "Timeout waiting for input"。

示例 2:带参数版(选择环境 + 3 分钟超时)
场景:部署前让用户选环境,3 分钟超时自动中止,适合需要输入参数的场景。
groovy
pipeline {
agent any
stages {
stage('部署审批') {
steps {
script {
echo "请3分钟内选择部署环境并确认"
// 超时配置:明确单位为分钟(更清晰,避免歧义)
timeout(time: 3, unit: 'MINUTES') {
def deployEnv = input(
message: '选择部署环境(3分钟超时)',
parameters: [
choice(
name: 'ENV', // 参数名(仅用于输入框标识,返回值不是Map)
choices: ['dev', 'test', 'prod'],
description: '只能选这3个环境'
)
],
ok: '确认部署'
)
// 直接使用 deployEnv(字符串值),无需加 .ENV
echo "已选择部署环境:${deployEnv}"
// 可选:存入环境变量,支持后续Stage引用
env.DEPLOY_ENV = deployEnv
}
}
}
}
// 可选:测试跨Stage引用部署环境
stage('执行部署') {
steps {
echo "开始部署到 ${env.DEPLOY_ENV} 环境..."
// 后续部署命令(如部署脚本、容器启动等)
// sh "./deploy.sh ${env.DEPLOY_ENV}"
}
}
}
}
//运行效果:
//3 分钟内选环境 + 确认:打印环境名称,继续部署;
//3 分钟未操作:直接失败,不执行部署。

示例 3:自定义超时行为(2 分钟超时不失败,跳过步骤)
场景:非关键步骤,2 分钟超时后不失败,仅跳过该步骤。
groovy
pipeline {
agent any
stages {
stage('可选测试步骤') {
steps {
script {
echo "2分钟内未确认,将跳过测试步骤"
// catchError:捕获超时错误,不中断整体构建
catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE') {
timeout(time: 2, unit: 'MINUTES') {
input message: '是否执行额外测试?'
echo "执行额外测试..."
sh "echo 测试脚本运行中"
}
}
}
}
}
stage('核心构建') {
steps {
echo "核心构建步骤不受超时影响,继续执行~"
}
}
}
}
//运行效果:
//2 分钟内确认:执行测试步骤,核心构建正常;
//2 分钟超时:测试步骤标记为 "不稳定",直接执行核心构建,整体构建状态为成功。
