Jenkins Pipeline语法详解:从基础到高级应用的完整指南

1. Pipeline执行模型深度解析

1.1 Pipeline核心架构

Jenkins Pipeline是Jenkins 2.0引入的核心特性,它将CI/CD流程以代码形式定义,实现了"Pipeline as Code"的理念。Pipeline基于Groovy脚本语言构建,通过CPS(Continuation Passing Style)转换实现持久化和恢复能力。

Pipeline执行引擎

FlowNode执行层

Stage节点

Step节点

Parallel节点

Matrix节点

CPS转换层

语法树分析

续体生成

状态序列化

Groovy脚本

CPS转换器

FlowNode执行器

FlowGraph DAG

执行队列

Executor执行

日志收集

结果持久化

技术原理说明:

组件 职责 技术实现
CPS转换器 将Groovy脚本转换为可序列化的续体形式 ASM字节码操作、Groovy AST转换
FlowNode Pipeline执行的最小单元,代表一个步骤或阶段 有向无环图(DAG)节点
FlowGraph Pipeline执行的完整流程图,记录节点间依赖关系 邻接表存储结构
CpsFlowExecution Pipeline执行的核心控制器,管理执行状态 状态机模式

1.2 CPS转换机制详解

CPS(Continuation Passing Style)是Pipeline能够实现持久化和恢复的核心技术。当Pipeline执行过程中Jenkins重启或发生中断时,CPS机制能够保存当前执行状态,并在恢复后继续执行。

/**
 * CPS转换示例说明
 * 
 * 原始Groovy代码:
 * def result = compute(1, 2)
 * println result
 * 
 * CPS转换后(伪代码):
 * compute(1, 2, new Continuation() {
 *     Object receive(Object result) {
 *         println result
 *         return null
 *     }
 * })
 */

// Pipeline中的CPS限制示例
pipeline {
    agent any
    stages {
        stage('CPS Demo') {
            steps {
                script {
                    // ✅ 正确:使用Pipeline兼容的语法
                    def result = sh(script: 'echo 42', returnStdout: true).trim()
                    echo "Result: ${result}"
                    
                    // ❌ 错误:非CPS兼容的操作
                    // def file = new File('/tmp/test.txt')
                    // file.text = 'hello'  // 文件操作在CPS中不支持
                    
                    // ✅ 正确:使用Pipeline提供的文件操作Step
                    writeFile file: '/tmp/test.txt', text: 'hello'
                }
            }
        }
    }
}

1.3 FlowNode执行流程

持久化存储 Step执行 FlowNode 执行器 构建队列 用户触发 持久化存储 Step执行 FlowNode 执行器 构建队列 用户触发 loop [遍历FlowGraph] 每个节点执行后都会持久化状态,支持中断恢复 提交构建请求 分配执行器 创建Root FlowNode 获取下一个节点 保存节点状态 执行Step 返回执行结果 更新节点状态 执行完成 释放执行器 返回构建结果

FlowNode状态持久化机制:

// FlowNode状态持久化核心逻辑(源码解析)
public class FlowNode {
    // 节点唯一标识
    private final String id;
    
    // 父节点引用(构成DAG)
    private final List<FlowNode> parents;
    
    // 节点执行状态
    private FlowNodeStatus status;
    
    // 持久化到磁盘
    public void save() {
        // 序列化节点状态到 build.xml
        // 路径: JENKINS_HOME/jobs/{job}/builds/{build}/build.xml
        getXStream().toXML(this, new FileOutputStream(getStateFile()));
    }
    
    // 从磁盘恢复
    public static FlowNode load(String id) {
        return (FlowNode) getXStream().fromXML(new FileInputStream(getStateFile()));
    }
}

2. 声明式与脚本式Pipeline对比分析

2.1 两种范式对比

Jenkins Pipeline提供两种语法范式:声明式(Declarative)脚本式(Scripted)。两种范式各有优劣,适用于不同场景。

适用场景

适用场景

脚本式Pipeline

Groovy脚本

完全灵活

运行时验证

高级定制

声明式Pipeline

结构化语法

预定义块

编译时验证

易于维护

标准CI/CD流程

复杂逻辑处理

2.2 详细对比表

特性维度 声明式Pipeline 脚本式Pipeline
语法结构 结构化、预定义块 Groovy脚本、自由形式
学习曲线 低,易于上手 高,需要Groovy知识
错误检测 编译时检测,错误提示友好 运行时检测,调试困难
灵活性 受限,遵循规范 高,完全自由
代码可读性 高,结构清晰 依赖编码规范
IDE支持 较好,有语法高亮 一般,Groovy支持
适用场景 标准CI/CD流程、团队协作 复杂逻辑、高级定制
重启恢复 完全支持 完全支持
Blue Ocean 完美支持 部分支持

2.3 声明式Pipeline完整示例

/**
 * 声明式Pipeline完整示例
 * 演示所有核心指令的使用方法
 * 
 * 环境要求:
 * - Jenkins LTS 2.400+
 * - Pipeline: Declarative Plugin 2.40+
 * - 相关Agent节点已配置
 */
pipeline {
    // ==================== Agent配置 ====================
    // 必选:定义Pipeline执行位置
    // any: 任意可用节点
    // none: 不指定,各stage单独指定
    // label 'xxx': 指定标签节点
    // docker { image 'xxx' }: Docker容器
    // kubernetes { yaml '...' }: Kubernetes Pod
    agent any
    
    // ==================== 环境变量 ====================
    // 可选:定义Pipeline级别环境变量
    // 支持静态值、动态表达式、凭证注入
    environment {
        // 静态值定义
        APP_NAME = 'my-application'
        VERSION = '1.0.0'
        
        // 动态表达式(Groovy语法)
        BUILD_TIME = "${new Date().format('yyyy-MM-dd_HH-mm-ss')}"
        GIT_COMMIT_SHORT = sh(
            script: 'git rev-parse --short HEAD 2>/dev/null || echo "unknown"',
            returnStdout: true
        ).trim()
        
        // 凭证注入 - 用户名密码类型
        // 自动创建: DB_CREDS_USR 和 DB_CREDS_PSW 变量
        DB_CREDS = credentials('database-credentials')
        
        // 凭证注入 - Secret Text类型
        API_KEY = credentials('api-secret-key')
        
        // 凭证注入 - 分别获取用户名密码
        DB_USER = credentials('database-credentials').username
        DB_PASS = credentials('database-credentials').password
    }
    
    // ==================== 构建参数 ====================
    // 可选:定义构建参数,支持多种类型
    parameters {
        // 字符串参数
        string(
            name: 'BRANCH_NAME',           // 参数名称(必选)
            defaultValue: 'main',          // 默认值(可选)
            description: 'Git分支名称',     // 描述(可选)
            trim: true                     // 是否去除首尾空格(可选,默认false)
        )
        
        // 布尔参数
        booleanParam(
            name: 'DEPLOY_ENABLED',
            defaultValue: false,
            description: '是否执行部署'
        )
        
        // 选择参数
        choice(
            name: 'DEPLOY_ENV',
            choices: ['development', 'staging', 'production'],
            description: '部署环境选择'
        )
        
        // 密码参数(加密存储)
        password(
            name: 'SECRET_TOKEN',
            defaultValue: '',
            description: '安全令牌'
        )
        
        // 文本参数(多行文本)
        text(
            name: 'RELEASE_NOTES',
            defaultValue: '',
            description: '发布说明'
        )
        
        // 运行参数(选择其他构建)
        run(
            name: 'UPSTREAM_BUILD',
            projectName: 'upstream-job-name',
            description: '选择上游构建',
            filter: 'SUCCESSFUL'  // 可选值: ALL, SUCCESSFUL, FAILED, UNSTABLE
        )
        
        // 文件参数(上传文件)
        file(
            name: 'CONFIG_FILE',
            description: '上传配置文件'
        )
    }
    
    // ==================== 触发器配置 ====================
    // 可选:定义自动触发规则
    triggers {
        // Cron定时触发
        // 格式: 分 时 日 月 周
        // H表示哈希值,避免同时触发
        cron('H/15 * * * *')  // 每15分钟执行一次
        
        // SCM轮询触发
        // 检测代码仓库变化时触发
        pollSCM('H/5 * * * *')  // 每5分钟检查一次
        
        // 上游项目触发
        // 当指定项目完成时触发
        upstream(
            upstreamProjects: 'build-job, test-job',
            threshold: hudson.model.Result.SUCCESS  // 触发阈值
        )
        
        // GitHub Webhook触发
        githubPush()
        
        // GitLab Webhook触发
        gitlab(
            triggerOnPush: true,
            triggerOnMergeRequest: true,
            branchFilterType: 'All'
        )
        
        // Bitbucket Webhook触发
        bitbucketPush()
    }
    
    // ==================== 工具配置 ====================
    // 可选:自动配置构建工具到PATH
    // 需要在"全局工具配置"中预先定义
    tools {
        // Maven配置
        maven 'Maven-3.9.5'  // 全局工具配置中的名称
        
        // JDK配置
        jdk 'JDK-17'
        
        // Gradle配置
        gradle 'Gradle-8.4'
        
        // Node.js配置
        nodejs 'NodeJS-18'
        
        // Git配置
        git 'Git-2.42'
    }
    
    // ==================== Pipeline选项 ====================
    // 可选:Pipeline级别配置选项
    options {
        // 构建超时设置
        timeout(
            time: 1,
            unit: 'HOURS'  // 可选值: NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS
        )
        
        // 失败重试次数
        retry(3)
        
        // 跳过默认的SCM检出
        skipDefaultCheckout(true)
        
        // 禁止并发构建
        disableConcurrentBuilds(
            abortPrevious: false  // 是否中止前一个构建,默认false
        )
        
        // 构建历史管理
        buildDiscarder(
            logRotator(
                numToKeepStr: '20',           // 保留构建数量
                daysToKeepStr: '30',          // 保留天数
                artifactNumToKeepStr: '5',    // 保留制品数量
                artifactDaysToKeepStr: '7'    // 制品保留天数
            )
        )
        
        // 时间戳输出
        timestamps()
        
        // ANSI颜色输出
        ansiColor('xterm')  // 可选值: xterm, vga, css, gnome-terminal
        
        // 静默期(秒)
        quietPeriod(10)
        
        // 构建变为不稳定后跳过后续阶段
        skipStagesAfterUnstable()
        
        // 并行阶段快速失败
        // 任一并行阶段失败立即中止其他
        parallelsAlwaysFailFast()
        
        // 构建速率限制
        rateLimitBuilds(
            throttle: [
                count: 2,
                durationName: 'hour',
                userBoost: true  // 用户手动触发是否豁免
            ]
        )
        
        // 资源锁定
        lock(resource: 'deploy-lock')
        
        // 自定义工作空间
        customWorkspace('workspace/my-project')
    }
    
    // ==================== 输入配置 ====================
    // 可选:Pipeline级别输入确认
    input {
        message "确认部署到生产环境?"
        id "deploy-approval"           // 唯一标识符
        ok "确认部署"                  // 确认按钮文本
        submitter "admin,ops-team"     // 允许提交的用户/组
        submitterParameter "APPROVER"  // 提交者存入变量名
        parameters {
            string(name: 'DEPLOY_VERSION', defaultValue: '1.0.0')
            booleanParam(name: 'SKIP_TESTS', defaultValue: false)
        }
    }
    
    // ==================== 阶段定义 ====================
    // 必选:定义构建阶段
    stages {
        stage('代码检出') {
            // Stage级别选项
            options {
                timeout(time: 5, unit: 'MINUTES')
                retry(2)
            }
            
            // Stage级别环境变量
            environment {
                GIT_URL = 'https://github.com/company/project.git'
            }
            
            steps {
                script {
                    echo "开始检出代码: ${env.GIT_URL}"
                }
                checkout scm
            }
        }
        
        stage('构建') {
            agent {
                docker {
                    image 'maven:3.9.5-eclipse-temurin-17'
                    args '-v $HOME/.m2:/root/.m2 -e MAVEN_OPTS=-Xmx2g'
                }
            }
            
            steps {
                sh 'mvn clean package -DskipTests'
            }
        }
        
        stage('测试') {
            parallel {
                stage('单元测试') {
                    steps {
                        sh 'mvn test'
                    }
                    post {
                        always {
                            junit '**/target/surefire-reports/*.xml'
                        }
                    }
                }
                
                stage('集成测试') {
                    steps {
                        sh 'mvn verify -P integration-test'
                    }
                    post {
                        always {
                            junit '**/target/failsafe-reports/*.xml'
                        }
                    }
                }
                
                stage('代码质量') {
                    steps {
                        withSonarQubeEnv('SonarQube') {
                            sh 'mvn sonar:sonar'
                        }
                    }
                }
            }
        }
        
        stage('部署') {
            when {
                allOf {
                    branch 'main'
                    expression { params.DEPLOY_ENABLED == true }
                }
            }
            
            steps {
                sh './deploy.sh ${params.DEPLOY_ENV}'
            }
        }
    }
    
    // ==================== 构建后处理 ====================
    // 可选:定义构建后操作
    post {
        // 总是执行
        always {
            cleanWs()  // 清理工作空间
            archiveArtifacts artifacts: 'target/*.jar', fingerprint: true
        }
        
        // 成功时执行
        success {
            emailext(
                subject: "✅ 构建成功: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
                body: """
                    <h2>构建成功</h2>
                    <p><strong>项目:</strong> ${env.JOB_NAME}</p>
                    <p><strong>构建号:</strong> ${env.BUILD_NUMBER}</p>
                    <p><strong>持续时间:</strong> ${currentBuild.durationString}</p>
                    <p><a href="${env.BUILD_URL}">查看详情</a></p>
                """,
                to: 'team@company.com',
                mimeType: 'text/html'
            )
        }
        
        // 失败时执行
        failure {
            emailext(
                subject: "❌ 构建失败: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
                body: "构建失败,请检查日志: ${env.BUILD_URL}console",
                to: 'team@company.com'
            )
        }
        
        // 不稳定时执行(测试失败等)
        unstable {
            echo '构建状态不稳定,请检查测试结果'
        }
        
        // 中止时执行
        aborted {
            echo '构建被中止'
        }
        
        // 结果改变时执行
        changed {
            echo "构建结果从 ${currentBuild.previousBuild?.result} 变为 ${currentBuild.result}"
        }
        
        // 从失败恢复时执行
        fixed {
            emailext(
                subject: "🔧 构建已恢复: ${env.JOB_NAME}",
                to: 'team@company.com'
            )
        }
        
        // 从成功变为失败时执行
        regression {
            emailext(
                subject: "⚠️ 构建回退: ${env.JOB_NAME}",
                to: 'team@company.com'
            )
        }
        
        // 清理(always之后执行)
        cleanup {
            deleteDir()  // 删除整个工作空间
        }
    }
}

2.4 脚本式Pipeline完整示例

/**
 * 脚本式Pipeline完整示例
 * 演示Groovy语法的完整使用
 * 
 * 注意事项:
 * - 需要Groovy语法知识
 * - 错误处理需要手动实现
 * - 结构相对自由,需要自行规范
 */

