Jenkins参数化构建与用户输入 - 让构建更灵活

Jenkins参数化构建与用户输入

一、前言

前面我们写的Pipeline都是"一键构建",每次执行的操作完全一样。但在实际工作中,我们经常需要灵活控制构建行为——比如选择部署环境、指定版本号、决定是否跳过测试等。这就需要用到Jenkins的参数化构建功能。

二、为什么需要参数化构建

先看几个场景:

  • 每次构建都想选择部署到dev/staging/production哪个环境
  • 热修复版本需要跳过耗时的测试步骤,快速部署
  • 需要指定构建的分支或标签
  • 部署前需要人工审批确认
  • 需要输入版本号或配置信息

没有参数化构建的话,你只能创建多个几乎相同的任务来处理这些差异。有了参数化构建,一个任务搞定所有场景!

三、参数类型详解

3.1 String Parameter(字符串参数)

最基础的参数类型,让用户输入一段文本:

pipeline {
    agent any
    
    parameters {
        string(
            name: 'VERSION',
            defaultValue: '1.0.0',
            description: '发布版本号'
        )
    }
    
    stages {
        stage('Build') {
            steps {
                echo "构建版本: ${params.VERSION}"
                sh "./build.sh ${params.VERSION}"
            }
        }
    }
}

构建时会出现一个文本输入框,让你填写版本号。

3.2 Choice Parameter(选择参数)

提供下拉列表让用户选择:

pipeline {
    agent any
    
    parameters {
        choice(
            name: 'DEPLOY_ENV',
            choices: ['dev', 'staging', 'production'],
            description: '选择部署环境'
        )
    }
    
    stages {
        stage('Deploy') {
            steps {
                echo "部署到: ${params.DEPLOY_ENV} 环境"
                sh "./deploy.sh ${params.DEPLOY_ENV}"
            }
        }
    }
}

构建时会出现一个下拉选择框,你只能从预定义的选项中选择。

3.3 Boolean Parameter(布尔参数)

提供一个复选框,适合开关类选项:

pipeline {
    agent any
    
    parameters {
        booleanParam(
            name: 'SKIP_TESTS',
            defaultValue: false,
            description: '是否跳过测试(热修复时可勾选)'
        )
        booleanParam(
            name: 'ENABLE_DEBUG',
            defaultValue: true,
            description: '是否开启调试模式'
        )
    }
    
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean package -DskipTests'
            }
        }
        
        stage('Test') {
            when {
                expression { return !params.SKIP_TESTS }
            }
            steps {
                sh 'mvn test'
            }
        }
        
        stage('Deploy') {
            steps {
                script {
                    def debugFlag = params.ENABLE_DEBUG ? '--debug' : ''
                    sh "./deploy.sh ${debugFlag}"
                }
            }
        }
    }
}

3.4 Password Parameter(密码参数)

输入密码用的参数,输入时显示为星号,保护敏感信息:

pipeline {
    agent any
    
    parameters {
        password(
            name: 'DB_PASSWORD',
            defaultValue: '',
            description: '数据库密码'
        )
    }
    
    stages {
        stage('Migrate') {
            steps {
                sh "DB_PASS=${params.DB_PASSWORD} ./migrate.sh"
            }
        }
    }
}

注意:虽然密码参数会在界面上隐藏输入,但在构建日志中仍然可能被看到。对于生产环境的敏感信息,推荐使用Jenkins Credentials来管理。

3.5 Text Parameter(多行文本参数)

适合输入多行内容,如配置文件、部署说明等:

pipeline {
    agent any
    
    parameters {
        text(
            name: 'RELEASE_NOTES',
            defaultValue: '请填写发布说明...',
            description: '本次发布的变更说明'
        )
    }
    
    stages {
        stage('Deploy') {
            steps {
                script {
                    writeFile file: 'release-notes.txt', text: params.RELEASE_NOTES
                    sh './deploy-with-notes.sh'
                }
            }
        }
    }
}

