Jenkins管道 - 如何动态提供选择参数

时间:2018-03-28 03:36:23

标签: jenkins jenkins-pipeline

pipeline {
  agent any
  stages {
    stage("foo") {
        steps {
            script {
                env.RELEASE_SCOPE = input message: 'User input required', ok: 'Release!',
                        parameters: [choice(name: 'RELEASE_SCOPE', choices: 'patch\nminor\nmajor', 
                                     description: 'What is the release scope?')]
            }
            echo "${env.RELEASE_SCOPE}"
        }
    }
  }
}

在上面的代码中,选项是硬编码的(patch \ nminor \ nmajor) - 我的要求是在下拉列表中动态给出选择值。 我通过从artifactory调用api - Artifacts list(.zip)文件名来获取值 在上面的例子中,它在我们进行构建时请求输入,但我想做一个"使用参数构建"

请建议/帮助。

6 个答案:

答案 0 :(得分:2)

取决于如何从API获取数据,它将有不同的选项,例如让我们假设您将数据作为字符串列表(让我们称之为releaseScope),在这种情况下,您的代码如下:

...
script {
    def releaseScopeChoices = ''
    releaseScope.each {
        releaseScopeChoices += it + '\n'
    }

    parameters: [choice(name: 'RELEASE_SCOPE', choices: ${releaseScopeChoices}, description: 'What is the release scope?')]
}
...
希望它会有所帮助。

答案 1 :(得分:2)

这是我们使用的缩减版本。我们将东西分成共享库,但我已经整合了一些以使其更容易。

Jenkinsfile看起来像这样:

#!groovy
@Library('shared') _
def imageList = pipelineChoices.artifactoryArtifactSearchList(repoName, env.BRANCH_NAME)
imageList.add(0, 'build')
properties([
    buildDiscarder(logRotator(numToKeepStr: '20')),
    parameters([
        choice(name: 'ARTIFACT_NAME', choices: body.artifacts.join('\n'), description: '')
    ])
])

查看artifactory的共享库,非常简单。 基本上生成GET请求(并在其上提供auth信用)然后过滤/拆分结果以减少到所需的值并将列表返回到Jenkinsfile。

import com.cloudbees.groovy.cps.NonCPS
import groovy.json.JsonSlurper
import java.util.regex.Pattern
import java.util.regex.Matcher   

List artifactoryArtifactSearchList(String repoKey, String artifact_name, String artifact_archive, String branchName) {
    // URL components
    String baseUrl = "https://org.jfrog.io/org/api/search/artifact"
    String url = baseUrl + "?name=${artifact_name}&repos=${repoKey}"

    Object responseJson = getRequest(url)

    String regexPattern = "(.+)${artifact_name}-(\\d+).(\\d+).(\\d+).${artifact_archive}\$"

    Pattern regex = ~ regexPattern
    List<String> outlist = responseJson.results.findAll({ it['uri'].matches(regex) })
    List<String> artifactlist=[]

    for (i in outlist) {
        artifactlist.add(i['uri'].tokenize('/')[-1])
    }

    return artifactlist.reverse()
}

// Artifactory Get Request - Consume in other methods
Object getRequest(url_string){

    URL url = url_string.toURL()

    // Open connection
    URLConnection connection = url.openConnection()

    connection.setRequestProperty ("Authorization", basicAuthString())

    // Open input stream
    InputStream inputStream = connection.getInputStream()
    @NonCPS
    json_data = new groovy.json.JsonSlurper().parseText(inputStream.text)
    // Close the stream
    inputStream.close()

    return json_data
}

// Artifactory Get Request - Consume in other methods
Object basicAuthString() {
    // Retrieve password
    String username = "artifactoryMachineUsername"
    String credid = "artifactoryApiKey"
    @NonCPS
    credentials_store = jenkins.model.Jenkins.instance.getExtensionList(
        'com.cloudbees.plugins.credentials.SystemCredentialsProvider'
        )
    credentials_store[0].credentials.each { it ->
        if (it instanceof org.jenkinsci.plugins.plaincredentials.StringCredentials) {
            if (it.getId() == credid) {
                apiKey = it.getSecret()
            }
        }
    }
    // Create authorization header format using Base64 encoding
    String userpass = username + ":" + apiKey;
    String basicAuth = "Basic " + javax.xml.bind.DatatypeConverter.printBase64Binary(userpass.getBytes());

    return basicAuth

}

答案 2 :(得分:0)

以下Jenkinsfile的示例包含AWS CLI命令,该命令可从AWS ECR动态获取Docker映像列表,但可以将其替换为您自己的命令。 Active Choices Plug-in是必需的。

注意!,在“ Manage Jenkins”->“进程内脚本批准”中首次运行后,您需要批准parameters中指定的脚本,或者打开作业配置并保存它审批 自动(可能需要管理员权限)。

properties([
  parameters([[
    $class: 'ChoiceParameter',
    choiceType: 'PT_SINGLE_SELECT',
    name: 'image',
    description: 'Docker image',
    filterLength: 1,
    filterable: false,
    script: [
      $class: 'GroovyScript',
      fallbackScript: [classpath: [], sandbox: false, script: 'return ["none"]'],
      script: [
        classpath: [],
        sandbox: false,
        script: '''\
          def repository = "frontend"
          def aws_ecr_cmd = "aws ecr list-images" +
                            " --repository-name ${repository}" +
                            " --filter tagStatus=TAGGED" +
                            " --query imageIds[*].[imageTag]" +
                            " --region us-east-1 --output text"
          def aws_ecr_out = aws_ecr_cmd.execute() | "sort -V".execute()
          def images = aws_ecr_out.text.tokenize().reverse()
          return images
        '''.stripIndent()
      ]
    ]
  ]])
])

pipeline {
  agent any

  stages {  
    stage('First stage') {
      steps {
        sh 'echo "${image}"'
      }
    }
  }
}

答案 3 :(得分:0)

这是我的解决方法。

def envList
def dockerId
node {
    envList = "defaultValue\n" + sh (script: 'kubectl get namespaces --no-headers -o custom-columns=":metadata.name"', returnStdout: true).trim()
}
pipeline {
    agent any
    parameters {
        choice(choices: "${envList}", name: 'DEPLOYMENT_ENVIRONMENT', description: 'please choose the environment you want to deploy?')
        booleanParam(name: 'SECURITY_SCAN',defaultValue: false, description: 'container vulnerability scan')
    }

答案 4 :(得分:0)

我可以在没有插件的情况下以这种方式实现 使用声明式管道的 Jenkins 2.249.2, 以下模式通过动态下拉菜单提示用户 (让他选择一个分支):

(周围的 withCredentials 块是可选的,仅当您的脚本和 jenkins 配置确实使用凭据时才需要)

节点{

withCredentials([[$class: 'UsernamePasswordMultiBinding',
              credentialsId: 'user-credential-in-gitlab',
              usernameVariable: 'GIT_USERNAME',
              passwordVariable: 'GITLAB_ACCESS_TOKEN']]) {
    BRANCH_NAMES = sh (script: 'git ls-remote -h https://${GIT_USERNAME}:${GITLAB_ACCESS_TOKEN}@dns.name/gitlab/PROJS/PROJ.git | sed \'s/\\(.*\\)\\/\\(.*\\)/\\2/\' ', returnStdout:true).trim()
}

} 管道{

agent any

parameters {
    choice(
        name: 'BranchName',
        choices: "${BRANCH_NAMES}",
        description: 'to refresh the list, go to configure, disable "this build has parameters", launch build (without parameters)to reload the list and stop it, then launch it again (with parameters)'
    )
}

stages {
    stage("Run Tests") {
        steps {
            sh "echo SUCCESS on ${BranchName}"
        }
    }
}

}

缺点是应该刷新 jenkins 配置并使用空白运行来使用脚本刷新列表... 解决方案(不是我的):使用用于专门刷新值的附加参数可以减少此限制的烦恼:

parameters {
        booleanParam(name: 'REFRESH_BRANCHES', defaultValue: false, description: 'refresh BRANCH_NAMES branch list and launch no step')
}

然后在舞台上:

stage('a stage') {
   when {
      expression { 
         return ! params.REFRESH_BRANCHES.toBoolean()
      }
   }
   ...
}

答案 5 :(得分:-3)

choiceArray = [ "patch" , "minor" , "major" ]

properties([
    parameters([
            choice(choices: choiceArray.collect { "$it\n" }.join(' ') ,
                    description: '',
                    name: 'SOME_CHOICE')

    ])
])