// 定义节点
node('linux') {
    
    // 定义全局变量
    def appName = 'my-application'
    def buildNumber = env.BUILD_NUMBER
    
    // 设置构建名称
    currentBuild.displayName = "Build-${buildNumber}"
    currentBuild.description = "构建于 ${new Date().format('yyyy-MM-dd HH:mm:ss')}"
    
    try {
        // ==================== 代码检出阶段 ====================
        stage('代码检出') {
            echo "开始检出代码..."
            
            // 检出代码
            checkout([
                $class: 'GitSCM',
                branches: [[name: "*/${params.BRANCH_NAME ?: 'main'}"]],
                userRemoteConfigs: [[
                    url: 'https://github.com/company/project.git',
                    credentialsId: 'git-credentials'
                ]]
            ])
            
            // 获取Git信息
            env.GIT_COMMIT = sh(
                script: 'git rev-parse HEAD',
                returnStdout: true
            ).trim()
            
            env.GIT_COMMIT_SHORT = sh(
                script: 'git rev-parse --short HEAD',
                returnStdout: true
            ).trim()
            
            echo "Git Commit: ${env.GIT_COMMIT_SHORT}"
        }
        
        // ==================== 构建阶段 ====================
        stage('构建') {
            echo "开始构建..."
            
            // 使用Maven构建
            sh 'mvn clean package -DskipTests'
            
            // 检查构建产物
            def artifacts = sh(
                script: 'ls -la target/*.jar',
                returnStdout: true
            )
            echo "构建产物:\n${artifacts}"
        }
        
        // ==================== 并行测试阶段 ====================
        stage('测试') {
            parallel(
                // 单元测试
                '单元测试': {
                    stage('单元测试') {
                        try {
                            sh 'mvn test'
                        } finally {
                            // 收集测试报告
                            junit '**/target/surefire-reports/*.xml'
                        }
                    }
                },
                
                // 集成测试
                '集成测试': {
                    stage('集成测试') {
                        try {
                            sh 'mvn verify -P integration-test'
                        } finally {
                            junit '**/target/failsafe-reports/*.xml'
                        }
                    }
                },
                
                // 代码质量检查
                '代码质量': {
                    stage('代码质量') {
                        withSonarQubeEnv('SonarQube') {
                            sh 'mvn sonar:sonar'
                        }
                    }
                },
                
                // 快速失败配置
                failFast: true  // 任一失败立即中止其他
            )
        }
        
        // ==================== 部署阶段 ====================
        stage('部署') {
            // 条件判断
            if (env.BRANCH_NAME == 'main' && params.DEPLOY_ENABLED) {
                // 等待用户确认
                input message: '确认部署到生产环境?', ok: '确认部署', submitter: 'admin,ops'
                
                // 部署脚本
                sh "./deploy.sh production"
                
                echo "部署完成"
            } else {
                echo "跳过部署(分支: ${env.BRANCH_NAME}, 部署开关: ${params.DEPLOY_ENABLED})"
            }
        }
        
        // 设置构建成功
        currentBuild.result = 'SUCCESS'
        
    } catch (Exception e) {
        // 异常处理
        currentBuild.result = 'FAILURE'
        echo "构建失败: ${e.message}"
        throw e
        
    } finally {
        // 清理工作空间
        cleanWs()
        
        // 发送通知
        if (currentBuild.result == 'SUCCESS') {
            emailext(
                subject: "构建成功: ${env.JOB_NAME}",
                to: 'team@company.com'
            )
        } else {
            emailext(
                subject: "构建失败: ${env.JOB_NAME}",
                to: 'team@company.com'
            )
        }
    }
}

3. 声明式Pipeline完整语法详解

3.1 Agent配置详解

Agent定义了Pipeline或Stage的执行位置,是Pipeline的核心配置。

Agent类型

any

任意可用节点

none

不指定,Stage单独配置

label

指定标签节点

docker

Docker容器

kubernetes

Kubernetes Pod

dockerfile

Dockerfile构建

Agent配置完整示例:

pipeline {
    // ==================== Agent类型详解 ====================
    
    // 类型1: any - 任意可用节点
    agent any
    
    // 类型2: none - 不指定(各Stage需单独指定)
    agent none
    
    // 类型3: label - 指定标签
    agent { label 'linux && docker' }
    
    // 类型4: node - 带额外配置
    agent {
        node {
            label 'linux'
            customWorkspace '/opt/workspace/my-project'
        }
    }
    
    // 类型5: docker - Docker容器(完整参数)
    agent {
        docker {
            // 必选参数
            image 'maven:3.9.5-eclipse-temurin-17'  // Docker镜像
            
            // 可选参数
            label 'docker'                          // 节点标签
            args '-v $HOME/.m2:/root/.m2'           // Docker运行参数
            registryUrl 'https://registry.company.com'  // 私有仓库URL
            registryCredentialsId 'docker-creds'    // 仓库凭证
            alwaysPull true                         // 总是拉取最新镜像
            reuseNode true                          // 重用节点工作空间
            customWorkspace 'my-workspace'          // 自定义工作空间
        }
    }
    
    // 类型6: dockerfile - 从Dockerfile构建
    agent {
        dockerfile {
            filename 'Dockerfile.build'             // Dockerfile文件名
            dir 'docker'                            // Dockerfile目录
            label 'docker'                          // 节点标签
            additionalBuildArgs '--build-arg VERSION=1.0'  // 构建参数
            registryUrl 'https://registry.company.com'
            registryCredentialsId 'docker-creds'
        }
    }
    
    // 类型7: kubernetes - Kubernetes Pod(完整配置)
    agent {
        kubernetes {
            // YAML定义Pod模板
            yaml '''
                apiVersion: v1
                kind: Pod
                metadata:
                  labels:
                    app: jenkins-agent
                spec:
                  containers:
                  - name: maven
                    image: maven:3.9.5-eclipse-temurin-17
                    command:
                    - cat
                    tty: true
                    resources:
                      limits:
                        memory: "4Gi"
                        cpu: "2"
                      requests:
                        memory: "2Gi"
                        cpu: "1"
                    volumeMounts:
                    - name: maven-cache
                      mountPath: /root/.m2
                  - name: docker
                    image: docker:24.0.5
                    command:
                    - cat
                    tty: true
                    volumeMounts:
                    - name: docker-sock
                      mountPath: /var/run/docker.sock
                  volumes:
                  - name: maven-cache
                    persistentVolumeClaim:
                      claimName: maven-cache-pvc
                  - name: docker-sock
                    hostPath:
                      path: /var/run/docker.sock
            '''
            
            // 默认容器
            defaultContainer 'maven'
            
            // YAML文件路径(替代内联YAML)
            yamlFile 'kubernetes/pod-template.yaml'
            
            // 连接超时
            connectTimeout 60
            
            // Pod保留时间
            podRetention never  // never, onFailure, always
            
            // 服务账户
            serviceAccount 'jenkins-agent'
            
            // 命名空间
            namespace 'jenkins-ci'
        }
    }
    
    stages {
        stage('Build') {
            steps {
                sh 'mvn package'
            }
        }
    }
}

3.2 Environment环境变量详解

