Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use a Jenkins plugin inside a class?

I am pretty new to Jenkins/Groovy to please bear with me here.

I am working with a DSL inside a pipeline groovy script. The DSL instantiates a custom class that tries to use Jenkins plugins. I keep getting errors that appear as if the system is trying to access the plugins as direct members of the class...?

Jenkins Job: Pipeline Script

@Library('lib-jenkins-util@branchname') _  // contains dsl.groovy

dsl {
    x = 'value'
}

File: dsl.groovy

def call(body) {
def config = [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = config
body()

node('node-name') {

    stage('Stage 1') {
        def f = new Foo()
    }

}

File: Foo.groovy

class Foo implements Serializable {
    Foo() {
        // fails below
        sh "curl http://our-jenkins-server/xxx/api/json -user username:apitoken -o output.json"
        json = readJSON file: output.json
    }
}

Error:

hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: com.xxx.Foo.sh() is applicable for argument types: (org.codehaus.groovy.runtime.GStringImpl) values: [curl http://our-jenkins-server/xxx/api/json -user username:apitoken -o output.json]

Can someone please help me understand what I am missing? Is it not possible to directly call plugins from within a custom class?

like image 794
retsigam Avatar asked Jul 24 '18 22:07

retsigam


1 Answers

Ok, I found the answer: plugins such as sh, httpResponse, readJSON, etc are part of the Pipeline, so you have to send the pipeline context to your class in order to be able to use it.

I also had to move calls that used the Pipeline context to their own methods instead of inside the constructor to avoid a CpsCallableInvocation issue that caused the build to fail.

File: dls.groovy

def call(body) {
def config = [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = config
body()

node('node-name') {
    stage('Stage 1') {
        def f = new Foo(this)  // send pipeline context to class
    }
}

File: Foo.groovy

class Foo implements Serializable {
    def context

    Foo(context) {
        this.context = context
    }

    def doTheThing() {
        this.context.sh "curl http://our-jenkins-server/xxx/api/json -user username:apitoken -o output.json"
        def json = this.context.readJSON file: output.json
    }
}
like image 90
retsigam Avatar answered Oct 30 '22 09:10

retsigam