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?
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
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With