Custom Groovy function with arguments doesn't work in Jenkins pipeline - jenkins

I'm using a function to set environment variables in Jenkins pipeline. I've noticed that if I declare function without argument, it works, but if I declare function that accepts 1 string argument, Jenkins throws error No such DSL method 'get_metadata' found among steps while running my pipeline.
def get_metadata(String type) {
switch(type) {
case "env":
return "environment name";
break;
case "domain":
return "domain name";
break;
case "cloud":
return "cloud name";
break;
default:
return "none";
break;
}
}
pipeline {
environment {
PROJECT=get_metadata()
CLOUD=get_metadata(type: "cloud")
DOMAIN=get_metadata(type: "domain")
ENVIRONMENT=get_metadata(type: "env")
}
}
Function without argument works when I call it like get_metadata()
def get_metadata() {
<...>
}
Jenkins version is 2.289.2.

Your get_metadata does not define a default value for type and therefore the call to PROJECT=get_metadata() throws an error, as you can't use it as is without passing the type parameter.
To solve it you can just add a default value to your function:
def get_metadata(String type = '') {
switch(type) {
case "env":
return "environment name";
case "domain":
return "domain name";
case "cloud":
return "cloud name";
default:
return "none";
}
}

Related

How to show jenkins.currentBuild.result to "SUCCESS" not "null"

The problem is when the pipeline runs and passes I get "null" which I know "null" is a success. When a stage fails the notification properly shows "FAILURE"
Where should I be putting jenkins.currentBuild.result = CommonStrings.SUCCESS or what needs altered?
This is the method I utilize to make the curl:
def notifyTeam(String webhook2) {
jenkins.stage('Post Build Notify Teams') {
jenkins.echo "${jenkins.currentBuild.result}"
String jobName = jenkins.currentBuild.fullDisplayName
String status = jenkins.currentBuild.result
jenkins.echo "Job Name: ${jobName} STATUS: ${status}"
jenkins.sh "curl -H 'Content-Type: application/json' -d '{\"text\": \"Job Name: ${jobName} Status: ${status} URL: <${jenkins.env.BUILD_URL}>\"}' ${webhook2}"
jenkins.echo "${status}"
}
}
This is the closure pipeline:
try {
chat.prebuildChat(email, pipelineAttrs)
pipeline.run()
pipelineAttrs.getBuild().post()
} catch (e) {
jenkins.currentBuild.result = CommonStrings.FAILURE
throw e
} finally {
switch (product) {
case Product.****:
chat.notifyTeam(CommonStrings.****_WEBHOOK)
break
case Product.****:
chat.winNotifyTeam(CommonStrings.****_WEBHOOK)
break
case Product.****:
chat.notifyTeam(CommonStrings.****_WEBHOOK)
break
case Product.****:
chat.notifyTeam(CommonStrings.****_WEBHOOK)
break
case Product.****:
chat.notifyTeam(CommonStrings.****_WEBHOOK)
break
case Product.****:
chat.notifyTeam(CommonStrings.****_WEBHOOK)
break
}
chat.postbuildChat(email, pipelineAttrs)
jenkins.dir(jenkins.env.WORKSPACE) {
jenkinsUtils.cleanupWorkspace()
}
Any assistance would be greatly appreciated.
Try
String status = jenkins.currentBuild.result ?: 'SUCCESS'

IllegalArgumentException: Expected named arguments (Jenkins)

I am getting the following error when trying to run my jenkins job. Any help would be much appreciated
java.lang.IllegalArgumentException: Expected named arguments but got
[org.jenkinsci.plugins.workflow.cps.CpsClosure2#33c7c4a6,
org.jenkinsci.plugins.workflow.cps.CpsClosure2#79505a8c,
org.jenkinsci.plugins.workflow.cps.CpsClosure2#6a96df3,
org.jenkinsci.plugins.workflow.cps.CpsClosure2#1a0cb771,
org.jenkinsci.plugins.workflow.cps.CpsClosure2#17e3a262] at
org.jenkinsci.plugins.workflow.cps.DSL.singleParam(DSL.java:606) at
org.jenkinsci.plugins.workflow.cps.DSL.parseArgs(DSL.java:594) at
org.jenkinsci.plugins.workflow.cps.DSL.parseArgs(DSL.java:534) at
org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:219) at
org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:178) at
org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:122)
at sun.reflect.GeneratedMethodAccessor102.invoke(Unknown Source)
My code is:
node("dvsacvsmgmt") {
stage("Build") {
def buildJobs = []
for (BACKEND_SERVICE in BACKEND_SERVICES) {
SVC = BACKEND_SERVICE.replaceAll('-','_')
switch (BRANCH_SVC) {
case ["develop","master"]:
def buildJob = {
build "${ROOT_FOLDER}/2_Build/Backend/${SVC}/job_build_backend_" + BRANCH_SVC + "_" + SVC +".groovy"
}
buildJobs.add(buildJob)
break
default:
def buildJob = {
build "job_${SVC}": "${ROOT_FOLDER}/2_Build/Backend/${SVC}/job_build_backend_" + BRANCH_SVC + "_" + SVC +".groovy",
parameters: [gitParameter(name: "BRANCH", value: BRANCH_SVC)]
}
buildJobs.add(buildJob)
break
}
}
parallel(buildJobs)
}
}
NOTE: My variables are defined at the top,
BRANCH, BRANCH_SVC, ROOT_FOLDER, BACKEND_SERVICES
You see this exception because buildJobs in your example is a list of closures and it should be a map instead. It would make sense to use backend service name as a key for the map you pass to parallel() method. Consider the following changes to your code:
node("dvsacvsmgmt") {
stage("Build") {
def buildJobs = [:]
for (BACKEND_SERVICE in BACKEND_SERVICES) {
SVC = BACKEND_SERVICE.replaceAll('-','_')
switch (BRANCH_SVC) {
case ["develop","master"]:
def buildJob = {
build "${ROOT_FOLDER}/2_Build/Backend/${SVC}/job_build_backend_" + BRANCH_SVC + "_" + SVC +".groovy"
}
buildJobs.put(BACKEND_SERVICE, buildJob)
break
default:
def buildJob = {
build "job_${SVC}": "${ROOT_FOLDER}/2_Build/Backend/${SVC}/job_build_backend_" + BRANCH_SVC + "_" + SVC +".groovy",
parameters: [gitParameter(name: "BRANCH", value: BRANCH_SVC)]
}
buildJobs.put(BACKEND_SERVICE, buildJob)
break
}
}
parallel(buildJobs)
}
}
It invokes
buildJobs.put(BACKEND_SERVICE, buildJob)
instead
buildJobs.add(buildJob)
to create a map that is seen as named arguments in parallel method call.