3.6 Git Parameter(Git参数)

需要安装 git-parameter 插件。可以动态获取Git的分支、标签列表供选择:

pipeline {
    agent any
    
    parameters {
        gitParameter(
            name: 'BRANCH',
            type: 'PT_BRANCH',
            defaultValue: 'main',
            description: '选择要构建的分支'
        )
    }
    
    stages {
        stage('Checkout') {
            steps {
                git branch: "${params.BRANCH}", url: 'https://github.com/user/repo.git'
            }
        }
    }
}

gitParameter的type选项:

  • PT_BRANCH:分支列表
  • PT_TAG:标签列表
  • PT_BRANCH_TAG:分支和标签都显示
  • PT_REVISION:提交哈希

3.7 Extended Choice Parameter(扩展选择参数)

需要安装 extended-choice-parameter 插件,支持多选、单选按钮等:

pipeline {
    agent any
    
    parameters {
        extendedChoice(
            name: 'SERVICES',
            type: 'multi-select',
            value: 'user-service,order-service,payment-service,notification-service',
            description: '选择要部署的服务(可多选)'
        )
    }
    
    stages {
        stage('Deploy') {
            steps {
                script {
                    def services = params.SERVICES.split(',')
                    for (service in services) {
                        echo "部署 ${service}..."
                        sh "./deploy-service.sh ${service.trim()}"
                    }
                }
            }
        }
    }
}

四、input步骤 - 运行时用户交互

与参数不同,input步骤是在Pipeline执行过程中弹出的,可以让用户在关键节点做出决定。

4.1 基本用法

pipeline {
    agent any
    
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean package'
            }
        }
        
        stage('Confirm Deploy') {
            steps {
                input message: '确认部署到生产环境?', ok: '确认部署'
            }
        }
        
        stage('Deploy') {
            steps {
                sh './deploy.sh production'
            }
        }
    }
}

Pipeline执行到input步骤时会暂停,等待用户在Jenkins界面上点击"确认"或"取消"。

4.2 带参数的input

pipeline {
    agent any
    
    stages {
        stage('Deploy') {
            input {
                message "选择部署策略"
                ok "开始部署"
                parameters {
                    choice(name: 'STRATEGY', choices: ['rolling', 'blue-green', 'canary'], description: '部署策略')
                    string(name: 'REASON', defaultValue: '', description: '部署原因')
                }
            }
            steps {
                echo "部署策略: ${STRATEGY}"
                echo "部署原因: ${REASON}"
                sh "./deploy.sh --strategy ${STRATEGY}"
            }
        }
    }
}

4.3 指定审批人

pipeline {
    agent any
    
    stages {
        stage('Production Deploy') {
            input {
                message "确认部署到生产环境?"
                submitter "admin,release-manager"
                submitterParameter "APPROVER"
            }
            steps {
                echo "审批人: ${APPROVER}"
                sh './deploy.sh production'
            }
        }
    }
}

只有 adminrelease-manager 用户才能审批这个部署操作。

4.4 超时处理

input步骤会一直等待用户操作,如果没人处理就会永远卡住。建议加上超时:

pipeline {
    agent any
    
    stages {
        stage('Deploy') {
            steps {
                timeout(time: 30, unit: 'MINUTES') {
                    input message: '请在30分钟内确认部署', ok: '确认'
                }
                sh './deploy.sh production'
            }
        }
    }
}

30分钟内没人确认,Pipeline会自动中止并标记为失败。

五、综合实战 - 完整的参数化部署Pipeline