pipeline {
    agent any
    
    environment {
        // ============ 静态值 ============
        APP_NAME = 'my-application'
        VERSION = '1.0.0'
        
        // ============ 动态表达式 ============
        // 使用Groovy表达式
        BUILD_TIMESTAMP = "${new Date().format('yyyy-MM-dd_HH-mm-ss')}"
        
        // 使用Shell命令
        GIT_COMMIT_SHORT = sh(
            script: 'git rev-parse --short HEAD 2>/dev/null || echo "unknown"',
            returnStdout: true
        ).trim()
        
        // 使用环境变量组合
        ARTIFACT_NAME = "${APP_NAME}-${VERSION}-${BUILD_TIMESTAMP}"
        
        // ============ 凭证注入 ============
        // 用户名密码类型 - 自动创建 DB_CREDS_USR 和 DB_CREDS_PSW
        DB_CREDS = credentials('database-credentials')
        
        // Secret Text类型
        API_KEY = credentials('api-secret-key')
        
        // Secret File类型 - 返回文件路径
        SSH_KEY_PATH = credentials('ssh-private-key-file')
        
        // 证书类型
        CLIENT_CERT = credentials('client-certificate')
        
        // SSH私钥类型
        GIT_SSH_KEY = credentials('git-ssh-key')
        
        // ============ 凭证属性访问 ============
        // 分别获取用户名和密码
        DB_USERNAME = credentials('database-credentials').username
        DB_PASSWORD = credentials('database-credentials').password
        
        // ============ 跨Stage共享 ============
        DEPLOY_ENV = "${params.ENVIRONMENT ?: 'development'}"
    }
    
    stages {
        stage('Environment Demo') {
            // Stage级别环境变量
            environment {
                STAGE_VAR = 'stage-specific-value'
            }
            
            steps {
                script {
                    // 访问环境变量
                    echo "应用名称: ${env.APP_NAME}"
                    echo "构建时间: ${env.BUILD_TIMESTAMP}"
                    echo "Git提交: ${env.GIT_COMMIT_SHORT}"
                    
                    // 使用凭证(注意:敏感信息会被掩码)
                    echo "数据库用户: ${env.DB_CREDS_USR}"
                    // echo "数据库密码: ${env.DB_CREDS_PSW}"  // 会被掩码显示
                }
            }
        }
    }
}

环境变量优先级(从高到低):

withEnv设置的变量

Stage environment

Pipeline environment

全局环境变量
Global Tool Configuration

节点环境变量
Node Properties

系统环境变量


4. 核心Step完整参数详解

4.1 文件操作Step

pipeline {
    agent any
    
    stages {
        stage('File Operations') {
            steps {
                // ============ stash/unstash - 文件暂存与恢复 ============
                
                /**
                 * stash - 暂存文件
                 * 
                 * @param name        暂存名称(必选),用于后续unstash引用
                 * @param includes    包含文件模式(可选),默认"**",支持通配符
                 * @param excludes    排除文件模式(可选),默认无
                 * @param allowEmpty  允许空暂存(可选),默认false
                 * @param useDefaultExcludes 是否使用默认排除规则(可选),默认true
                 * 
                 * 默认排除规则: .git, .svn, target, node_modules等
                 */
                stash(
                    name: 'source-code',
                    includes: 'src/**,pom.xml,config/**',
                    excludes: 'src/test/**,**/*.log',
                    allowEmpty: false,
                    useDefaultExcludes: true
                )
                
                /**
                 * unstash - 恢复暂存文件
                 * 
                 * @param name   暂存名称(必选),对应stash的name
                 * @param dir    恢复到子目录(可选),默认根目录
                 * @param quiet  静默模式(可选),默认false
                 */
                unstash(
                    name: 'source-code',
                    dir: 'restored',
                    quiet: false
                )
                
                // ============ dir/ws - 目录切换 ============
                
                /**
                 * dir - 切换工作目录
                 * 在指定目录下执行闭包中的操作
                 */
                dir('subdirectory') {
                    sh 'ls -la'
                    writeFile file: 'test.txt', text: 'Hello World'
                }
                
                /**
                 * ws - 创建临时工作空间
                 * 在新的工作空间目录下执行操作
                 */
                ws('temp-workspace') {
                    sh 'pwd'
                    echo "当前工作空间: ${pwd()}"
                }
                
                // ============ 文件读写 ============
                
                /**
                 * readFile - 读取文件内容
                 * 
                 * @param file      文件路径(必选),相对或绝对路径
                 * @param encoding  文件编码(可选),默认UTF-8
                 */
                def fileContent = readFile(
                    file: 'config.json',
                    encoding: 'UTF-8'
                )
                echo "文件内容: ${fileContent}"
                
                /**
                 * writeFile - 写入文件
                 * 
                 * @param file      文件路径(必选)
                 * @param text      写入内容(必选)
                 * @param encoding  文件编码(可选),默认UTF-8
                 */
                writeFile(
                    file: 'output.txt',
                    text: 'Hello Jenkins Pipeline',
                    encoding: 'UTF-8'
                )
                
                // ============ JSON处理 ============
                
                /**
                 * readJSON - 读取JSON文件或文本
                 * 
                 * @param file  JSON文件路径(二选一)
                 * @param text  JSON文本内容(二选一)
                 */
                def config = readJSON(file: 'config.json')
                echo "配置项: ${config.key}"
                
                def jsonData = readJSON(text: '{"name":"test","value":123}')
                echo "名称: ${jsonData.name}, 值: ${jsonData.value}"
                
                /**
                 * writeJSON - 写入JSON文件
                 * 
                 * @param file   输出文件路径(必选)
                 * @param json   JSON对象(必选)
                 * @param pretty 格式化输出(可选),默认false
                 */
                writeJSON(
                    file: 'output.json',
                    json: [
                        name: 'test',
                        version: '1.0.0',
                        dependencies: ['lib1', 'lib2']
                    ],
                    pretty: 2  // 缩进空格数
                )
                
                // ============ YAML处理 ============
                
                /**
                 * readYaml - 读取YAML文件
                 */
                def yamlConfig = readYaml(file: 'config.yaml')
                echo "YAML配置: ${yamlConfig}"
                
                /**
                 * writeYaml - 写入YAML文件
                 */
                writeYaml(
                    file: 'output.yaml',
                    data: [
                        application: [
                            name: 'my-app',
                            version: '1.0.0'
                        ]
                    ]
                )
                
                // ============ Properties文件处理 ============
                
                /**
                 * readProperties - 读取Properties文件
                 */
                def props = readProperties file: 'gradle.properties'
                echo "版本: ${props.version}"
                
                // ============ 文件检查 ============
                
                /**
                 * fileExists - 检查文件是否存在
                 */
                if (fileExists('pom.xml')) {
                    echo 'Maven项目'
                } else if (fileExists('build.gradle')) {
                    echo 'Gradle项目'
                }
                
                /**
                 * isUnix - 检查是否为Unix系统
                 */
                if (isUnix()) {
                    sh 'chmod +x script.sh'
                } else {
                    bat 'echo Windows'
                }
            }
        }
    }
}

4.2 Shell执行Step

pipeline {
    agent any
    
    stages {
        stage('Shell Execution') {
            steps {
                // ============ sh - Shell脚本执行 ============
                
                /**
                 * sh - 执行Shell脚本
                 * 
                 * @param script          脚本内容(必选)
                 * @param returnStdout    返回标准输出(可选),默认false
                 * @param returnStatus    返回状态码(可选),默认false
                 * @param encoding        输出编码(可选),默认UTF-8
                 * @param label           日志标签(可选)
                 */
                
                // 基本用法
                sh 'echo "Hello World"'
                
                // 多行脚本
                sh '''
                    #!/bin/bash
                    set -e  # 遇错即停
                    set -x  # 打印执行的命令
                    
                    echo "开始构建..."
                    mvn clean package
                    echo "构建完成"
                '''
                
                // 获取输出
                def output = sh(
                    script: 'git rev-parse --short HEAD',
                    returnStdout: true
                ).trim()
                echo "Git提交: ${output}"
                
                // 获取状态码
                def status = sh(
                    script: 'test -f pom.xml',
                    returnStatus: true
                )
                if (status == 0) {
                    echo 'pom.xml存在'
                } else {
                    echo 'pom.xml不存在'
                }
                
                // 带标签
                sh(
                    script: 'mvn test',
                    label: '执行单元测试'
                )
                
                // ============ bat - Windows批处理 ============
                
                /**
                 * bat - 执行Windows批处理命令
                 * 参数与sh相同
                 */
                bat '''
                    @echo off
                    echo Building on Windows...
                    mvn clean package
                '''
                
                // ============ powershell - PowerShell脚本 ============
                
                /**
                 * powershell - 执行PowerShell脚本
                 */
                powershell '''
                    Write-Host "Building with PowerShell..."
                    mvn clean package
                '''
            }
        }
    }
}

4.3 流程控制Step

pipeline {
    agent any
    
    stages {
        stage('Flow Control') {
            steps {
                // ============ withEnv - 临时环境变量 ============
                
                /**
                 * withEnv - 设置临时环境变量
                 * 仅在闭包内有效
                 * 
                 * 语法: withEnv([变量列表]) { 闭包 }
                 * 
                 * 特殊语法:
                 * - PATH+XXX: 在PATH前面添加
                 * - PATH+XXX=值: 添加到PATH前面
                 */
                withEnv([
                    'MAVEN_OPTS=-Xmx2g -XX:+HeapDumpOnOutOfMemoryError',
                    'PATH+MAVEN=/opt/maven/bin',
                    'CUSTOM_VAR=custom_value'
                ]) {
                    sh 'echo $MAVEN_OPTS'
                    sh 'mvn package'
                }
                
                // ============ catchError - 错误捕获 ============
                
                /**
                 * catchError - 捕获错误并继续执行
                 * 
                 * @param buildResult          捕获后设置的构建结果(可选)
                 * @param stageResult          捕获后设置的阶段结果(可选)
                 * @param message              错误消息(可选)
                 * @param catchInterruptions   是否捕获中断(可选),默认true
                 */
                catchError(
                    buildResult: 'UNSTABLE',
                    stageResult: 'FAILURE',
                    message: '构建步骤失败,但继续执行',
                    catchInterruptions: false
                ) {
                    sh 'exit 1'  // 这个错误会被捕获
                }
                echo '继续执行后续步骤'
                
                // ============ retry - 重试 ============
                
                /**
                 * retry - 失败重试
                 * 
                 * @param count  重试次数
                 */
                retry(3) {
                    sh '''
                        # 模拟不稳定的操作
                        if [ $((RANDOM % 3)) -eq 0 ]; then
                            echo "操作成功"
                        else
                            echo "操作失败,将重试"
                            exit 1
                        fi
                    '''
                }
                
                // ============ timeout - 超时控制 ============
                
                /**
                 * timeout - 超时控制
                 * 
                 * @param time   超时时间
                 * @param unit   时间单位(可选)
                 *               NANOSECONDS, MICROSECONDS, MILLISECONDS
                 *               SECONDS, MINUTES, HOURS, DAYS
                 */
                timeout(time: 10, unit: 'MINUTES') {
                    sh 'long-running-task.sh'
                }
                
                // ============ waitUntil - 等待条件 ============
                
                /**
                 * waitUntil - 等待条件满足
                 * 
                 * @param initialRecurrencePeriod  初始等待时间(毫秒,可选)
                 * @param quiet                    静默模式(可选),默认false
                 */
                waitUntil(
                    initialRecurrencePeriod: 5000,
                    quiet: false
                ) {
                    def response = sh(
                        script: 'curl -s -o /dev/null -w "%{http_code}" http://service:8080/health',
                        returnStdout: true
                    )
                    return response == '200'
                }
                
                // ============ sleep - 休眠 ============
                
                /**
                 * sleep - 暂停执行
                 * 
                 * @param time  休眠时间
                 * @param unit  时间单位(可选),默认SECONDS
                 */
                sleep(time: 10, unit: 'SECONDS')
                
                // ============ error - 主动抛出错误 ============
                
                /**
                 * error - 主动抛出错误并终止构建
                 */
                script {
                    def validation = sh(script: 'validate-config.sh', returnStatus: true)
                    if (validation != 0) {
                        error("配置验证失败,终止构建")
                    }
                }
                
                // ============ unstable - 设置不稳定状态 ============
                
                /**
                 * unstable - 将构建标记为不稳定
                 */
                script {
                    def testFailures = sh(
                        script: 'grep -c "FAILURE" test-report.xml || echo 0',
                        returnStdout: true
                    ).trim().toInteger()
                    
                    if (testFailures > 0) {
                        currentBuild.result = 'UNSTABLE'
                        echo "存在 ${testFailures} 个测试失败"
                    }
                }
            }
        }
    }
}

4.4 锁定资源Step

pipeline {
    agent any
    
    stages {
        stage('Resource Locking') {
            steps {
                // ============ lock - 锁定共享资源 ============
                
                /**
                 * lock - 锁定资源,防止并发冲突
                 * 
                 * @param resource          资源名称(二选一)
                 * @param label             资源标签(二选一)
                 * @param quantity          资源数量(可选),默认1
                 * @param variable          锁ID存储变量(可选)
                 * @param inversePrecedence 是否反向优先(可选),默认false
                 * @param skipIfLocked      如果已锁定则跳过(可选),默认false
                 */
                
                // 按资源名称锁定
                lock(resource: 'deploy-server') {
                    sh './deploy.sh'
                }
                
                // 按标签锁定
                lock(label: 'production-servers', quantity: 1) {
                    sh './deploy.sh'
                }
                
                // 完整参数示例
                lock(
                    resource: 'database-migration',
                    quantity: 1,
                    variable: 'LOCK_ID',
                    inversePrecedence: false,
                    skipIfLocked: false
                ) {
                    echo "获取锁ID: ${LOCK_ID}"
                    sh 'flyway migrate'
                }
                
                // 如果资源已锁定则跳过
                lock(resource: 'optional-resource', skipIfLocked: true) {
                    sh 'optional-operation.sh'
                }
            }
        }
    }
}

4.5 HTTP请求Step

pipeline {
    agent any
    
    stages {
        stage('HTTP Requests') {
            steps {
                // ============ httpRequest - HTTP请求 ============
                
                /**
                 * httpRequest - 执行HTTP请求
                 * 
                 * @param url                      请求URL(必选)
                 * @param httpMode                 HTTP方法(可选)
                 *                               GET, POST, PUT, DELETE, PATCH, HEAD
                 * @param authentication           凭证ID(可选)
                 * @param contentType              内容类型(可选)
                 * @param requestBody              请求体(可选)
                 * @param customHeaders            自定义请求头(可选)
                 * @param timeout                  超时时间(秒,可选)
                 * @param validResponseCodes       有效响应码(可选)
                 * @param validResponseContent     响应内容匹配(可选)
                 * @param quiet                    静默模式(可选)
                 * @param consoleLogResponseBody   打印响应体(可选)
                 */
                
                // GET请求
                def getResponse = httpRequest(
                    url: 'https://api.example.com/data',
                    httpMode: 'GET',
                    authentication: 'api-credentials',
                    validResponseCodes: '200:299'
                )
                echo "响应状态: ${getResponse.status}"
                echo "响应内容: ${getResponse.content}"
                
                // POST请求(完整参数)
                def postResponse = httpRequest(
                    url: 'https://api.example.com/submit',
                    httpMode: 'POST',
                    authentication: 'api-credentials',
                    contentType: 'APPLICATION_JSON',
                    requestBody: '''
                        {
                            "name": "test",
                            "version": "1.0.0"
                        }
                    ''',
                    customHeaders: [
                        [name: 'X-Custom-Header', value: 'custom-value'],
                        [name: 'Authorization', value: 'Bearer token']
                    ],
                    timeout: 60,
                    validResponseCodes: '200:201',
                    validResponseContent: '"success":true',
                    quiet: false,
                    consoleLogResponseBody: true
                )
                
                // 处理JSON响应
                def jsonData = readJSON(text: postResponse.content)
                echo "返回数据: ${jsonData}"
            }
        }
    }
}

4.6 通知Step

