Jenkins学习

本文中所有的测试内容都是基于python相关自动化,没有java自动化相关的内容,重点实现三个目的

  1. 在本地环境中搭建一个属于自己的jenkins服务,练习jenkins上的操作,以便于工作中使用
  2. 学习pipeline流水线中的声明式脚本编写方法,达到独立编写和看懂别人的Jenkinsfile文件
  3. 部署windows 为slave节点,运行简单的ui自动化脚本

1 jenkins 安装

此处下载安装包

官方使用说明书

本文选择 war包进行测试学习 选择绿框的war包

这类版本会经过更充分的测试和验证,是生产环境的首选。

它的更新周期更长,注重稳定性和安全性,仅会修复严重的 bug 和安全漏洞,不会频繁引入新功能。

适合追求稳定、不希望频繁升级的企业级生产环境。

部署电脑为Mac M1,java 版本为

启动命令

bash 复制代码
java -jar jenkins.war

2 启动后配置

2.1 第一次启动后获取以下内容

打开 本地浏览器 ,在地址栏中输入 http://localhost:8080.默认8080端口,也可以指定端口开启 java -jar jenkins.war --httpPort=8080

2.2 配置服务内容

将上一步中的管理员密码复制到这里,然后点【继续】

选择 推荐插件安装,耐心等待安装完成...


创建一个自己的账户,点击【继续】

3 使用Jenkins

登录 jenkins后 点击右上角 ⚙️ ,打开全局设置,如果有以下内容提示 忽略,

3.1 Freestyle project 的使用方法

3.1.1 创建一个freestyle project


选择 freestyle project,输入一个名称,可以是中文,尽可能中间不要夹杂空格

根据需要进行配置,先来个简单的,填写描述后,在构建步骤中选择,执行shell,


这里可以执行shell的语法和linux中的命令,点击保存

在主界面上就会有新的项目生成,可以点击名称进入

3.1.2 触发执行freestyle project

点击【立即构建】,等待执行结束,查看执行结果

生成一条测试的记录,点进入

点击【控制台输出】,可以看到shell 执行的步骤和结果,最终的结果是SUCCESS

3.1.3 Freestyle project 配置中部分内容详解
bash 复制代码
This project is parameterized(这个项目是参数化的)
	- 让你的 Jenkins 构建任务支持传入自定义参数。
	- 勾选后可以添加多种类型的参数(如字符串、下拉选择、布尔值等)。每次构建时,你都可以输入或选择不同的参数值,让构建过程更灵活。
	- 比如你想让同一个任务构建不同的分支、部署到不同的环境(测试 / 生产)时,就可以用参数化来实现。
Throttle builds(限制构建)
	- 用来控制这个任务的并发构建次数和频率
	- 可以设置 "最大并发数" 或 "两次构建的最小间隔时间",避免短时间内大量构建占用过多服务器资源。
	- 在资源紧张的服务器上,或者防止代码提交太频繁导致的频繁构建。
丢弃旧的构建
	- 自动清理历史构建记录和产物,避免磁盘空间被占满。
	- 勾选后可以设置保留的构建天数、保留的最大构建数量,超出后 Jenkins 会自动删除旧的构建数据
	- 生产环境中运行很久的任务,构建记录会越来越多,开启这个可以节省磁盘空间

触发了三次构建,但是平台上只有两次的构建记录

默认是【无】,后续的使用中会配置gitee代库的内容

配置代码地址,添加用户名和密码,这里的密码不是登录gitee的密码,是一个类似与令牌的一串字符串,在个人设置中可以获取,还可以配置分支,验证分支代码

bash 复制代码
触发远程构建(例如,使用脚本)
	- 允许通过 HTTP 请求来触发构建,通常用于外部系统或脚本调用。
	- 勾选后会生成一个带认证令牌的 URL,外部系统可以通过 POST 请求调用这个 URL 来触发构建。
	- 比如在 CI/CD 流程中,让外部工具(如测试平台、发布系统)触发 Jenkins 构建,或用脚本实现自动化触发。
定时构建
	- 按照固定的时间周期自动触发构建,类似 Linux 的 cron 任务。
	- 勾选后需要填写 cron 表达式,比如 H 2 * * * 表示每天凌晨 2 点左右执行一次。
	- 适合需要定期执行的任务,比如每日构建、夜间自动测试、定时备份等。
轮询 SCM
	- 让 Jenkins 定期检查代码仓库是否有新提交,如果有则触发构建。
	- 勾选后填写 cron 表达式,比如 H/5 * * * * 表示每 5 分钟检查一次。
	- 当无法配置 WebHook(如仓库在内网)时,用轮询作为替代方案,但效率比 WebHook 低。
bash 复制代码
Delete workspace before build starts
	- 在构建开始前,清空当前任务的工作目录(workspace)
	- 确保每次构建都是 "干净" 的,避免上次构建的残留文件影响本次结果。适合编译类或依赖缓存的项目,但会增加构建时间。
Use secret text(s) or file(s)
	- 在构建环境中安全地注入敏感信息,如密码、API 密钥、证书文件等。
	- 需要访问私有仓库、外部 API 或云服务时,用它来传递凭据,避免在脚本中硬编码密码。
Terminate a build if it's stuck
	- 自动终止长时间无响应的 "卡住" 构建,避免占用资源。
	- 防止因代码死循环、网络超时等问题导致构建一直挂着,浪费服务器资源。勾选后可设置超时时间。
在构建日志中添加时间戳前缀
	- 在每一行构建日志前加上时间戳,方便定位问题发生的具体时间。
	- 排查构建失败或性能问题时,时间戳能帮你快速定位到问题发生的精确时刻。


bash 复制代码
Run with timeout
	- 给后续的构建步骤设置超时时间,防止某个步骤无限期运行
	- 比如运行测试脚本时,防止因测试卡住导致整个构建挂起。
执行 Windows 批处理命令
	- 在 Windows 系统的 Jenkins 节点上,执行 Windows 批处理脚本(.bat 或 .cmd 命令)
	- 在 Windows 环境下执行文件复制、环境变量配置等操作。
执行 shell
	- 作用:在 Linux/macOS 系统的 Jenkins 节点上,执行 Shell 脚本。
	- 最常用的步骤之一,用于拉取代码、编译、运行测试、上传产物等几乎所有自动化操作。


bash 复制代码
E-mail Notification / Editable Email Notification
	- 构建完成后发送邮件通知,后者支持自定义邮件内容、收件人和触发条件。
	- 构建失败时通知开发人员,或构建成功时通知测试团队。
Delete workspace when build is done
	- 构建完成后自动删除当前任务的工作目录,释放磁盘空间。
	- 适合一次性任务或磁盘资源紧张的环境,但会影响后续的增量构建。
3.1.4 从gitee上拉取指定分支的代码

选择 git 配置代码库

url 选择 ssh 下的

配置账号和密码

账号是gitee的账号,密码是在个人设置中的私人令牌

分支默认是master 代码库中也是master 不用修改

注意:需要提前把ssh 公钥上传到个人设置,

保存配置,立即构建测试,检查测试结果

存储的位置

可以看到,代码拉取下来,自动把git-study 下的内容 全部复制到了工作路径下

下面是测试的目录结构

3.1.5 列举在shell 中可用的环境变量有哪些
bash 复制代码
JOB_NAME	当前 Jenkins 任务名称
BUILD_NUMBER	当前构建的序号(每次构建自增)
BUILD_ID	当前构建的唯一 ID
BUILD_URL	当前构建的网页地址
WORKSPACE	构建工作目录的绝对路径

GIT_URL	Git 仓库地址
GIT_BRANCH	当前构建的代码分支
GIT_COMMIT	触发构建的 Git 提交哈希
GIT_PREVIOUS_COMMIT	上一次构建的 Git 提交哈希

JENKINS_URL	Jenkins 服务器的根地址
NODE_NAME	执行本次构建的节点名称
BUILD_USER	触发本次构建的用户名
JAVA_HOME	构建节点上的 Java 环境路径

出现乱码是有中文的原因

3.2 构建流水线项目

安装一个 插件 查看结果方便

3.2.1 流水线中的定义

