简体   繁体   中英

How to configure dynamic parameters in declarative pipeline (Jenkinsfile)?

Using the declarative pipeline syntax, I want to be able to define parameters based on an array of repos, so that when starting the build, the user can check/uncheck the repos that should not be included when the job runs.

final String[] repos = [
  'one',
  'two',
  'three',
]

pipeline {
  parameters {
    booleanParam(name: ...) // static param

    // now include a booleanParam for each item in the `repos` array
    // like this but it's not allowed
    script {
      repos.each {
        booleanParam(name: it, defaultValue: true, description: "Include the ${it} repo in the release?")
      }
    }
  }

  // later on, I'll loop through each repo and do stuff only if its value in `params` is `true`
}

Of course, you can't have a script within the parameters block, so this won't work. How can I achieve this?

You can use CHOICE parameter of Jenkins in which user can select a repository.

pipeline {
    agent any
    parameters
    {
     choice(name: "REPOS", choices: ['REPO1', 'REPO2', 'REPO3'])
    }
    stages {
           stage ('stage 1') {
                 steps { 
                   // the repository selected by user will be printed
                    println("$params.REPOS")
                 }
            }
    } 
    
    
}

You can also use the plugin Active Choices Parameter if you want to do multiple select:
https://plugins.jenkins.io/uno-choice/#documentation
You can visit pipeline syntax and configure in below way to generate code snippet and you can put it in the jenkins file:
在此处输入图像描述

在此处输入图像描述

在此处输入图像描述


Copy the snippet code and paste it in jenkinsfile at the start.

Using the Active Choices Parameter plugin is probably the best choice, but if for some reason you can't (or don't want to) use a plugin, you can still achieve dynamic parameters in a Declarative Pipeline.

Here is a sample Jenkinsfile:

def list_wrap() {
    sh(script: 'echo choice1 choice2 choice3 choice4 | sed -e "s/ /\\n/g"', , returnStdout: true)
}

pipeline {
    agent any
    stages {
        stage ('Gather Parameters') {
            steps {
                timeout(time: 30, unit: 'SECONDS') {
                    script {
                        properties([
                            parameters([
                                choice(
                                    description: 'List of arguments',
                                    name: 'service_name',
                                    choices: 'DEFAULT\n' + list_wrap()
                                ),
                                booleanParam(
                                    defaultValue: false,
                                    description: 'Whether we should apply changes',
                                    name: 'apply'
                                )
                            ])
                        ])
                    }
                }
            }
        }
        stage ('Run command') {
            when { expression {  params.apply == true  }  }
            steps {
                sh """
                    echo choice: ${params.service_name} ;
                """
            }
        }
    }
}

This embeds a script {} in a stage, which calls a function, which runs a shell script on the agent / node of the Declarative Pipeline, and uses the script's output to set the choices for the parameters. The parameters are then available in the next stages.

The gotcha is that you must first run the job with no build parameters in order for Jenkins to populate the parameters, so they're always going to be one run out of date. That's why the Active Choices Parameter plugin is probably a better idea.

You could also combine this with an input command to cause the pipeline to prompt the user for a parameter:

                    script {
                       def INPUT_PARAMS = input message: 'Please Provide Parameters', ok: 'Next',
                                        parameters: [
                                        choice(name: 'ENVIRONMENT', choices: ['dev','qa'].join('\n'), description: 'Please select the Environment'),
                                        choice(name: 'IMAGE_TAG', choices: getDockerImages(), description: 'Available Docker Images')]
                        env.ENVIRONMENT = INPUT_PARAMS.ENVIRONMENT
                        env.IMAGE_TAG = INPUT_PARAMS.IMAGE_TAG
                    }

Credit goes to Alex Lashford ( https://medium.com/disney-streaming/jenkins-pipeline-with-dynamic-user-input-9f340fb8d9e2 ) for this method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM