jenkins pipeline: can't pass build parameters to shared library vars

白昼怎懂夜的黑 提交于 2019-12-23 20:00:55

问题


Basically I can't pass build properties to Library var call without extra nonsense.

jenkinsfile relevant chunk:

tc_test{
    repo = 'test1'
    folder = 'test2'
    submodules = true
    refs = params.GitCheckout
}

That results in error

java.lang.NullPointerException: Cannot get property 'GitCheckout' on null object

This, however, works:

def a1 = params.GitCheckout
tc_test{
    repo = 'test1'
    folder = 'test2'
    submodules = true
    refs = a1
}

The contents of the vars/tc_test.groovy in shared library :

def call ( body ) {

    def config = [:]
    body.resolveStrategy = Closure.DELEGATE_FIRST
    body.delegate = config
    try {
        body()
    } catch(e) {
        currentBuild.result = "FAILURE";
        throw e;
    } finally {

        config.each{ k, v -> println "${k}:${v}" }

    }
}

I'm not really good with groovy, so it might be something obvious.


回答1:


Got the answer from Jenkins JIRA.

Small workaround is using maps instead of closures:

tc_test ([
  repo: 'test1',
  folder: 'test2',
  submodules: true,
  refs = params.GitCheckout
])

May have drawbacks, but for me that worked perfectly.

Still have to transfer params as argument to have access to them, but at least the code makes more sense now.




回答2:


Suppose you have a sharedLibrary to call a Rundeck Job,

Parameters:
1 runDeckJobId - Rundeck unique job id thats available in settings.
2 role - AD Group associated with Rundeck Job
3 runDeckProject - Name of the project configured in rundeck.
4 optional - All optional parameters as a Map.
- rundeckInstanceType - Rundeck instances are currently in UK or HK.
- retries - Number of retries for checking job status once started (Default value=100)
- timeout - Number of seconds to be waited before each retry (Default value=15)
- verbose - If verbose calls need to be made in the rundeck api calls (Default value=false)
- rundeckArgs - All rundeck parameters as a map. Eg: Name of the playBook, location of inventory file.

Example Usage in JenkinsFile:

if (isRundeckDeployment == "true") {
    def optional = [
        rundeckInstance : "UK",
        timeout : 10,
        rundeckArgs : [
            artifactPack      : "${artifactPath}",
            DEPLOYMENT_ENVIRONMENT: "${deploymentEnvironment}",
            EXTRA_ARGS            : "-e deployment_serial=1"
        ]
    ]
    triggerRundeckJob("job-id", "AD-group-id", "BitbucketKey", optional)
} 

Shared Library Function with filename : triggerRundeckJob in vars folder

def call(String rundeckJobId, String role, String  rundeckProject, Map optional) {

    String jobUserId
    wrap([$class: 'BuildUser']) {
        jobUserId = "${BUILD_USER_ID}"
    }
    // Determine rundeck instance type, by default instance is UK (rundeckAuthToken)
    String mainRundeckId  = optional.rundeckInstance == "HK" ? "rundeckAuthTokenHK": "rundeckAuthToken"
    String rundeckBaseURL = optional.rundeckInstance == "HK" ? "https://rundeckUrl/selfservice" : "https://rundeckUrl:9043/selfservice"

    withCredentials([string(credentialsId: mainRundeckId, variable: 'mainRundeckIdVariable')]) {
        int retries     = optional.retries ?: 100
        int timeout     = optional.timeout ?: 15
        String verbose  = optional.verbose? "-v" : "-s"
        String rundeckArgsString = optional.rundeckArgs.collect{ "-${it.key} \\\"${it.value}\\\"" }.join(" ")

        def tokenResponse = sh(returnStdout: true, script: "curl -k ${verbose} -X POST -d '{\"user\": \"${jobUserId}\",\"roles\":\"${role}\",\"duration\":\"30m\"}' -H Accept:application/json -H 'Content-Type: application/json' -H X-Rundeck-Auth-Token:${mainRundeckIdVariable} ${rundeckBaseURL}/api/19/tokens")
        def tokenResponseJson = readJSON text: tokenResponse

        def rundeckResponse =  sh(returnStdout: true, script: "curl -k ${verbose} --data-urlencode argString=\"${rundeckArgsString}\" -H Accept:application/json -H X-Rundeck-Auth-Token:${tokenResponseJson.token} ${rundeckBaseURL}/api/19/job/${rundeckJobId}/run")
        def rundeckResponseJson = readJSON text: rundeckResponse

        if(!rundeckResponseJson.error){
            while(true){
                if(retries==0) {
                    currentBuild.result = "FAILURE"
                    echo "Rundeck Job Timedout, See: ${rundeckBaseURL}/project/${rundeckProject}/job/show/${rundeckJobId}"
                    break;
                }
                def jobStateResponse = sh(returnStdout: true, script:"curl -k ${verbose} -H Accept:application/json -H X-Rundeck-Auth-Token:${tokenResponseJson.token} ${rundeckBaseURL}/api/19/execution/${rundeckResponseJson.id}/state")
                def jobStateResponseJson = readJSON text: jobStateResponse

                if(jobStateResponseJson.completed) {
                    if(jobStateResponseJson.executionState == "FAILED") {
                        currentBuild.result = "FAILURE"
                        echo "Rundeck Job FAILED, See: ${rundeckBaseURL}/project/${rundeckProject}/job/show/${rundeckJobId}"
                        break
                    }else{
                        currentBuild.result = "SUCCESS"
                        echo "Rundeck Job SUCCESS, See: ${rundeckBaseURL}/project/${rundeckProject}/job/show/${rundeckJobId}"
                        break
                    }
                }
                else{
                    sleep timeout
                }
                retries--
            }
        }else{
            echo "******************Rundeck Job Error: ${rundeckResponseJson.message} ******************"
            currentBuild.result = "FAILURE"
        }
    }
}


来源:https://stackoverflow.com/questions/44659759/jenkins-pipeline-cant-pass-build-parameters-to-shared-library-vars

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!