支持两种方式

一种是在平台上编写的方式,另一种是Jenkinsfile的方式

3.2.2 编写的方式

声明式

脚本式

3.2.3 使用声明式编写一个简单的流程

输出结果 通过Blue Ocean 看


可以在顶部直观的看每一步骤的执行结果,还可以单独的重复执行某一个步骤

3.2.4 编写声明式脚本

官方pipeline语法编写参考

3.2.4.1 声明式脚本的框架

基本框架

groovy 复制代码
// 声明式 Pipeline 的根块,所有逻辑都在其中
pipeline {
    // agent 定义执行流水线的代理(节点),必填项
    // any 表示使用任意可用的节点执行
    agent any

    // 可选:定义流水线的全局参数
    parameters {
        // 字符串参数示例
        string(name: 'ENV', defaultValue: 'dev', description: '部署环境')
        // 布尔参数示例
        booleanParam(name: 'DEPLOY', defaultValue: false, description: '是否部署')
    }

    // 可选:定义全局环境变量
    environment {
        // 自定义环境变量
        APP_NAME = 'my-project'
        // 从 Jenkins 凭据中读取变量(推荐)
        DB_PASSWORD = credentials('jenkins-db-pass-123')
    }

    // 可选:定义流水线执行的触发器
    triggers {
        // 定时触发(cron 表达式,每天凌晨 2 点执行)
        cron('0 2 * * *')
        // 代码提交触发(需配置 SCM 触发器)
        // pollSCM('H/15 * * * *')
    }

    // 可选:定义流水线执行失败后的重试策略
    options {
        // 失败后重试 2 次
        retry(2)
        // 流水线超时时间 30 分钟
        timeout(time: 30, unit: 'MINUTES')
    }

    // 可选:定义后置条件(无论成功/失败都会执行)
    post {
        // 流水线成功后执行
        success {
            echo "✅ 流水线执行成功!环境:${ENV}"
        }
        // 流水线失败后执行
        failure {
            echo "❌ 流水线执行失败!"
            // 可添加发送邮件、钉钉通知等逻辑
        }
        // 无论结果如何都执行
        always {
            echo "📝 流水线执行完成,清理临时文件"
        }
    }

    // 核心:定义流水线的阶段(Stage),按顺序执行
    stages {
        // 阶段 1:拉取代码
        stage('拉取代码') {
            // 阶段内的具体步骤
            steps {
                echo "📥 拉取 ${APP_NAME} 代码..."
                // git 拉取代码示例(需配置代码仓库地址)
                // git url: 'https://github.com/your/repo.git', branch: 'main'
            }
        }

        // 阶段 2:构建项目
        stage('构建项目') {
            steps {
                echo "🔨 构建 ${APP_NAME}(环境:${ENV})..."
                // 执行构建命令(如 maven、npm 等)
                // sh 'mvn clean package -DskipTests'
            }
            // 可选:阶段级别的后置条件
            post {
                success {
                    echo "✅ 构建成功!"
                }
            }
        }

        // 阶段 3:条件性部署(仅当 DEPLOY 参数为 true 时执行)
        stage('部署项目') {
            // 阶段执行的条件
            when {
                expression { params.DEPLOY == true }
            }
            steps {
                echo "🚀 部署 ${APP_NAME} 到 ${ENV} 环境..."
                // 执行部署命令
                // sh './deploy.sh ${ENV}'
            }
        }
    }
}

声明式 Pipeline 的核心骨架是 pipeline -> agent -> stages -> stage -> steps,这 5 个层级是必填且不可缺失的。

3.2.4.2 声明式脚本的组件
组件 作用 是否必填
pipeline 声明式Pipeline的根块
agent 指定流水线执行的节点(any|none|label等),决定代码在哪里执行
stages 包含所有执行阶段(stage),是流水线的核心逻辑区
stage 单个执行阶段(容易拉取代码、构建、部署等),可命名,需要包含steps
steps 单个阶段内的具体执行步骤(如 echo、sh、git等命令)
environment 定义全局环境变量
parameters 定义流水线运行时的输入参数(字符串、布尔、选择框等)
triggers 定义流水线的自动触发规则 (定时、代码提交等)
options 定义流水线的全局配置 (超时、重试、并行等)
post 定义流水线/阶段执行后的后置操作(成功/失败/始终执行)
when 定义阶段执行的条件(参数判断、分支判断等)

environment/parameters/triggers 等是扩展组件,用于满足参数化、自动化、环境隔离等场景。

3.2.4.3 常用关键字用法
3.2.4.3.0 pipeline (必填

写法

groovy 复制代码
pipeline {
	...
	...
	...
}

只能有存在一个,作为根,所有的内容都必须包含其中

3.2.4.3.1 agent (必填

1 agent any

  • 作用:使用Jenkins集群中任意可用的节点执行流水线(包括Jenkins主控节点)
  • 适用场景:无特殊节点要求的简单流水线,新手入门首选
groovy 复制代码
pipeline {
    agent any  // 全局生效,整个流水线在任意节点执行
    stages {
        stage('Test') {
            steps {
                echo "运行在节点:${env.NODE_NAME}"
            }
        }
    }
}

小知识

bash 复制代码
stage('打印所有环境变量') {
    steps {
        echo "===== 所有环境变量 ====="
        sh 'printenv'  // Linux/Mac
        // bat 'set'  // Windows节点用这行
    }
}

2 指定节点标签 : agent { label '标签名' }

  • 作用:仅在带有指定标签(label)的节点上执行,标签需要提前在Jenkins节点配置中设置
  • 适用场景:需要特定环境的节点(如带构建工具、GPU、特定系统的节点)
groovy 复制代码
pipeline {
    // 仅在标签为 "linux-build" 的节点上执行
    agent { label 'linux-build' }
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean package'  // 假设 linux-build 节点安装了 maven
            }
        }
    }
}

扩展:多标签匹配(满足任意一个):agent { label 'linux || docker' }

满足所有标签:agent { label 'linux && docker' }

3 不使用代理: agent none

  • 作用:全局不指定默认节点,需为每个stage单独配置agnet,适用于不同阶段需要不同节点的场景。
  • 适用场景:多阶段流水线,各阶段依赖不同环境,(如拉取代码在通用节点,构建在Linux节点,部署在windows节点)
groovy 复制代码
pipeline {
    agent none  // 全局无默认节点
    stages {
        stage('拉取代码') {
            agent { label 'common-node' }  // 该阶段用通用节点
            steps {
                git url: 'https://github.com/your/repo.git'
            }
        }
        stage('Linux 构建') {
            agent { label 'linux-build' }  // 该阶段用 Linux 节点
            steps {
                sh 'make build'
            }
        }
        stage('Windows 部署') {
            agent { label 'windows-deploy' }  // 该阶段用 Windows 节点
            steps {
                bat 'deploy.bat'
            }
        }
    }
}

4 使用docker容器: agent { docker '镜像名' }

  • 作用:在指定的docker容器内执行流水线/阶段,无需在节点上预装依赖(依赖封装在镜像中)
  • 适用场景:需要隔离构建环境、统一依赖版本 (如不同项目需要不同版本 JDK/Node.js)
groovy 复制代码
pipeline {
    agent { docker 'maven:3.8.8-openjdk-17' }  // 使用 maven 镜像执行
    stages {
        stage('Maven 构建') {
            steps {
                // 容器内已预装 maven,可直接执行
                sh 'mvn -v && mvn clean package'
            }
        }
    }
}

扩展:指定dockerfile构建镜像

groovy 复制代码
agent {
    dockerfile {
        dir 'docker'  // Dockerfile 所在目录
        label 'docker-node'  // 仅在带 docker 标签的节点执行
    }
}

5 高级配置

agent { node {...} }

  • 作用:更精细地配置节点,如指定标签+自定义工作路径
groovy 复制代码
pipeline {
    agent {
        node {
            label 'linux-build'  // 指定节点标签
            customWorkspace '/opt/workspace/my-project'  // 自定义工作目录
        }
    }
    stages {
        stage('Test') {
            steps {
                echo "工作目录:${env.WORKSPACE}"
            }
        }
    }
}