pipeline {
    agent any
    
    stages {
        stage('Build') {
            steps {
                sh 'mvn package'
            }
        }
    }
    
    post {
        always {
            // ============ 邮件通知 ============
            
            /**
             * mail - 发送邮件
             * 
             * @param to           收件人(必选)
             * @param subject      邮件主题(必选)
             * @param body         邮件正文(必选)
             * @param from         发件人(可选)
             * @param cc           抄送(可选)
             * @param bcc          密送(可选)
             * @param replyTo      回复地址(可选)
             * @param mimeType     内容类型(可选)
             *                   text/plain, text/html
             */
            mail(
                to: 'team@company.com',
                cc: 'manager@company.com',
                subject: "构建通知: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
                body: """
                    构建完成!
                    项目: ${env.JOB_NAME}
                    构建号: ${env.BUILD_NUMBER}
                    结果: ${currentBuild.result}
                    URL: ${env.BUILD_URL}
                """,
                mimeType: 'text/plain'
            )
            
            // ============ 扩展邮件 ============
            
            /**
             * emailext - 扩展邮件功能
             * 支持模板、附件、收件人解析等高级功能
             */
            emailext(
                to: 'team@company.com',
                subject: "构建${currentBuild.result}: ${env.JOB_NAME}",
                body: '''${SCRIPT, template="groovy-html.template"}''',
                attachLog: true,
                compressLog: true,
                attachmentsPattern: 'target/*.jar',
                mimeType: 'text/html',
                recipientProviders: [
                    [$class: 'DevelopersRecipientProvider'],
                    [$class: 'CulpritsRecipientProvider'],
                    [$class: 'RequesterRecipientProvider']
                ]
            )
            
            // ============ Slack通知 ============
            
            /**
             * slackSend - 发送Slack消息
             */
            slackSend(
                color: currentBuild.result == 'SUCCESS' ? 'good' : 'danger',
                message: """
                    构建通知
                    项目: ${env.JOB_NAME}
                    构建: #${env.BUILD_NUMBER}
                    结果: ${currentBuild.result}
                    URL: ${env.BUILD_URL}
                """,
                channel: '#builds',
                tokenCredentialId: 'slack-token',
                baseUrl: 'https://hooks.slack.com/services/'
            )
            
            // ============ 企业微信通知 ============
            
            /**
             * dingtalk - 发送钉钉消息
             */
            dingtalk(
                robot: 'jenkins-robot-id',
                type: 'MARKDOWN',
                title: '构建通知',
                text: [
                    "## 构建结果: ${currentBuild.result}",
                    "- **项目**: ${env.JOB_NAME}",
                    "- **构建号**: #${env.BUILD_NUMBER}",
                    "- **持续时间**: ${currentBuild.durationString}",
                    "- **[查看详情](${env.BUILD_URL})**"
                ],
                at: [
                    'user1',
                    'user2'
                ],
                atAll: false
            )
            
            // ============ 飞书通知 ============
            
            /**
             * lark - 发送飞书消息
             */
            lark(
                webhook: 'https://open.feishu.cn/open-apis/bot/v2/hook/xxx',
                message: """
                    构建完成
                    项目: ${env.JOB_NAME}
                    结果: ${currentBuild.result}
                """,
                title: 'Jenkins构建通知'
            )
            
            // ============ Microsoft Teams通知 ============
            
            /**
             * office365ConnectorSend - 发送Teams消息
             */
            office365ConnectorSend(
                webhookUrl: 'https://outlook.office.com/webhook/xxx',
                message: "构建完成: ${env.JOB_NAME} - ${currentBuild.result}",
                status: currentBuild.result,
                color: currentBuild.result == 'SUCCESS' ? '00FF00' : 'FF0000'
            )
        }
    }
}

5. 构建触发器完整配置

5.1 Generic Webhook Trigger详解

/**
 * Generic Webhook Trigger完整配置
 * 
 * 支持从任意Webhook触发构建
 * 可解析JSON/XML请求体和HTTP头
 */

properties([
    pipelineTriggers([
        GenericTrigger(
            // ============ 变量定义 ============
            
            /**
             * genericVariables - 从请求体提取变量
             * 
             * @param key             变量名
             * @param value           JSONPath表达式
             * @param expressionType  表达式类型
             *                         JSONPath, XPath
             * @param regexpFilter    正则过滤(可选)
             */
            genericVariables: [
                [
                    key: 'ref',
                    value: '$.ref',
                    expressionType: 'JSONPath',
                    regexpFilter: 'refs/heads/(.*)'
                ],
                [
                    key: 'action',
                    value: '$.action',
                    expressionType: 'JSONPath'
                ],
                [
                    key: 'sender',
                    value: '$.sender.login',
                    expressionType: 'JSONPath'
                ],
                [
                    key: 'repository',
                    value: '$.repository.name',
                    expressionType: 'JSONPath'
                ]
            ],
            
            /**
             * genericHeaderVariables - 从HTTP头提取变量
             */
            genericHeaderVariables: [
                [
                    key: 'X-GitHub-Event',
                    regexpFilter: ''
                ],
                [
                    key: 'X-GitHub-Delivery',
                    regexpFilter: ''
                ]
            ],
            
            // ============ 触发配置 ============
            
            /**
             * causeString - 构建原因描述
             * 支持变量替换
             */
            causeString: 'Triggered by $sender via $X-GitHub-Event',
            
            /**
             * token - 触发令牌
             * 用于验证Webhook请求
             */
            token: 'my-secret-token',
            
            /**
             * tokenCredentialId - 令牌凭证ID
             * 使用Jenkins凭证存储令牌
             */
            tokenCredentialId: 'webhook-token-credentials',
            
            // ============ 调试选项 ============
            
            /**
             * printContributedVariables - 打印提取的变量
             */
            printContributedVariables: true,
            
            /**
             * printPostContent - 打印请求体
             */
            printPostContent: true,
            
            // ============ 响应配置 ============
            
            /**
             * silentResponse - 静默响应
             * 不返回详细信息
             */
            silentResponse: false,
            
            /**
             * shouldNotFlatten - 不展平变量
             */
            shouldNotFlatten: false,
            
            // ============ 过滤配置 ============
            
            /**
             * regexFilterText - 过滤文本
             * 用于条件触发
             */
            regexFilterText: '$ref $action',
            
            /**
             * regexFilterExpression - 过滤正则
             * 只有匹配时才触发构建
             */
            regexFilterExpression: 'refs/heads/(main|develop) (push|opened)'
        )
    ])
])

pipeline {
    agent any
    
    stages {
        stage('Webhook Build') {
            steps {
                script {
                    echo "触发事件: ${env.X_GitHub_Event}"
                    echo "触发分支: ${env.ref}"
                    echo "触发用户: ${env.sender}"
                    echo "仓库: ${env.repository}"
                    echo "动作: ${env.action}"
                }
            }
        }
    }
}

5.2 Webhook URL格式

# 基本URL格式
https://jenkins.example.com/generic-webhook-trigger/invoke

# 带Token的URL
https://jenkins.example.com/generic-webhook-trigger/invoke?token=my-secret-token

# GitHub Webhook配置示例
# Content-Type: application/json
# URL: https://jenkins.example.com/generic-webhook-trigger/invoke?token=my-secret-token
# Secret: (可选,用于签名验证)
# Events: Push, Pull request, etc.

6. 构建后操作详解

6.1 制品归档与指纹