pipeline {
    agent any
    
    parameters {
        choice(
            name: 'DEPLOY_ENV',
            choices: ['dev', 'staging', 'production'],
            description: '🎯 选择部署环境'
        )
        string(
            name: 'APP_VERSION',
            defaultValue: '',
            description: '📋 指定版本号(留空使用最新构建号)'
        )
        booleanParam(
            name: 'SKIP_TESTS',
            defaultValue: false,
            description: '⏭️ 跳过测试(紧急修复时使用)'
        )
        booleanParam(
            name: 'ROLLBACK',
            defaultValue: false,
            description: '🔄 回滚到上一版本'
        )
        text(
            name: 'RELEASE_NOTES',
            defaultValue: '',
            description: '📝 发布说明'
        )
    }
    
    environment {
        VERSION = "${params.APP_VERSION ? params.APP_VERSION : "v${BUILD_NUMBER}"}"
    }
    
    stages {
        stage('Prepare') {
            steps {
                echo """
                ===========================
                🚀 部署信息
                ===========================
                环境: ${params.DEPLOY_ENV}
                版本: ${VERSION}
                跳过测试: ${params.SKIP_TESTS}
                回滚: ${params.ROLLBACK}
                ===========================
                """
            }
        }
        
        stage('Rollback') {
            when {
                expression { return params.ROLLBACK }
            }
            steps {
                echo '🔄 执行回滚...'
                sh "./rollback.sh ${params.DEPLOY_ENV}"
            }
        }
        
        stage('Build') {
            when {
                expression { return !params.ROLLBACK }
            }
            steps {
                sh 'mvn clean package -DskipTests'
            }
        }
        
        stage('Test') {
            when {
                allOf {
                    expression { return !params.SKIP_TESTS }
                    expression { return !params.ROLLBACK }
                }
            }
            steps {
                sh 'mvn test'
            }
        }
        
        stage('Deploy') {
            when {
                expression { return !params.ROLLBACK }
            }
            steps {
                script {
                    if (params.DEPLOY_ENV == 'production') {
                        timeout(time: 30, unit: 'MINUTES') {
                            input message: "⚠️ 确认部署 ${VERSION} 到生产环境?", ok: '确认部署'
                        }
                    }
                    sh "./deploy.sh ${params.DEPLOY_ENV} ${VERSION}"
                }
            }
        }
        
        stage('Verify') {
            when {
                expression { return !params.ROLLBACK }
            }
            steps {
                sh "./verify.sh ${params.DEPLOY_ENV}"
                echo '✅ 部署验证通过!'
            }
        }
    }
    
    post {
        success {
            echo """
            🎉 部署成功!
            环境: ${params.DEPLOY_ENV}
            版本: ${VERSION}
            发布说明: ${params.RELEASE_NOTES}
            """
        }
        failure {
            echo '❌ 部署失败,请检查日志!'
        }
    }
}

六、在Freestyle项目中使用参数

Freestyle项目也支持参数化构建:

  • 1. 勾选"This project is parameterized"
  • 2. 点击"Add Parameter"选择参数类型
  • 3. 配置参数名称、默认值、描述
  • 4. 在Shell脚本中用 ${参数名} 引用
# Freestyle项目Shell脚本中使用参数
echo "部署环境: ${DEPLOY_ENV}"
echo "应用版本: ${APP_VERSION}"

if [ "${SKIP_TESTS}" = "true" ]; then
    echo "跳过测试"
    mvn clean package -DskipTests
else
    mvn clean package
fi

七、最佳实践

  • 参数不要太多:参数太多会让构建页面复杂,一般5-8个以内
  • 给参数加描述:让其他团队成员理解每个参数的作用
  • 设置合理的默认值:让最常用的场景一键可执行
  • 敏感信息用Credentials:不要用Password参数,用Jenkins凭据更安全
  • input步骤加超时:避免Pipeline永远卡住等待
  • 生产部署加审批:用input + submitter控制谁可以部署到生产环境

八、总结

本文详细介绍了Jenkins参数化构建的所有用法:

  • 6种参数类型:String、Choice、Boolean、Password、Text、Git Parameter
  • input步骤:运行时交互,支持审批、参数输入、超时
  • 实战案例:完整的参数化多环境部署Pipeline
  • 最佳实践:参数设计原则和安全建议

有了参数化构建,你的Jenkins任务就变得非常灵活了!

发表回复

后才能评论