How to Fix -- Jenkins Post-build Action Groovy script fails to evaluate - jenkins

I'm new to Groovy and am trying to invoke a Groovy script as a Jenkins Post-build Action, but whenever I run it, I'm getting "ERROR: Failed to evaluate groovy script":
groovy.lang.MissingMethodException: No signature of method: Script1.stage() is applicable for argument types: (org.codehaus.groovy.runtime.GStringImpl, Script1$_run_closure1) values: [branch_1, Script1$_run_closure1#7e39737b]
Possible solutions: wait(), any(), isCase(java.lang.Object) at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:58)
Here is my code :
def warList1= ["one.war", "two.war", "three.war" ]
def branches = [:]
for (int i = 0; i < 10 ; i++) {
int index=i, branch = i+1
stage ("branch_${branch}"){
branches["branch_${branch}"] = {
node {
sshagent(credentials : ['someuser-SSH']){
sh "scp ${WORKSPACE}/${warList1[index]} someuser#<somefqdn>:/tmp/pscp/dev"
}
}
}
}
}
}

I think that your issue come from the fact that you can not use stage method in a Groovy Post Build Action. This method is only available in a pipeline script.

Related

Jenkins Job DSL does not take parameters

I have a Jenkins seed DSL job:
job("cronjob/${ACTION}_${ENVRIONMENT}_environment_CRONJOB") {
scm {
git('https://git_user#github.com/abc-Data/devops.git','*/develop')
}
triggers {
scm("${SCHEDULE}")
}
steps {
ansiblePlaybook("ansible/scripts/ansible-${ACTION}.yml") {
inventoryPath("/etc/ansible/hosts")
credentialsId("usercred")
extraVars {
extraVar('environment_name',"${ENVRIONMENT}",false)
}
}
}
}
ACTION, ENVIRONMENT and SCHDULE are parameters.
ACTION can have values of create or remove, and I have two ansible playbooks ansible-create.yml and ansible-remove.yml.
When I run the sseed job, I got the following error:
ERROR: (unknown source) No signature of method: javaposse.jobdsl.dsl.helpers.step.StepContext.ansiblePlaybook() is applicable for argument types: (org.codehaus.groovy.runtime.GStringImpl, script$_run_closure1$_closure4$_closure5) values: [ansible/scripts/ansible-create.yml, ...]
Finished: FAILURE
The ansiblePlaybook("ansible/scripts/ansible-${ACTION}.yml") does not work with the variable ACTION.
If I hard code the the script name in ansiblePlaybook, the seed job will create a new job.
The other two variables work fine in the DSL script.
What did I miss here?
Thanks!
As #daggett suggested above, I changed the code as below:
job("cronjob/${ACTION}_${ENVRIONMENT}_environment_CRONJOB") {
scm {
git('https://git_user#github.com/abc-Data/devops.git','*/develop')
}
triggers {
scm("${SCHEDULE}")
}
steps {
ansiblePlaybook("ansible/scripts/ansible-${ACTION}.yml" as String) {
inventoryPath("/etc/ansible/hosts")
credentialsId("usercred")
extraVars {
extraVar('environment_name',"${ENVRIONMENT}",false)
}
}
}
}
It works as expect and create a new job with the use entered variable values. Thanks to you again #daggett!

Jenkins samples groovy code vs plain groovy (closure errors)