pipeline {
    agent any
    
    stages {
        stage('Build') {
            steps {
                sh 'mvn package'
            }
        }
    }
    
    post {
        success {
            // ============ archiveArtifacts - 归档制品 ============
            
            /**
             * archiveArtifacts - 归档构建制品
             * 
             * @param artifacts          文件模式(必选),支持通配符
             * @param allowEmptyArchive  允许空归档(可选),默认false
             * @param caseSensitive      大小写敏感(可选),默认true
             * @param defaultExcludes    使用默认排除(可选),默认true
             * @param excludes           排除模式(可选)
             * @param fingerprint        生成指纹(可选),默认false
             * @param onlyIfSuccessful   仅成功时归档(可选),默认false
             */
            archiveArtifacts(
                artifacts: 'target/*.jar, target/*.war',
                allowEmptyArchive: false,
                caseSensitive: true,
                defaultExcludes: true,
                excludes: '*-sources.jar, *-javadoc.jar',
                fingerprint: true,
                onlyIfSuccessful: true
            )
            
            // ============ 指纹追踪 ============
            
            /**
             * 指纹用于追踪制品的使用关系
             * 可查看哪些构建使用了特定制品
             */
            echo "制品指纹已生成,可在构建页面查看"
        }
    }
}

6.2 构建触发器

pipeline {
    agent any
    
    stages {
        stage('Build') {
            steps {
                sh 'mvn package'
            }
        }
    }
    
    post {
        success {
            // ============ build - 触发下游构建 ============
            
            /**
             * build - 触发其他Job构建
             * 
             * @param job              Job名称(必选)
             * @param parameters       构建参数(可选)
             * @param wait             是否等待完成(可选),默认true
             * @param propagate        是否传播失败(可选),默认true
             * @param quietPeriod      静默期(可选)
             */
            
            // 基本触发
            build job: 'downstream-deploy-job'
            
            // 带参数触发
            build job: 'deploy-job',
                  parameters: [
                      string(name: 'ENVIRONMENT', value: 'staging'),
                      string(name: 'VERSION', value: env.BUILD_NUMBER),
                      booleanParam(name: 'RUN_TESTS', value: false)
                  ],
                  wait: true,
                  propagate: true
            
            // 异步触发(不等待)
            build job: 'notification-job',
                  parameters: [
                      string(name: 'BUILD_URL', value: env.BUILD_URL)
                  ],
                  wait: false
            
            // 条件触发
            if (env.BRANCH_NAME == 'main') {
                build job: 'production-deploy',
                      parameters: [
                          string(name: 'VERSION', value: env.BUILD_NUMBER)
                      ],
                      wait: true
            }
        }
    }
}

6.3 JUnit测试报告

pipeline {
    agent any
    
    stages {
        stage('Test') {
            steps {
                sh 'mvn test'
            }
            post {
                always {
                    // ============ junit - 发布测试报告 ============
                    
                    /**
                     * junit - 发布JUnit格式测试报告
                     * 
                     * @param testResults           测试报告文件模式(必选)
                     * @param allowEmptyResults     允许空结果(可选),默认false
                     * @param healthScaleFactor     健康度因子(可选),默认1.0
                     * @param keepLongStdio         保留长输出(可选),默认false
                     * @param skipPublishingChecks  跳过检查发布(可选)
                     */
                    junit(
                        testResults: '**/target/surefire-reports/*.xml',
                        allowEmptyResults: false,
                        healthScaleFactor: 1.0,
                        keepLongStdio: true
                    )
                    
                    // 集成测试报告
                    junit(
                        testResults: '**/target/failsafe-reports/*.xml',
                        allowEmptyResults: true
                    )
                }
            }
        }
    }
}

7. when条件完整语法

7.1 when条件完整示例

pipeline {
    agent any
    
    stages {
        // ============ 分支条件 ============
        stage('Branch Conditions') {
            when {
                // 精确匹配
                branch 'main'
                
                // 通配符匹配
                branch pattern: 'release/*', comparator: 'GLOB'
                
                // 正则匹配
                branch pattern: 'release/\\d+\\.\\d+', comparator: 'REGEXP'
            }
            steps {
                echo '分支条件满足'
            }
        }
        
        // ============ 环境变量条件 ============
        stage('Environment Condition') {
            when {
                environment name: 'DEPLOY_ENV', value: 'production'
            }
            steps {
                echo '部署到生产环境'
            }
        }
        
        // ============ 表达式条件 ============
        stage('Expression Condition') {
            when {
                expression {
                    // Groovy布尔表达式
                    return params.DEPLOY_ENABLED && 
                           env.BRANCH_NAME == 'main' &&
                           currentBuild.previousBuild?.result != 'SUCCESS'
                }
            }
            steps {
                echo '表达式条件满足'
            }
        }
        
        // ============ 变化检测条件 ============
        stage('Changeset Condition') {
            when {
                // 检测文件变化
                changeset '**/*.java'
                
                // 带正则的变化检测
                changeset pattern: 'src/(main|test)/.*', comparator: 'REGEXP'
            }
            steps {
                echo '代码有变化'
            }
        }
        
        // ============ 变更请求条件 ============
        stage('Change Request Condition') {
            when {
                // 任意PR
                changeRequest()
                
                // 指定目标分支
                changeRequest target: 'main'
                
                // 指定PR ID
                changeRequest id: '123'
                
                // 指定作者
                changeRequest author: 'username'
                
                // 指定标题模式
                changeRequest title: 'JENKINS-\\d+'
                
                // 组合条件
                changeRequest target: 'main', author: 'username'
            }
            steps {
                echo 'PR条件满足'
            }
        }
        
        // ============ 触发原因条件 ============
        stage('Trigger Condition') {
            when {
                // SCM触发
                triggeredBy 'SCMTrigger'
                
                // 定时触发
                triggeredBy 'TimerTrigger'
                
                // 用户触发
                triggeredBy cause: 'UserIdCause', detail: 'admin'
                
                // 上游项目触发
                triggeredBy 'UpstreamCause'
            }
            steps {
                echo '触发条件满足'
            }
        }
        
        // ============ 标签条件 ============
        stage('Tag Condition') {
            when {
                // 通配符标签
                tag 'v*'
                
                // 正则标签
                tag pattern: 'v\\d+\\.\\d+\\.\\d+', comparator: 'REGEXP'
            }
            steps {
                echo '标签条件满足'
            }
        }
        
        // ============ 条件组合 ============
        stage('Combined Conditions') {
            when {
                // 所有条件都满足
                allOf {
                    branch 'main'
                    environment name: 'DEPLOY_ENV', value: 'production'
                    expression { params.DEPLOY_ENABLED }
                }
            }
            steps {
                echo '所有条件满足'
            }
        }
        
        stage('AnyOf Conditions') {
            when {
                // 任一条件满足
                anyOf {
                    branch 'main'
                    branch 'develop'
                    branch pattern: 'release/*'
                }
            }
            steps {
                echo '任一条件满足'
            }
        }
        
        stage('Not Condition') {
            when {
                // 条件取反
                not {
                    branch 'feature/*'
                }
            }
            steps {
                echo '非feature分支'
            }
        }
        
        stage('Nested Conditions') {
            when {
                allOf {
                    branch 'main'
                    anyOf {
                        environment name: 'DEPLOY_ENV', value: 'staging'
                        environment name: 'DEPLOY_ENV', value: 'production'
                    }
                    not {
                        changeset 'docs/**'
                    }
                }
            }
            steps {
                echo '嵌套条件满足'
            }
        }
        
        // ============ 执行时机配置 ============
        stage('Before Agent') {
            when {
                beforeAgent true  // 在分配Agent前评估条件
                branch 'main'
            }
            agent { label 'production-server' }
            steps {
                echo '条件满足后才分配Agent'
            }
        }
        
        stage('Before Input') {
            when {
                beforeInput true  // 在等待输入前评估条件
                branch 'main'
            }
            input {
                message "确认部署?"
            }
            steps {
                echo '条件满足后才等待输入'
            }
        }
        
        stage('Before Options') {
            when {
                beforeOptions true  // 在应用选项前评估条件
                branch 'main'
            }
            options {
                timeout(time: 30, unit: 'MINUTES')
            }
            steps {
                echo '条件满足后才应用选项'
            }
        }
    }
}