Jenkins PER USER default parameter values?

We are using a parameterized Jenkins build job, and I would like to have default values for some parameters specific for myself, e.g. the dev branch name I mostly use. Is it possible? We do have personal users in Jenkins.
You could do it by:
Create a scriptler which checks the current user and returns the appropriate value:
def user = jenkins.model.Jenkins.getAuthentication().getName();
def returnValue
switch (user) {
case ['user1','user2']:
returnValue = 'xyz'
break;
case ['user3']:
returnValue = 'abc'
break;
default:
returnValue = '00'
break;
}
return returnValue
If you want to use the Active Choices Plugin your script will need to return a list:
def user = jenkins.model.Jenkins.getAuthentication().getName();
def returnValue = [];
switch (user) {
case ['user1','user2']:
returnValue << 'xyz'
break;
case ['mtlelj']:
returnValue << 'abc'
break;
default:
returnValue << '00'
break;
}
return returnValue
Configure your parameterized build to have a Dynamic Parameter (Scriptler) or an Active Choices parameter and reference the script you created as it's source.
If you don't want a script centrally managed by admins, the Active Choices Parameter allows you to use the code within the parameter definition. I'm using:
Jenkins ver 2.32.3
Scriptler Plugin ver 2.9
Dynamic Parameter Plugin ver 2.9
Active Choices Plugin ver 2.9

Jenkins Active Choices Parameter plugin not working as expected

I have a hidden parameter in Jenkins called platformType. I want to display choices based on the parameter platformType. I created the following groovy script but it doesn't work
if (platformType.equals("android")) {
return ['7.0', '6.0']
} else (platformType.equals("ios")) {
return ['10.0', '9.0']
}
Pls see the screenshot below
quite sure you did not specify the platformType as a parameter to platformVersion or you have other error in your code..
without error handling you just don't see it.
in your script you can catch the exception like this:
try {
if (platformType.equals("android")) {
return ['7.0', '6.0']
} else if(platformType.equals("ios")) {
return ['10.0', '9.0']
}
}catch(e){ return [e.toString()] }
in this case you'll see the error in your choice field
Looks you are missing if in the else part.
It is supposed to be:
if ('android' == platformType) {
return ['7.0', '6.0']
} else if ('ios' == platformType) {
return ['10.0', '9.0']
} else return []

Mock Grails configurations in Integration test cases

How to mock Grails configurations in Integration test cases?
Consider following scenario
MyController.groovy
def save() {
baseLink = Holders.getFlatConfig()["grails.test.base.link"]
if (!baseLink) {
response.status = HttpStatus.NOT_ACCEPTABLE.value
respond([message: "Configuration not found."])
return
}
// Some Code
}
MyControllerIntegrationSpec.groovy
def save() {
baseLink = Holders.getFlatConfig()["grails.test.base.link"]
if (!baseLink) {
response.status = HttpStatus.NOT_ACCEPTABLE.value
respond([message: "Configuration not found."])
return
}
// Some Code
}
def setup() {
//Some Setup Code
//Update configuration
grailsApplication.config["grails.test.base.link"] = true
}
void "Configuration not found"() {
when: ""
myController.save()
then: "Configuration not found"
controller.response.json["message"] == "Configuration not found."
controller.response.status == HttpStatus.NOT_ACCEPTABLE.value
}
void "Configuration found"() {
when: ""
myController.save()
then: "Configuration found"
//some code
}
Assuming you know why you want to mock the grails application in an integration test, my suggestion would be to use DI of grailsApplication. Is there any reason why you use baseLink = Holders.getFlatConfig()["grails.test.base.link"] instead of grailsApplication.config.grails.test.base.link ? What grails version are you using?
When using grailsApplication as a dependency the controller, you can inject it in the test:
def setup() {
myController.grailsApplication = [config: [grails: [test: [base: [link: true]]]]]
}
void "Configuration found"() {
when: ""
myController.save()
then: "Configuration found"
//some code
}

Resources