6 阶段级 agent (覆盖全局)

  • 作用:全局配置 agent后,单个阶段可自定义agent,实现不同阶段在不同环境中执行
groovy 复制代码
pipeline {
    agent any  // 全局默认任意节点
    stages {
        stage('普通步骤') {
            steps {
                echo "全局节点:${env.NODE_NAME}"
            }
        }
        stage('Docker 内执行') {
            agent { docker 'node:20' }  // 该阶段单独使用 Node.js 容器
            steps {
                sh 'node -v && npm install'
            }
        }
    }
}
3.2.4.3.1 stages (必填

stages 是声明式pipeline的必填核心,用于包裹所有执行阶段(stage), 只能有一个

groovy 复制代码
pipeline {
    agent any
    stages {
       ...
       ...
       ...
    }
}
3.2.4.3.1 stage (必填

每个 stage 代表流水线的一个独立步骤(如拉取代码、构建、测试、部署),可以配置执行条件、并行逻辑、专属代理等,让流水线结构清晰、可维护。可以有多个

groovy 复制代码
pipeline {
    agent any
    stages {
        // 阶段1:拉取代码
        stage('拉取代码') {
            ...
        }
        
        // 阶段2:构建项目
        stage('构建项目') {
            ...
        }
        
        // 阶段3:部署项目
        stage('部署项目') {
            ...
        }
    }
}
3.2.4.3.1 steps (必填

steps 块包含一个或多个步骤指令,每个指令对应Jenkins的一个具体操作,支持内置核心指令、插件扩展指令,还能通过脚本块实现复杂逻辑。所有指令按照书写顺序串行执行(除非显示配置并行执行)
1 执行系统命令

适用于在节点上执行shell(Linux/Mac)、Batch(Windows)命令,是流水线中最常用的操作

(1)sh:执行linux命令

groovy 复制代码
pipeline {
    agent any
    stages {
        stage('执行 Shell 命令') {
            steps {
                // 单行命令
                sh 'echo "当前工作目录:$WORKSPACE"'
                // 多行命令(用三引号包裹)
                sh '''
                    echo "开始构建..."
                    ls -l  # 列出文件
                    mvn clean package -DskipTests  # Maven 构建
                '''
                // 捕获命令输出(保存到变量)
                script {
                    def branchName = sh(script: 'git rev-parse --abbrev-ref HEAD', returnStdout: true).trim()
                    echo "当前分支:${branchName}"
                }
            }
        }
    }
}

关键参数:returnStdout: true (返回命令输出)

returnStatus: true (返回命令执行状态码)

(2)bat/powershell : 执行windows命令

groovy 复制代码
stage('执行 Windows 命令') {
    agent { label 'windows-node' }
    steps {
        // Batch 命令
        bat 'dir && echo "构建开始"'
        // PowerShell 命令
        powershell 'Get-ChildItem && Write-Host "PowerShell 执行完成"'
    }
}

2 基础逻辑与输出

(1)echo:打印日志

groovy 复制代码
steps {
    echo "✅ 构建成功,当前环境:${params.ENV}"  // 支持变量插值
    echo '静态日志信息'
}

(2) script: 嵌入Groovy脚本(复杂逻辑)

script 块允许在声明式pipeline中嵌入脚本式pipeline语法,实现条件判断、循环、变量操作等复杂逻辑

groovy 复制代码
stage('复杂逻辑处理') {
    steps {
        script {
            // 定义变量
            def buildNum = env.BUILD_NUMBER
            def appName = 'my-app'
            
            // 条件判断
            if (params.DEPLOY == true) {
                echo "📤 开始部署 ${appName}(构建号:${buildNum})"
                // 调用其他步骤
                sh "./deploy.sh ${params.ENV}"
            } else {
                echo "🔍 跳过部署,仅完成构建"
            }
            
            // 循环
            for (int i = 1; i <= 3; i++) {
                echo "循环次数:${i}"
            }
        }
    }
}

(3) input: 人工确认 (暂停流水线)

适用于需要人共介入的场景(如发布前审批)

groovy 复制代码
stage('生产环境部署审批') {
    steps {
        input message: '是否确认部署到生产环境?',
               ok: '确认',
               submitter: 'admin,dev-lead',  // 仅指定用户可审批
               parameters: [string(name: 'DEPLOY_REASON', description: '部署原因')]
        
        echo "✅ 审批通过,部署原因:${params.DEPLOY_REASON}"
        sh './deploy-prod.sh'
    }
}

(4) sleep 暂停执行

groovy 复制代码
steps {
    echo "等待 10 秒后继续..."
    sleep time: 10, unit: 'SECONDS'  // 支持 SECONDS/MINUTES/HOURS/DAYS
}

3 文件与产物处理

(1)deleteDir/fileOperations:文件操作

groovy 复制代码
steps {
    deleteDir()  // 删除当前工作目录所有文件(清理环境)
    // 需安装 File Operations 插件
    fileOperations([
        fileCreateOperation(fileName: 'deploy.log'),  // 创建文件
        fileCopyOperation(sourceFile: 'config/dev.conf', targetLocation: 'conf/')  // 复制文件
    ])
}

4 调用Jenkins工具/集成插件

(1)git: 拉取代码

groovy 复制代码
steps {
    git url: 'https://github.com/your/repo.git',
        branch: 'main',
        credentialsId: 'github-cred',  // 凭证ID(私有仓库)
        clean: true  // 拉取前清理工作目录
}

5 环境与凭证处理

(1) withCredentials :使用凭证(核心)

groovy 复制代码
steps {
    // 使用用户名密码凭证
    withCredentials([usernamePassword(credentialsId: 'db-cred', 
                                      usernameVariable: 'DB_USER', 
                                      passwordVariable: 'DB_PASS')]) {
        sh "mysql -u${DB_USER} -p${DB_PASS} -e 'SELECT VERSION()'"
    }
    
    // 使用密钥文件凭证(如 SSH 私钥)
    withCredentials([file(credentialsId: 'ssh-key', variable: 'SSH_KEY')]) {
        sh "ssh -i ${SSH_KEY} user@server 'echo hello'"
    }
}

(2) withEnv: 临时设置环境变量

groovy 复制代码
steps {
    withEnv(['JAVA_HOME=/usr/lib/jvm/java-17', 'BUILD_TYPE=prod']) {
        sh 'echo $JAVA_HOME && echo $BUILD_TYPE'
        echo "构建类型:${env.BUILD_TYPE}"
    }
}

6 错误处理

goovy 复制代码
steps {
    catchError(buildResult: 'FAILURE', stageResult: 'UNSTABLE') {
        // 即使该命令失败,流水线不会立即终止,标记阶段为 UNSTABLE
        sh 'mvn test'
    }
    echo "测试完成(无论失败/成功)"
}

参数说明:buildResult(流水线整体结果)、stageResult(当前阶段结果),支持 SUCCESS/UNSTABLE/FAILURE。

3.2.4.3.1 environment (选填

environment 可以定义在全局或者阶段级,全局变量在所有阶段生效,阶段级变量仅在当前阶段生效且会覆盖同名全局变量。它支持静态变量、动态变量、凭据引用、参数引用等多种定义方式
1 基础用法:定义静态环境变量

(1)全局静态变量

groovy 复制代码
pipeline {
    agent any
    // 全局环境变量(所有阶段可用)
    environment {
        APP_NAME = 'my-springboot-app'  // 项目名称
        BASE_DIR = '/opt/workspace'     // 基础工作目录
        ENV_TYPE = 'test'               // 部署环境
    }
    stages {
        stage('打印全局变量') {
            steps {
                echo "项目名:${APP_NAME}"       // 输出:my-springboot-app
                echo "工作目录:${BASE_DIR}"     // 输出:/opt/workspace
                sh "echo '环境类型:${ENV_TYPE}'" // Shell 中引用
            }
        }
    }
}

(2) 阶段级静态变量(覆盖全局)

groovy 复制代码
pipeline {
    agent any
    environment {
        ENV_TYPE = 'test'  // 全局默认测试环境
    }
    stages {
        stage('部署生产环境') {
            // 阶段级变量,覆盖全局同名变量
            environment {
                ENV_TYPE = 'prod'
                DEPLOY_HOST = 'prod.example.com'
            }
            steps {
                echo "当前环境:${ENV_TYPE}"      // 输出:prod
                echo "部署地址:${DEPLOY_HOST}"   // 输出:prod.example.com
            }
        }
        stage('部署测试环境') {
            steps {
                echo "当前环境:${ENV_TYPE}"      // 输出:test(全局变量)
            }
        }
    }
}

2 核心用法:引用Jenkins凭据

(1)引用【用户名+密码】凭据

groovy 复制代码
pipeline {
    agent any
    environment {
        // 引用 ID 为 "db-cred" 的用户名+密码凭据
        // 会自动生成两个变量:DB_CRED_USR(用户名)、DB_CRED_PSW(密码)
        DB_CRED = credentials('db-cred')
        // 也可手动拆分用户名和密码(更直观)
        DB_USER = credentials('db-cred').username
        DB_PASS = credentials('db-cred').password
    }
    stages {
        stage('连接数据库') {
            steps {
                // 使用组合凭据
                sh "mysql -u${DB_CRED_USR} -p${DB_CRED_PSW} -h db.example.com"
                // 使用拆分后的凭据
                echo "数据库用户名:${DB_USER}"
                sh "psql -U ${DB_USER} -d mydb -w ${DB_PASS}"
            }
        }
    }
}

(2)引用【字符串凭据】(如令牌 密钥)

groovy 复制代码
environment {
    // 引用 ID 为 "api-token" 的字符串凭据
    API_TOKEN = credentials('api-token')
    // 引用 ID 为 "ssh-private-key" 的密钥文件凭据(变量存储密钥文件路径)
    SSH_KEY = credentials('ssh-private-key')
}
stages {
    stage('调用 API') {
        steps {
            sh "curl -H 'Authorization: Bearer ${API_TOKEN}' https://api.example.com"
        }
    }
    stage('SSH 连接服务器') {
        steps {
            sh "ssh -i ${SSH_KEY} user@server 'echo hello'"
        }
    }
}

(3) 引用【文件凭据】(如配置文件)

groovy 复制代码
environment {
    // 引用 ID 为 "app-config" 的文件凭据(变量存储文件路径)
    APP_CONFIG = credentials('app-config')
}
stages {
    stage('加载配置文件') {
        steps {
            sh "cat ${APP_CONFIG}"  // 读取配置文件内容
            sh "cp ${APP_CONFIG} ./config/application.yml"  // 复制到项目目录
        }
    }
}

3 高级用法:动态变量(引用内置变量/参数)

(1) 引用Jenkins内置环境变量

groovy 复制代码
pipeline {
    agent any
    environment {
        // 引用内置变量:构建号
        BUILD_VERSION = "v${env.BUILD_NUMBER}"
        // 引用内置变量:工作目录
        APP_OUTPUT_DIR = "${env.WORKSPACE}/target"
        // 引用内置变量:代码分支(需 Git 插件)
        GIT_BRANCH = "${env.GIT_BRANCH}"
    }
    stages {
        stage('打印动态变量') {
            steps {
                echo "构建版本:${BUILD_VERSION}"  // 输出:v123(假设构建号是123)
                echo "产物目录:${APP_OUTPUT_DIR}" // 输出:/var/jenkins/workspace/my-app/target
                echo "代码分支:${GIT_BRANCH}"     // 输出:main
            }
        }
    }
}

(2) 引用流水线参数

groovy 复制代码
pipeline {
    agent any
    parameters {
        string(name: 'DEPLOY_ENV', defaultValue: 'test', description: '部署环境')
        choice(name: 'APP_VERSION', choices: ['1.0.0', '1.1.0', '1.2.0'], description: '应用版本')
    }
    environment {
        // 引用参数变量
        TARGET_ENV = "${params.DEPLOY_ENV}"
        // 组合参数和内置变量
        DEPLOY_VERSION = "${params.APP_VERSION}-build${env.BUILD_NUMBER}"
    }
    stages {
        stage('部署') {
            steps {
                echo "部署环境:${TARGET_ENV}"       // 输出:test(或手动选择的值)
                echo "部署版本:${DEPLOY_VERSION}"   // 输出:1.0.0-build123
            }
        }
    }
}

(3) 使用expression动态计算(groovy表达式)

groovy 复制代码
pipeline {
    agent any
    environment {
        // 简单表达式:判断分支,动态设置环境
        RUN_ENV = expression { 
            env.GIT_BRANCH == 'main' ? 'prod' : 'test' 
        }
        // 复杂表达式:拼接字符串+时间戳
        BUILD_TAG = expression {
            def timestamp = new Date().format('yyyyMMddHHmmss')
            "app-${env.APP_NAME}-${timestamp}-${env.BUILD_NUMBER}"
        }
    }
    stages {
        stage('打印动态计算变量') {
            steps {
                echo "运行环境:${RUN_ENV}"    // 分支为 main 则输出 prod,否则 test
                echo "构建标签:${BUILD_TAG}"  // 输出:app-my-app-20260124100000-123
            }
        }
    }
}

4 特殊用法:withEnv临时覆盖(步骤级)

groovy 复制代码
pipeline {
    agent any
    environment {
        ENV_TYPE = 'test'
    }
    stages {
        stage('临时覆盖变量') {
            steps {
                echo "全局变量:${ENV_TYPE}"  // 输出:test
                // 临时覆盖,仅在 withEnv 块内生效
                withEnv(['ENV_TYPE=temp', 'TEMP_VAR=123']) {
                    echo "临时变量:${ENV_TYPE}"  // 输出:temp
                    echo "自定义临时变量:${TEMP_VAR}"  // 输出:123
                }
                echo "回到全局变量:${ENV_TYPE}"  // 输出:test
            }
        }
    }
}
3.2.4.3.1 parameters (选填

parameters 块定义在pipeline 根级别(全局生效),触发流水线时Jenkins会展示参数输入界面,用户填写后参数会被注入到流水线中,可通过params.参数 名或env.参数名引用。支持多种参数类型,覆盖文本输入、选择框、布尔值、文件上传等场景

1 基础文本类参数

(1)string:单行字符串参数(最常用)

用于输入简单文本

groovy 复制代码
pipeline {
    agent any
    parameters {
        // 基础配置:名称、默认值、描述
        string(
            name: 'DEPLOY_ENV', 
            defaultValue: 'test', 
            description: '部署环境(test/prod/pre)'
        )
        // 无默认值(必填)
        string(
            name: 'APP_VERSION', 
            defaultValue: '', 
            description: '应用版本号(必填,如 1.0.0)'
        )
    }
    stages {
        stage('打印字符串参数') {
            steps {
                echo "部署环境:${params.DEPLOY_ENV}"  // 推荐用法
                echo "应用版本:${env.APP_VERSION}"     // 也可通过 env 引用
                sh "echo '部署版本:${params.APP_VERSION}'"  // Shell 中引用
            }
        }
    }
}

(2)text:多行文本参数

用于输入长文本

groovy 复制代码
parameters {
    text(
        name: 'RELEASE_NOTES',
        defaultValue: '本次更新:\n1. 修复XX问题\n2. 新增XX功能',
        description: '发布备注(多行文本)'
    )
}
stages {
    stage('打印发布备注') {
        steps {
            echo "发布备注:\n${params.RELEASE_NOTES}"
            // 写入文件
            sh "echo '${params.RELEASE_NOTES}' > release-notes.txt"
        }
    }
}

(3) password : 密码脱敏

用于输入敏感文本(如密码 令牌)

groovy 复制代码
parameters {
    password(
        name: 'TEMP_TOKEN',
        defaultValue: '',
        description: '临时访问令牌(敏感信息,输入后脱敏)'
    )
}
stages {
    stage('使用密码参数') {
        steps {
            echo "令牌:${params.TEMP_TOKEN}"  // 日志中显示为 ****
            sh "curl -H 'Token: ${params.TEMP_TOKEN}' https://api.example.com"
        }
    }
}

2 选择类参数

(1)choice:下拉选择框

支持单值选择,选择用逗号分隔列表形式定义

groovy 复制代码
parameters {
    // 方式1:逗号分隔选项
    choice(
        name: 'BUILD_TYPE',
        choices: 'debug,release,test',  // 选项列表(逗号分隔,无空格)
        description: '构建类型'
    )
    // 方式2:列表形式(推荐,可读性更高)
    choice(
        name: 'JAVA_VERSION',
        choices: ['8', '11', '17'],
        description: 'JDK 版本'
    )
}
stages {
    stage('执行构建') {
        steps {
            echo "构建类型:${params.BUILD_TYPE}"
            echo "使用 JDK 版本:${params.JAVA_VERSION}"
            // 根据选择执行不同命令
            script {
                if (params.JAVA_VERSION == '8') {
                    sh 'export JAVA_HOME=/usr/lib/jvm/java-8 && mvn clean package'
                } else {
                    sh 'export JAVA_HOME=/usr/lib/jvm/java-17 && mvn clean package'
                }
            }
        }
    }
}

(2) extendedChoice: 扩展选择框(需要插件)

需安装「Extended Choice Parameter」插件,支持多选、级联选择等高级功能。

groovy 复制代码
parameters {
    extendedChoice(
        name: 'MODULES',
        type: 'PT_CHECKBOX',  // 多选框类型
        value: 'user,order,payment,goods',  // 可选模块
        description: '选择要构建的模块(可多选)'
    )
}
stages {
    stage('构建指定模块') {
        steps {
            echo "选中的模块:${params.MODULES}"  // 输出:user,order(多选结果用逗号分隔)
            script {
                def modules = params.MODULES.split(',')
                for (mod in modules) {
                    echo "开始构建模块:${mod}"
                    sh "mvn clean package -pl ${mod} -am"
                }
            }
        }
    }
}

3 布尔值与数值类型参数

适用于开关型选项、数值输入场景

(1)booleanParam: 布尔值参数(开关)

用于【是|否】【执行|跳过】类选择,默认值为true或false

groovy 复制代码
parameters {
    booleanParam(
        name: 'DEPLOY_AFTER_BUILD',
        defaultValue: false,
        description: '构建完成后是否自动部署'
    )
    booleanParam(
        name: 'RUN_TEST',
        defaultValue: true,
        description: '是否执行自动化测试'
    )
}
stages {
    stage('构建项目') {
        steps {
            sh 'mvn clean package'
        }
    }
    stage('自动化测试') {
        when { expression { params.RUN_TEST == true } }  // 条件执行
        steps {
            sh 'mvn test'
        }
    }
    stage('部署项目') {
        when { expression { params.DEPLOY_AFTER_BUILD == true } }
        steps {
            echo "开始部署..."
            sh './deploy.sh'
        }
    }
}

(2) number:数值参数

用于输入整数/小数 可指定范围

groovy 复制代码
parameters {
    number(
        name: 'RETRY_COUNT',
        defaultValue: 3,
        description: '部署失败重试次数(整数)',
        minValue: 1,  // 最小值
        maxValue: 5   // 最大值
    )
    number(
        name: 'TIMEOUT',
        defaultValue: 5.0,
        description: '超时时间(分钟,支持小数)',
        minValue: 1.0,
        maxValue: 10.0
    )
}
stages {
    stage('部署重试配置') {
        steps {
            echo "重试次数:${params.RETRY_COUNT}"
            echo "超时时间:${params.TIMEOUT} 分钟"
            sh "./deploy.sh --retry ${params.RETRY_COUNT} --timeout ${params.TIMEOUT}"
        }
    }
}

4 日期

(1)date:日期参数

需安装「Date Parameter」插件,用于选择日期。

groovy 复制代码
parameters {
    date(
        name: 'RELEASE_DATE',
        defaultValue: new Date().format('yyyy-MM-dd'),  // 默认当前日期
        description: '计划发布日期'
    )
}
stages {
    stage('打印发布日期') {
        steps {
            echo "计划发布日期:${params.RELEASE_DATE}"
        }
    }
}
bash 复制代码
1 参数引用方式:推荐用 params.参数名 引用(语义更清晰),也可通过 env.参数名 引用(兼容旧版本)。
2 参数必填性:Jenkins 原生参数无「必填」配置,若需必填可在 steps 中手动校验
3 参数类型转换:number 参数会自动转为数值类型,string/choice 为字符串类型,booleanParam 为布尔类型,无需手动转换。
groovy 复制代码
script {
    if (params.APP_VERSION.trim() == '') {
        error('APP_VERSION 参数为必填,请输入版本号!')  // 终止流水线并报错
    }
}
3.2.4.3.1 triggers (选填

triggers 块定义在pipeline根级别,支持多种触发方式,可组合使用(如同时配置定时触发和代码提交触发)。不同触发方式依赖不同的Jenkins插件/配置(如代码提交触发需配置SCM仓库)
1 定时触发:cron

基于cron表达式实现定时自动触发,适用于周期性构建(如每日构建/每周巡检)

(1)基础用法

groovy 复制代码
pipeline {
    agent any
    triggers {
        // cron 表达式:分 时 日 月 周(与 Linux cron 语法一致)
        cron('0 2 * * *')  // 每天凌晨 2 点触发
    }
    stages {
        stage('定时构建') {
            steps {
                echo "✅ 定时触发执行,当前时间:${new Date()}"
                sh 'mvn clean package'
            }
        }
    }
}

(2) cron 表达式详解

字段 允许值 特殊字符 说明
0-59 * , - / 每分钟/指定范围/间隔
0-23 * , - / 每小时/指定范围/间隔
1-31 * , - / ? L W 每日/指定日期/最后一天
1-12 * , - / 每月/指定月份
0-7 * , - / ? L # 每周/指定星期

(3) 常用cron示例

groovy 复制代码
triggers {
    cron('*/15 * * * *')        // 每 15 分钟触发一次
    cron('0 8,18 * * *')        // 每天 8 点和 18 点触发
    cron('0 0 * * 1')           // 每周一凌晨 0 点触发
    cron('0 0 1 * *')           // 每月 1 号凌晨 0 点触发
    cron('H 2-4 * * *')         // 每天 2-4 点之间的随机分钟触发(避免集群并发)
}

使用 H(Hash)替代固定数值,可避免多个流水线同时触发导致 Jenkins 负载过高(如 H * * * * 表示每小时随机分钟触发)。

2 代码提交触发:pollSCM

定时检查代码库(如git/SVN)是否提交有新提交,有则触发流水线(需要配置SCM仓库地址)

(1) 基础用法

groovy 复制代码
pipeline {
    agent any
    triggers {
        // 每 5 分钟检查一次代码仓库是否有更新
        pollSCM('H/5 * * * *')
    }
    stages {
        stage('拉取代码并构建') {
            steps {
                git url: 'https://github.com/your/repo.git', branch: 'main'
                echo "📥 检测到代码更新,执行构建"
                sh 'mvn clean package'
            }
        }
    }
}

(2) 注意项

bash 复制代码
1 pollSCM 依赖 SCM 插件(如 Git 插件),需先在流水线中配置 git 步骤或在 Jenkins 任务中绑定代码仓库;
2 与 cron 区别:cron 是「定时执行」,不管代码是否更新;pollSCM 是「定时检查 + 有更新才执行」;
3 推荐用法:结合 H 避免固定时间检查(如 H/10 * * * * 每 10 分钟随机检查)。

3 Webhook 触发

Jenkins 本身没有 webhook 原生触发指令,但可通过「Generic Webhook Trigger」插件实现代码提交 / 第三方事件的 WebHook 触发(替代 pollSCM,更高效)。

(1)配置步骤

a 安装「Generic Webhook Trigger」插件;

b 在 triggers 中启用,并配置 token:

groovy 复制代码
pipeline {
    agent any
    triggers {
        // 启用 WebHook 触发
        genericTrigger(
            genericVariables: [
                [key: 'ref', value: '$.ref']  // 提取 WebHook 中的 ref 字段(如分支名)
            ],
            token: 'my-webhook-token',  // WebHook 令牌(自定义,用于验证)
            printContributedVariables: true,
            printPostContent: true
        )
    }
    stages {
        stage('WebHook 触发构建') {
            steps {
                echo "🔔 收到 WebHook 触发,分支:${ref}"
                git url: 'https://github.com/your/repo.git', branch: "${ref.replace('refs/heads/', '')}"
                sh 'mvn clean package'
            }
        }
    }
}

c 在代码仓库(如 GitHub/GitLab)配置 WebHook 地址:http://<Jenkins地址>/generic-webhook-trigger/invoke?token=my-webhook-token。

3.2.4.3.1 options (选填

1 执行控制类

(1)timeout:设置执行超时时间

避免流水线/阶段无限阻塞(如网络问题、命令卡死),超时后自动终止并标记为失败

groovy 复制代码
pipeline {
    agent any
    // 全局超时:整个流水线最多执行 30 分钟
    options {
        timeout(time: 30, unit: 'MINUTES')  // 支持 SECONDS/MINUTES/HOURS/DAYS
    }
    stages {
        stage('构建项目') {
            steps {
                sh 'mvn clean package'
            }
        }
        // 阶段级超时:覆盖全局,仅该阶段最多执行 10 分钟
        stage('部署到远程服务器') {
            options {
                timeout(time: 10, unit: 'MINUTES')
            }
            steps {
                sh './deploy-remote.sh'
            }
        }
    }
}

(2) retry: 失败后重试

对易失败的操作(如网络依赖的部署)设置重试次数,提升成功率

groovy 复制代码
pipeline {
    agent any
    stages {
        stage('部署项目') {
            options {
                retry(3)  // 失败后重试 3 次(总计执行 4 次)
            }
            steps {
                echo "第 ${env.BUILD_ATTEMPT} 次部署"  // 内置变量:当前重试次数
                sh './deploy.sh'
            }
        }
    }
}

retry 会重试整个stage的所有steps,需要保步骤是【幂等】的(重复执行无副作用)

(3) parallelsAlwaysFailFast:并行阶段快速失败

当并行阶段中有任意一个失败时,立即终止其他并行阶段,避免资源浪费

groovy 复制代码
pipeline {
    agent any
    options {
        parallelsAlwaysFailFast()  // 全局开启并行快速失败
    }
    stages {
        stage('并行测试') {
            parallel {
                stage('单元测试') {
                    steps { sh 'mvn test -Dtest=UnitTest*' }
                }
                stage('接口测试') {
                    steps { sh 'mvn test -Dtest=ApiTest*' }  // 若该阶段失败,单元测试会立即终止
                }
            }
        }
    }
}

2 构建历史/资源管理类

(1) buildDiscarder: 保留构建历史

限制保留的构建数量/时长,避免Jenkins磁盘空间耗尽

groovy 复制代码
pipeline {
    agent any
    options {
        // 保留最近 30 次构建,或保留 7 天内的构建(满足其一即删除)
        buildDiscarder(logRotator(
            numToKeepStr: '30',    // 保留构建次数
            daysToKeepStr: '7',    // 保留天数
            artifactNumToKeepStr: '10',  // 保留产物的构建次数
            artifactDaysToKeepStr: '3'   // 保留产物的天数
        ))
    }
    stages {
        stage('构建') { steps { sh 'mvn clean package' } }
    }
}

(2)skipDefaultCheckout:跳过默认代码拉取

当流水线中手动配置 git 步骤时,跳过 Jenkins 自动执行的 checkout scm 操作(避免重复拉取)

groovy 复制代码
pipeline {
    agent any
    options {
        skipDefaultCheckout()  // 禁用默认的代码拉取
    }
    stages {
        stage('拉取代码') {
            steps {
                // 手动拉取指定分支,替代默认拉取
                git url: 'https://github.com/your/repo.git', branch: 'main', clean: true
            }
        }
    }
}

(3) customWorkspace: 自定义工作目录

指定流水线的工作目录(默认是 Jenkins 全局工作目录),适用于多项目隔离、特定路径依赖场景。

groovy 复制代码
pipeline {
    agent any
    options {
        customWorkspace '/opt/jenkins/workspace/my-project-prod'  // 全局自定义工作目录
    }
    stages {
        stage('检查工作目录') {
            steps {
                echo "当前工作目录:${env.WORKSPACE}"  // 输出:/opt/jenkins/workspace/my-project-prod
            }
        }
    }
}

3 UI/通知类

(1) timestamps 日志添加时间戳

在所有日志输出前添加时间戳

groovy 复制代码
pipeline {
    agent any
    options {
        timestamps()  // 全局日志添加时间戳
    }
    stages {
        stage('构建') {
            steps {
                echo "开始构建"  // 日志显示:[2026-01-24 10:00:00] 开始构建
                sh 'sleep 5 && echo "构建完成"'
            }
        }
    }
}

(2) ansiColor:支持 ANSI 颜色输出

让 Shell 命令的彩色输出在 Jenkins 日志中正常显示(需安装「AnsiColor」插件)

groovy 复制代码
pipeline {
    agent any
    options {
        ansiColor('xterm')  // 启用 xterm 颜色模式
    }
    stages {
        stage('彩色日志') {
            steps {
                // Shell 彩色输出会在 Jenkins 中正常显示
                sh 'echo -e "\\033[32m✅ 构建成功(绿色)\\033[0m"'
                sh 'echo -e "\\033[31m❌ 构建失败(红色)\\033[0m"'
            }
        }
    }
}

4 其他实用选项

(1) skipStagesAfterUnstable:流水线不稳定时跳过后续阶段

groovy 复制代码
pipeline {
    agent any
    options {
        skipStagesAfterUnstable()
    }
    stages {
        stage('测试') {
            steps {
                catchError(buildResult: 'UNSTABLE') {
                    sh 'mvn test'  // 测试失败标记为 UNSTABLE
                }
            }
        }
        stage('部署') {
            steps {
                echo "该阶段会被跳过"  // 因前序阶段导致流水线 UNSTABLE
            }
        }
    }
}
3.2.4.3.1 post (选填
bash 复制代码
post 可定义在两个层级:
1 全局级:pipeline 根级别,流水线所有阶段执行完成后触发;
2 阶段级:stage 内部,仅当前阶段执行完成后触发。

1 核心条件字句

条件子句 触发机制 优先级
always 无论流水线/阶段结果如何,始终执行 最低
success 流水线/阶段执行成功(状态为SUCCESS)时执行 中等
failure 流水线/阶段执行失败(状态为FAILURE)时执行 中等
unstable 流水线/阶段不稳定(状态为UNSTABLE)时执行 中等
aborted 流水线/阶段被手动中止(状态为ABORTED)时执行 中等
chaned 本次构建结果与上一次相比发生时执行 最高

执行顺序:post 内的条件子句按「优先级从高到低」执行(changed > success/failure/unstable/aborted > always)

2 基础用法:全局级post(流水线收尾)

适用于整个流水线执行完成后的统一收尾(如发送最终通知、清理全局资源)。

groovy 复制代码
pipeline {
    agent any
    stages {
        stage('构建') { steps { sh 'mvn clean package' } }
        stage('测试') { steps { sh 'mvn test' } }
        stage('部署') { steps { sh './deploy.sh' } }
    }
    // 全局后置操作(流水线所有阶段完成后执行)
    post {
        // 成功时执行:发送成功通知
        success {
            echo "✅ 流水线执行成功!构建号:${env.BUILD_NUMBER}"
            // 发送邮件通知(需 Email Extension 插件)
            emailext(
                to: 'dev-team@example.com',
                subject: "✅ 流水线 ${env.JOB_NAME} 执行成功(构建号:${env.BUILD_NUMBER})",
                body: "流水线执行完成,结果:成功\n构建地址:${env.BUILD_URL}"
            )
        }
        
        // 失败时执行:发送失败告警
        failure {
            echo "❌ 流水线执行失败!"
            emailext(
                to: 'dev-team@example.com',
                subject: "❌ 流水线 ${env.JOB_NAME} 执行失败(构建号:${env.BUILD_NUMBER})",
                body: "流水线执行失败,请及时排查!\n构建地址:${env.BUILD_URL}"
            )
        }
        
        // 不稳定时执行(如测试失败但构建成功)
        unstable {
            echo "⚠️ 流水线执行不稳定(如测试失败)!"
        }
        
        // 始终执行:清理工作目录、归档日志
        always {
            echo "📝 流水线执行完成,开始清理资源"
            deleteDir()  // 删除当前工作目录
            archiveArtifacts artifacts: 'logs/*.log', allowEmptyArchive: true  // 归档日志文件
        }
        
        // 结果变化时执行(如上次失败本次成功)
        changed {
            echo "🔄 本次构建结果与上次相比发生变化!"
            emailext(to: 'admin@example.com', subject: "🔄 流水线结果变化", body: "构建地址:${env.BUILD_URL}")
        }
    }
}

3 进阶用法:阶段级 post(阶段收尾)

适用于单个阶段执行完成后的差异化收尾(如构建阶段成功后归档产物,测试阶段失败后保存报告)。

groovy 复制代码
pipeline {
    agent any
    stages {
        stage('构建项目') {
            steps {
                sh 'mvn clean package'
            }
            // 阶段级后置操作(仅构建阶段完成后执行)
            post {
                success {
                    echo "✅ 构建成功,归档产物"
                    archiveArtifacts artifacts: 'target/*.jar', fingerprint: true  // 归档 JAR 包
                }
                failure {
                    echo "❌ 构建失败,保存构建日志"
                    archiveArtifacts artifacts: 'target/logs/build-*.log'  // 保存失败日志
                }
                always {
                    echo "📌 构建阶段执行完成"
                }
            }
        }
        
        stage('自动化测试') {
            steps {
                sh 'mvn test'
            }
            post {
                unstable {
                    echo "⚠️ 测试有失败用例,归档测试报告"
                    publishHTML(target: [
                        allowMissing: false,
                        alwaysLinkToLastBuild: false,
                        keepAll: true,
                        reportDir: 'target/site/junit',
                        reportFiles: 'index.html',
                        reportName: '测试报告'
                    ])  // 发布测试报告到 Jenkins 界面
                }
            }
        }
    }
}

4 实用场景:多条件组合+第三方通知

结合企业微信 / 钉钉 / 飞书等工具发送通知,适配生产环境的告警需求(需安装对应插件或调用 API)。

groovy 复制代码
pipeline {
    agent any
    stages {
        stage('部署生产环境') { steps { sh './deploy-prod.sh' } }
    }
    post {
        success {
            // 调用企业微信机器人发送通知(通过 Shell 调用 API)
            sh '''
                curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=your-key' \
                -H 'Content-Type: application/json' \
                -d '{
                    "msgtype": "text",
                    "text": {
                        "content": "✅ 生产环境部署成功!\\n构建号:'''${env.BUILD_NUMBER}'\\n地址:'''${env.BUILD_URL}'"
                    }
                }'
            '''
        }
        failure {
            // 钉钉机器人告警
            sh '''
                curl 'https://oapi.dingtalk.com/robot/send?access_token=your-token' \
                -H 'Content-Type: application/json' \
                -d '{
                    "msgtype": "markdown",
                    "markdown": {
                        "title": "生产环境部署失败",
                        "text": "### ❌ 生产环境部署失败\\n> 构建号:'''${env.BUILD_NUMBER}'\\n> 地址:[''${env.JOB_NAME}'']('''${env.BUILD_URL}')"
                    }
                }'
            '''
        }
    }
}

依赖插件

发送邮件需「Email Extension Plugin」;

发布 HTML 报告需「HTML Publisher Plugin」;

3.2.4.3.1 when (选填

when 块定义在 stage 内部,仅在该阶段开始执行前判断条件:条件满足则执行阶段,不满足则跳过(标记为「Skipped」)。它支持单条件、多条件组合、嵌套条件,还能结合内置函数实现复杂判断。

1 基础条件

(1)branch:判断代码分支

仅当流水线关联的代码分支匹配指定值时执行阶段(需配置 SCM 仓库,如 Git)。

groovy 复制代码
pipeline {
    agent any
    stages {
        // 仅主分支执行部署
        stage('部署生产环境') {
            when {
                branch 'main'  // 分支名完全匹配
            }
            steps {
                echo "🚀 主分支执行生产环境部署"
                sh './deploy-prod.sh'
            }
        }
        // 仅开发分支执行测试
        stage('执行自动化测试') {
            when {
                branch 'develop'
            }
            steps {
                sh 'mvn test'
            }
        }
    }
}

支持通配符:branch 'feature/*'(匹配所有 feature 开头的分支)。

(2) expression:自定义groovy表达式(最灵活)

通过 Groovy 布尔表达式实现任意逻辑判断,支持引用参数、环境变量、内置变量,覆盖 80% 以上复杂场景。

groovy 复制代码
pipeline {
    agent any
    parameters {
        booleanParam(name: 'DEPLOY', defaultValue: false, description: '是否部署')
        string(name: 'ENV', defaultValue: 'test', description: '部署环境')
    }
    stages {
        // 参数为 true 且环境为 prod 时执行
        stage('部署生产环境') {
            when {
                expression { params.DEPLOY == true && params.ENV == 'prod' }
            }
            steps {
                sh './deploy-prod.sh'
            }
        }
        // 构建号为偶数时执行
        stage('偶数构建号特殊处理') {
            when {
                expression { env.BUILD_NUMBER.toInteger() % 2 == 0 }
            }
            steps {
                echo "构建号 ${env.BUILD_NUMBER} 是偶数,执行特殊逻辑"
            }
        }
    }
}

(3) environment:判断环境变量

仅当指定环境变量匹配值时执行阶段。

groovy 复制代码
pipeline {
    agent any
    environment {
        RUN_TYPE = 'release'  // 自定义环境变量
    }
    stages {
        stage('打包发布包') {
            when {
                environment name: 'RUN_TYPE', value: 'release'  // 环境变量匹配
            }
            steps {
                sh 'mvn clean package -Dpackaging=zip'
            }
        }
    }
}

(4) booleanParam:判断布尔参数

专门用于判断布尔类型的流水线参数(简化 expression 写法)。

groovy 复制代码
pipeline {
    agent any
    parameters {
        booleanParam(name: 'RUN_TEST', defaultValue: true, description: '是否执行测试')
    }
    stages {
        stage('自动化测试') {
            when {
                booleanParam(name: 'RUN_TEST', value: true)
            }
            steps {
                sh 'mvn test'
            }
        }
    }
}

2 多条件组合

通过 allOf/anyOf/not 实现多条件的「与 / 或 / 非」逻辑,适配复杂场景。

(1)allOf:所有条件都满足(逻辑与)

groovy 复制代码
stage('部署生产环境') {
    when {
        allOf {
            branch 'main'                  // 分支为 main
            expression { params.DEPLOY == true }  // 部署参数为 true
            environment name: 'BUILD_STATUS', value: 'success'  // 构建状态成功
        }
    }
    steps {
        sh './deploy-prod.sh'
    }
}

(2) anyOf:任意一个条件满足(逻辑或)

groovy 复制代码
stage('执行快速测试') {
    when {
        anyOf {
            branch 'feature/*'  // 特性分支
            branch 'hotfix/*'   // 热修复分支
        }
    }
    steps {
        sh 'mvn test -Dquick=true'  // 仅执行快速测试
    }
}

(3) not:条件不满足(逻辑非)

groovy 复制代码
stage('跳过发布检查') {
    when {
        not {
            branch 'main'  // 非主分支时执行
        }
    }
    steps {
        echo "非主分支,跳过发布检查"
    }
}

(4) 嵌套组合

groovy 复制代码
stage('复杂条件部署') {
    when {
        allOf {
            branch 'main'
            anyOf {
                expression { params.EMERGENCY_DEPLOY == true }  // 紧急部署
                expression { new Date().getDay() == 5 }         // 周五
            }
            not {
                environment name: 'SKIP_DEPLOY', value: 'true'  // 未标记跳过
            }
        }
    }
    steps {
        sh './deploy-prod.sh'
    }
}
3.2.4.4 声明式脚本中使用脚本式的语法

script 块可出现在声明式的 steps 内(最常用),也可在 post、when 的 expression 中(本质也是脚本式语法)

1 基础用法:在 steps 中嵌入脚本式逻辑

这是最核心的用法,用于实现声明式原生语法无法覆盖的复杂逻辑(如循环、多分支判断、动态变量)。

groovy 复制代码
pipeline {
    agent any
    parameters {
        booleanParam(name: 'DEPLOY', defaultValue: false, description: '是否部署')
        choice(name: 'ENV', choices: ['test', 'prod', 'pre'], description: '部署环境')
    }
    stages {
        stage('复杂逻辑处理') {
            steps {
                // 声明式原生步骤(如 echo、sh)
                echo "开始执行复杂逻辑"
                
                // script 块:嵌入脚本式语法
                script {
                    // 1. 变量定义与赋值(脚本式核心)
                    def buildNum = env.BUILD_NUMBER  // 引用内置环境变量
                    def appName = "my-app-${buildNum}"
                    def deployEnv = params.ENV  // 引用声明式参数
                    
                    // 2. 条件判断(if-else)
                    if (params.DEPLOY) {
                        echo "✅ 确认部署,目标环境:${deployEnv}"
                        
                        // 3. 多分支判断(switch)
                        switch (deployEnv) {
                            case 'test':
                                sh './deploy-test.sh'  // 执行测试环境部署
                                break
                            case 'prod':
                                // 4. 嵌套条件:生产环境需二次确认
                                def confirm = input message: '确认部署生产环境?', ok: '确认'
                                sh './deploy-prod.sh'
                                break
                            case 'pre':
                                sh './deploy-pre.sh'
                                break
                        }
                    } else {
                        echo "🔍 跳过部署,仅执行构建"
                        sh 'mvn clean package'
                    }
                    
                    // 5. 循环(for/while)
                    echo "📝 打印 3 次构建信息"
                    for (int i = 1; i <= 3; i++) {
                        echo "第 ${i} 次:应用名称=${appName},构建号=${buildNum}"
                    }
                    
                    // 6. 异常捕获(try-catch)
                    try {
                        sh './check-health.sh'  // 执行健康检查
                    } catch (Exception e) {
                        echo "❌ 健康检查失败:${e.getMessage()}"
                        // 手动标记流水线状态(脚本式核心能力)
                        currentBuild.result = 'UNSTABLE'  // 标记为不稳定,而非直接失败
                    }
                }
                
                // 回到声明式原生步骤
                echo "复杂逻辑执行完成"
            }
        }
    }
}

2 进阶用法:动态生成步骤 / 阶段

通过脚本式语法动态生成声明式的步骤或阶段(如根据参数动态执行不同命令、动态创建并行阶段)。

(1) 动态执行命令

groovy 复制代码
pipeline {
    agent any
    parameters {
        string(name: 'MODULES', defaultValue: 'user,order', description: '要构建的模块(逗号分隔)')
    }
    stages {
        stage('动态构建模块') {
            steps {
                script {
                    // 拆分参数为列表(脚本式语法)
                    def modules = params.MODULES.split(',')
                    
                    // 遍历模块,动态执行构建命令
                    for (mod in modules) {
                        def cleanMod = mod.trim()  // 去除空格
                        echo "🔨 开始构建模块:${cleanMod}"
                        // 动态执行 sh 命令(声明式步骤也可在 script 内调用)
                        sh "mvn clean package -pl ${cleanMod} -am"
                    }
                }
            }
        }
    }
}

(2) 动态创建并行阶段

声明式的 parallel 块本身是静态的,通过 script 可动态生成并行阶段(脚本式核心能力):

groovy 复制代码
pipeline {
    agent any
    stages {
        stage('动态并行测试') {
            steps {
                script {
                    // 定义并行阶段的映射(脚本式语法)
                    def testStages = [:]  // 空映射,用于存储并行阶段
                    
                    // 动态添加并行阶段
                    testStages['单元测试'] = { sh 'mvn test -Dtest=UnitTest*' }
                    testStages['接口测试'] = { sh 'mvn test -Dtest=ApiTest*' }
                    testStages['UI测试'] = { sh 'npm run test:ui' }
                    
                    // 执行并行阶段(脚本式 parallel 命令)
                    parallel testStages
                }
            }
        }
    }
}

3 特殊场景:在 expression/when 中使用脚本式语法

声明式 when 的 expression 块本质就是脚本式语法,可直接使用 Groovy 逻辑:

groovy 复制代码
pipeline {
    agent any
    stages {
        stage('条件执行(脚本式语法)') {
            when {
                // expression 内直接使用脚本式 Groovy 语法
                expression {
                    // 组合判断:构建号为偶数 + 分支为 main
                    env.BUILD_NUMBER.toInteger() % 2 == 0 && env.GIT_BRANCH == 'main'
                }
            }
            steps {
                echo "满足脚本式条件,执行该阶段"
            }
        }
    }
}

4 高级用法:脚本式语法操作流水线状态 / 上下文

在 script 内可通过 currentBuild 等内置对象操作流水线的核心状态(声明式原生语法无法直接实现)

groovy 复制代码
pipeline {
    agent any
    stages {
        stage('操作流水线状态') {
            steps {
                script {
                    // 1. 设置流水线显示名称
                    currentBuild.displayName = "Build-${env.BUILD_NUMBER}-${params.ENV}"
                    
                    // 2. 设置流水线描述
                    currentBuild.description = "部署环境:${params.ENV},执行人:${env.BUILD_USER}"
                    
                    // 3. 手动设置流水线结果
                    if (someCondition) {
                        currentBuild.result = 'SUCCESS'  // 成功
                    } else if (someWarning) {
                        currentBuild.result = 'UNSTABLE'  // 不稳定
                    } else {
                        currentBuild.result = 'FAILURE'  // 失败
                    }
                    
                    // 4. 中止流水线(脚本式核心能力)
                    if (params.ABORT) {
                        error("用户手动触发中止,流水线终止")  // 抛出异常中止
                    }
                }
            }
        }
    }
}

作用域隔离:script 内定义的变量(如 def appName)仅在 script 块内生效,若需跨 script 块 / 阶段使用,需定义为全局变量(在 pipeline 外定义):

groovy 复制代码
// 全局变量(所有 stage/script 块可访问)
def globalAppName = "my-global-app"

pipeline {
    agent any
    stages {
        stage('Test') {
            steps {
                script {
                    globalAppName += "-v1"  // 修改全局变量
                }
                echo "全局变量:${globalAppName}"  // 输出:my-global-app-v1
            }
        }
    }
}

script 内可调用声明式的所有步骤(如 echo、sh、archiveArtifacts);

when 的 expression、environment 的 expression 本质是脚本式语法,无需额外 script 块。

3.2.5 脚本式使用流程 (不做特别详细的介绍)

参考链接

4 配置agent节点(从节点主机slave)

5 使用agent节点运行脚本

5.1 使用windows agent 运行ui自动化脚本

相关推荐
凯子坚持 c2 小时前
Qt常用控件指南(3)
运维·服务器
求真求知的糖葫芦2 小时前
简明微波2-12耦合传输线分析学习笔记(五)对称均匀耦合线Z参数矩阵推导
笔记·学习·矩阵·射频工程
闲过信陵饮~2 小时前
ubuntu24 安装向日葵远程软件报错
linux·运维·ubuntu
Dovis(誓平步青云)2 小时前
《优化算法效率的利器:双指针的原理、变种与边界处理》
linux·运维·算法·功能详解
wechat_Neal2 小时前
供应商合作模式中以产品中心取向的转型要点
运维·汽车·devops
188号安全攻城狮2 小时前
【PWN】HappyNewYearCTF_2_栈上变量覆写1
linux·运维·汇编·安全·网络安全
寻址000000012 小时前
华三(H3C)交换机基本运维命令及配置案例说明
运维·网络
QiZhang | UESTC2 小时前
学习日记day67
学习
码农阿豪2 小时前
实战指南:高效批量测试SSH连接的最佳实践与避坑手册
运维·ssh