8. 最佳实践与性能优化

8.1 Pipeline设计最佳实践

/**
 * Pipeline最佳实践示例
 * 
 * 设计原则:
 * 1. 单一职责:每个Stage只做一件事
 * 2. 快速失败:尽早发现问题
 * 3. 幂等性:可重复执行
 * 4. 可读性:清晰的命名和注释
 */

pipeline {
    agent none  // 全局不指定,各Stage单独指定
    
    // 全局选项配置
    options {
        // 构建历史管理
        buildDiscarder(logRotator(
            numToKeepStr: '20',
            artifactNumToKeepStr: '5'
        ))
        
        // 超时控制
        timeout(time: 30, unit: 'MINUTES')
        
        // 禁止并发
        disableConcurrentBuilds()
        
        // 跳过默认检出
        skipDefaultCheckout()
        
        // 时间戳
        timestamps()
        
        // ANSI颜色
        ansiColor('xterm')
    }
    
    // 环境变量
    environment {
        APP_NAME = 'my-application'
        // 使用凭证
        DOCKER_CREDS = credentials('docker-registry')
    }
    
    stages {
        // ============ 检出阶段 ============
        stage('Checkout') {
            agent { label 'linux' }
            
            steps {
                script {
                    // 清晰的日志输出
                    echo "========== 开始检出代码 =========="
                }
                
                // 检出代码
                checkout scm
                
                // 暂存代码供后续使用
                stash name: 'source', includes: '**', excludes: '.git/**'
                
                script {
                    echo "========== 代码检出完成 =========="
                }
            }
        }
        
        // ============ 构建阶段 ============
        stage('Build') {
            agent {
                docker {
                    image 'maven:3.9.5-eclipse-temurin-17'
                    args '-v $HOME/.m2:/root/.m2'  // Maven缓存
                }
            }
            
            steps {
                unstash 'source'
                
                script {
                    echo "========== 开始构建 =========="
                }
                
                // 并行构建
                sh 'mvn clean package -DskipTests -T 4'
                
                // 暂存制品
                stash name: 'artifacts', includes: 'target/*.jar'
                
                script {
                    echo "========== 构建完成 =========="
                }
            }
        }
        
        // ============ 测试阶段(并行) ============
        stage('Test') {
            parallel {
                stage('Unit Tests') {
                    agent {
                        docker {
                            image 'maven:3.9.5-eclipse-temurin-17'
                            args '-v $HOME/.m2:/root/.m2'
                        }
                    }
                    
                    steps {
                        unstash 'source'
                        sh 'mvn test'
                    }
                    
                    post {
                        always {
                            junit '**/target/surefire-reports/*.xml'
                        }
                    }
                }
                
                stage('Integration Tests') {
                    agent {
                        docker {
                            image 'maven:3.9.5-eclipse-temurin-17'
                            args '-v $HOME/.m2:/root/.m2'
                        }
                    }
                    
                    steps {
                        unstash 'source'
                        sh 'mvn verify -P integration-test'
                    }
                    
                    post {
                        always {
                            junit '**/target/failsafe-reports/*.xml'
                        }
                    }
                }
                
                stage('Code Quality') {
                    agent { label 'sonar' }
                    
                    steps {
                        unstash 'source'
                        withSonarQubeEnv('SonarQube') {
                            sh 'mvn sonar:sonar'
                        }
                    }
                }
            }
        }
        
        // ============ 部署阶段 ============
        stage('Deploy') {
            agent { label 'deploy' }
            
            when {
                allOf {
                    branch 'main'
                    expression { params.DEPLOY_ENABLED }
                }
            }
            
            // 部署前确认
            input {
                message "确认部署到生产环境?"
                submitter "admin,ops"
            }
            
            steps {
                unstash 'artifacts'
                
                script {
                    echo "========== 开始部署 =========="
                }
                
                // 部署脚本
                sh './deploy.sh production'
                
                script {
                    echo "========== 部署完成 =========="
                }
            }
        }
    }
    
    // ============ 构建后处理 ============
    post {
        always {
            // 清理工作空间
            cleanWs()
        }
        
        success {
            script {
                // 成功通知
                emailext(
                    subject: "✅ 构建成功: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
                    body: """
                        <h2>构建成功</h2>
                        <p><strong>项目:</strong> ${env.JOB_NAME}</p>
                        <p><strong>构建号:</strong> ${env.BUILD_NUMBER}</p>
                        <p><strong>持续时间:</strong> ${currentBuild.durationString}</p>
                        <p><a href="${env.BUILD_URL}">查看详情</a></p>
                    """,
                    to: 'team@company.com',
                    mimeType: 'text/html'
                )
            }
        }
        
        failure {
            script {
                // 失败通知
                emailext(
                    subject: "❌ 构建失败: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
                    body: """
                        <h2>构建失败</h2>
                        <p><strong>项目:</strong> ${env.JOB_NAME}</p>
                        <p><strong>构建号:</strong> ${env.BUILD_NUMBER}</p>
                        <p><a href="${env.BUILD_URL}console">查看日志</a></p>
                    """,
                    to: 'team@company.com',
                    mimeType: 'text/html'
                )
            }
        }
    }
}

8.2 性能优化技巧

pipeline {
    agent none
    
    options {
        // 优化1: 限制构建历史
        buildDiscarder(logRotator(numToKeepStr: '10'))
        
        // 优化2: 设置超时防止挂起
        timeout(time: 30, unit: 'MINUTES')
        
        // 优化3: 并行阶段快速失败
        parallelsAlwaysFailFast()
    }
    
    stages {
        stage('Optimized Build') {
            agent {
                docker {
                    image 'maven:3.9.5-eclipse-temurin-17'
                    // 优化4: 挂载缓存目录
                    args '-v $HOME/.m2:/root/.m2 -v $HOME/.gradle:/root/.gradle'
                }
            }
            
            steps {
                // 优化5: 跳过不必要的步骤
                script {
                    // 检查是否有代码变化
                    def changes = sh(
                        script: 'git diff --name-only HEAD~1',
                        returnStdout: true
                    ).trim()
                    
                    if (changes.isEmpty()) {
                        echo '无代码变化,跳过构建'
                        return
                    }
                }
                
                // 优化6: 增量构建
                sh 'mvn package -DskipTests -T 4 -Dmaven.test.skip=true'
                
                // 优化7: 使用stash/unstash传递文件
                stash name: 'artifacts', includes: 'target/*.jar', allowEmpty: true
            }
        }
        
        stage('Parallel Tests') {
            // 优化8: 并行执行测试
            parallel {
                stage('Fast Tests') {
                    agent { label 'test-node' }
                    steps {
                        unstash 'artifacts'
                        sh 'mvn test -Dtest=*FastTest'
                    }
                }
                
                stage('Slow Tests') {
                    agent { label 'test-node' }
                    steps {
                        unstash 'artifacts'
                        sh 'mvn test -Dtest=*SlowTest'
                    }
                }
            }
        }
    }
    
    post {
        always {
            // 优化9: 清理工作空间
            cleanWs()
        }
    }
}

总结

本文详细介绍了Jenkins Pipeline的语法体系,包括:

  1. 执行模型:深入解析了CPS转换机制和FlowNode执行流程
  2. 语法对比:全面对比了声明式和脚本式两种Pipeline范式
  3. 完整语法:详细讲解了声明式Pipeline的所有指令和参数
  4. 核心Step:提供了所有常用Step的完整参数说明和示例
  5. 触发器配置:详解了Generic Webhook等高级触发器配置
  6. 条件语法:完整介绍了when条件的所有用法
  7. 最佳实践:提供了性能优化和设计模式建议

通过本文的学习,读者可以全面掌握Jenkins Pipeline的语法体系,能够编写高质量、可维护的CI/CD流水线。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