1

I want to have this code with exactly this syntax in my pipeline script:

withXCredentials(id: 'some-cred-id', usernameVar: 'USER', passwordVar: 'PASS') {
   //do some stuff with $USER and $PASS
   echo "${env.USER} - ${env.PASS}"
}

Note that you can put any code within withXCredenitals to be executed. withXCredentials.groovy resides in my Jenkins shared library under vars folder and it will use Jenkins original withCredentials:

//withXCredentials.groovy
def userVar = params.usernameVar
def passwordVar = params.passwordVar
def credentialsId = params.credentialsId

withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: credentialsId, usernameVariable: usernameVar, passwordVariable: passwordVar]]) {

        body()
}

I am still learning advanced groovy stuff but I can't work out how to do this.

Please note:

My question is more about the syntax in groovy and using Closure and the answer here is not what I am after. With that solution, I need to instantiate the class first and then call the method. So I'm trying to avoid doing something like this:

new WithXCredentials(this).doSomthing(credentialsId, userVar, passwordVar)

In Jenkins documentation it has an example of using closure:

// vars/windows.groovy
def call(Closure body) {
    node('windows') {
        body()
    }
}

//the above can be called like this:
windows {
    bat "cmd /?"
}

But it doesn't explain how to pass parameters like this

windows(param1, param2) {
    bat "cmd /?"
}

See here

xbmono
  • 2,084
  • 2
  • 30
  • 50
  • Does this answer your question? [Jenkins Pipelines: How to use withCredentials() from a shared-variable script](https://stackoverflow.com/questions/51329766/jenkins-pipelines-how-to-use-withcredentials-from-a-shared-variable-script) – S.Spieker Mar 03 '20 at 06:23
  • @S.Spieker I guess my question is more about the syntax and using `vars` in shared library. So I want to use the new `withXCredentials` exactly the same as Jenkins' `withCredentials`. With the answer in the link, I need to instantiate the class and pass in `this` to its constructor and then call the method `doArchiveToNexus` like this: `new Utitlities(this).doArchiveToNexus(...)` .. I don't want to do it that way but rather the way I mentioned in my question. Thanks – xbmono Mar 03 '20 at 21:22

1 Answers1

3

So after digging internet I finally found the answer. In case anyone needs the same thing. The following code will work:

// filename in shared lib: /vars/withXCredentials.groovy

def call(map, Closure body) {

    def credentialsId = map.credentialsId
    def passwordVariable =  map.passwordVariable
    def usernameVariable = map.usernameVariable
    withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: credentialsId, usernameVariable: usernameVariable, passwordVariable: passwordVariable]]) {
        echo 'INSIDE withXCredentials'
        echo env."${passwordVariable}"
        echo env."${usernameVariable}"
        body()
    }

}

With this you can have the following in your pipeline:

node('name') {
   withXCredentials([credentialsId: 'some-credential', passwordVariable: 'my_password', 
            usernameVariable: 'my_username']) { 
      echo 'Outside withXCredenitals'
      checkout_some_code username: "$env.my_username", password: "$env.my_password"
   }
}

xbmono
  • 2,084
  • 2
  • 30
  • 50