In a jenkins shared library I can do something like this:
Jenkinsfile
#Library(value="my-shared-lib", changelog=false) _
jobGenerator {
notifier = [notifyEveryUnstableBuild: true]
}
sharedLibary/vars/jobGenerator.groovy
def call(body) {
println 'hi!'
}
To better understand the flow of whats goes on I have created two groovy files locally (with no reference to jenkins at all):
samples/launcher.groovy
jobGenerator {
s = 's'
}
samples/jobGenerator.groovy
def call(body) {
println 'inside jobGenerator '
}
But when I run that with:
groovy "/home/user/samples/launcher.groovy"
I get:
Caught: groovy.lang.MissingMethodException: No signature of method: launcher.jobGenerator() is applicable for argument types: (launcher$_run_closure1) values: [launcher$_run_closure1#61019f59]
groovy.lang.MissingMethodException: No signature of method: launcher.jobGenerator() is applicable for argument types: (launcher$_run_closure1) values: [launcher$_run_closure1#61019f59]
at launcher.run(launcher.groovy:2)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
So how much of the above code is jenkins/shared library specific? And is it even possible to write something like the above in plain groovy?
Or put in another way. How do I convert the above jenkins code to plain groovy?
IMHO following is close to what jenkins is doing
launcher.groovy
// load library scripts/functions
def binding = this.getBinding()
def gshell = new GroovyShell(this.getClass().getClassLoader(),binding)
new File("./my-lib").traverse(nameFilter: ~/.*\.groovy$/){f-> binding[f.name[0..-8]] = gshell.parse(f) }
// main
bar{
foo(name:"world")
}
./my-lib/foo.groovy
def call (Map m){
return "hello $m.name"
}
./my-lib/bar.groovy
def call (Closure c){
println ( "BAR: "+c() )
}
#> groovy launcher.groovy
BAR: hello world

Get environment parameters in Jenkins using groovy

I'm trying to fetch the environment parameters/variables from Jenkins using a System Groovy script.
I want to pass these variables to a post-build step, but I'm getting the following error while trying to get these variables to show up in the jenkins console.
Error : groovy.lang.MissingMethodException: No signature of method:org.jenkinsci.plugins.workflow.job.Workflowjob.getProperties() is applicable for argument types: (java.lang.Class) values: [class hudson.model.ParametersDefinitionProperty]
How can I fetch these parameters?
Would appreciate any help I can get. Thanks!
import hudson.model.*
for(item in Hudson.instance.items) {
prop = item.getProperty(ParametersDefinitionProperty.class)
if(prop != null) {
echo "Browser name: ${BROWSER_NAME}"
echo "env name: ${ENV_NAME}"
println("Parameters for "+item.name)
for(param in prop.getParameterDefinitions()) {
try {
echo "param.name+""+param.defaultValue"
}
catch(Exception e) {
println(e.printStackTrace())
}
}
}
}
echo "groovy ends here"

jenkinspipeline groovy.lang.MissingMethodException: No signature of method

I have created a pipeline that takes an array of JSON objects and will call a shared library which will iterate over the JSON objects
When trying to run the Jenkins job to test that I can forward the objects but I'm seeing the following error:
hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: imageBuild.call() is applicable for argument types: (java.lang.String) values: [[{"dockerConfig":"home/pipelines/conf/journeys/dockerbuild.yaml","aquaConfig":"home/pipelines/conf/journeys/aquascan.yaml","gtag": "v1.0.1","preFixName": "journey1"},{"dockerConfig":"home/pipelines/conf/if.com/dockerbuild.yaml","aquaConfig":"home/pipelines/conf/if.com/aquascan.yaml","gtag": "v2.0.2","preFixName": "journey2"},{"dockerConfig":"home/pipelines/conf/colleague/dockerbuild.yaml","aquaConfig":"home/pipelines/conf/colleague/aquascan.yaml","gtag": "v3.0.3","preFixName": "journey2"}]]
Possible solutions: call(), call(java.util.Map), wait(), any(), wait(long), main([Ljava.lang.String;)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:58)
Code:
library identifier: 'jenkins-sharedlib-cooking#BB-3611', retriever: modernSCM([$class: 'GitSCMSource',
remote: 'https://github.com/lbg-gcp-foundation/jenkins-sharedlib-cooking-lifecycle.git',
credentialsId: 'jenkinsPAT'])
def configList = '[{"dockerConfig":"home/pipelines/conf/journeys/dockerbuild.yaml","aquaConfig":"home/pipelines/conf/journeys/aquascan.yaml","gtag": "v1.0.1","preFixName": "journey1"},{"dockerConfig":"home/pipelines/conf/if.com/dockerbuild.yaml","aquaConfig":"home/pipelines/conf/if.com/aquascan.yaml","gtag": "v2.0.2","preFixName": "journey2"},{"dockerConfig":"home/pipelines/conf/colleague/dockerbuild.yaml","aquaConfig":"home/pipelines/conf/colleague/aquascan.yaml","gtag": "v3.0.3","preFixName": "journey2"}]'
pipeline {
environment {
def config =
brand =
environmentName =
CLUSTER_NAME =
CLUSTER_PROJECT =
VERSION = '1.0.0'
}
options {
ansiColor('xterm')
timeout(time: 150, unit: 'MINUTES')
disableConcurrentBuilds()
buildDiscarder(logRotator(numToKeepStr: '100'))
}
agent {
kubernetes {
label "jrn-${UUID.randomUUID().toString()}"
yamlFile "pipelines/conf/podTemplate.yaml"
}
}
stages {
stage('Stage 6 - Docker Image ') {
parallel {
stage ('Docker Image - Journeys') {
steps {
echo "*********************** Docker Journeys ***********************************"
container('docker') {
echo "Building the docker image..."
imageBuild(configList)
}
archiveArtifacts artifacts: "*.html", allowEmptyArchive: true
}
}
}enter code here
}
}
Looks like the groovy method or global variable imageBuild in the shared library Jenkins-shared lib-cooking#BB-3611 does not expecting any parameter but you are trying to pass a string, that's the reason you are getting MissingMethodException.
with the details
hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: imageBuild.call() is applicable for argument types: (java.lang.String) values
To fix the issue, you have to change the shared library method or global variable imageBuild from imageBuild() to imageBuild(String param) or imageBuild(def param)
I will try to illustrate with an example similar to your example for your reference.
Assuming you have a shared library in a git repository named - jenkins-sharedlib-cooking-lifecycle and you are following the folder structure suggested by Jenkins shared library documentation
// vars/imageBuild.groovy
import groovy.json.JsonSlurper
def call(def imagebuildParameter) {
def jsonSlurper = new JsonSlurper()
def object = jsonSlurper.parseText(imagebuildParameter)
// use loop on object to retrive the value like below
println object[0].name
}
//Jenkinsfile
node {
stage('stageName') {
def x = '[{"name": "foo"},{"name": "bar"}]'
imageBuild(x)
}
}

jenkins - java.io.IOException: Cannot run program "groovy"

I have the following groovy script in a jenkins build
def myFractureNO = ${FRACTURE_NO};
def myBuildNumber = ${BUILD_NUMBER};
def projectXml = new XmlSlurper().parseText("curl http://sparkbuilder.corp.adobe.com:8080/job/FractureAUT/api/xml".execute().text);
projectXml.build.each {
if(it.number < myBuildNumber)
{
def jobXml = new XmlSlurper().parseText(("curl http://sparkbuilder.corp.adobe.com:8080/job/FractureAUT/" + it.number + "/api/xml").execute().text);
if(1) {
def myparams = jobXml.getAction(hudson.model.ParametersAction.class);
for( p in myparams ) {
if (p.name.toString == "FRACTURE_NO") {
if (p.value.toString() == "$myFractureNO") {
println p.value.toString();
}
}
}
}
}
}
I get an error saying
java.io.IOException: Cannot run program "groovy"
when jenkins tries to run this script on a Jenkins slave. How do I fix this?
Now I get the following error when trying to execute the script as a system script
groovy.lang.MissingMethodException: No signature of method: Script1.$() is applicable for argument types: (Script1$_run_closure1) values [Script1$_run_closure1#5e38bed4]
Possible solutions: is(java.lang.Object), run(), run(), any(), any(groovy.lang.Closure), use([Ljava.lang.Object;)
at Script1.run(Script1.groovy:1)
The following is not valid groovy:
def myFractureNO = ${FRACTURE_NO};
def myBuildNumber = ${BUILD_NUMBER};
I'm guessing you're trying to get some variables from the environment. See this related question: https://stackoverflow.com/a/26428580/172599

Resources