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