Groovy pipeline if-else condition - groovy

So I try to set variable base of my job {currentBuild.currentResult} status.
script {
if ({currentBuild.currentResult} == "SUCCESS") {
HEADER_COLOR = "green"
} else {
HEADER_COLOR = "Red"
}
}
And although the job pass and the status is SUCCESS the else condition is executed so I put print inside the else section:
else {
echo "${currentBuild.currentResult}"
HEADER_COLOR = "red"
}
And the value inside echo "${currentBuild.currentResult}" is SUCCESS.
Maybe I need to use this if-else in some other way ?

You if-else is ok, but the way you feed it with conditions is wrong.
It should be either:
if (currentBuild.currentResult == "SUCCESS") {
or (strange way)
if ("${currentBuild.currentResult}" == "SUCCESS") {
or (the hard way)
if ({currentBuild.currentResult}() == "SUCCESS") {
or (the harder way)
if ({currentBuild.currentResult}.call() == "SUCCESS") {
WHY?
Your original if would always evaluate to false, because you a comparing an inline-closure instance to "SUCCESS" which is never true.

Related

Hide steps, Jenkins, Groovy

Is it possible to hide a build step in jenkins pipeline?
I use shared library I would like to hide (hide==it will not present on the GUI) some steps when these is not needed
Thank you,
First off, I presume you are trying to hide a Stage, not a Step?
If so, it is not possible to completely hide it, simply because some builds might have the stage turned on, and some might not - therefore the stage should always be there, but empty(disabled) when excluded from the build.
You need to put when { expression { return ... } } at the beginning of your stage and return any expression that evaluates to true or false depending on if you want the stage to run or not.
Example code:
stage('My Test Stage') {
when {
expression {return <TRUE OR FALSE HERE>}
}
steps {
...
}
}
Solution (workaround):
stage('Steps for hide') {
steps {
script {
if ( conditions == "true" ) {
echo "steps 1"
}
else if ( conditions == "false" ){
echo "steps 2"
}
else if ( conditions == "null" ) {
echo "No conditions step required."
}
}
}
}

Groovy compare string

I have the Groovy code as below
def retVal = sh(returnStdout: true, script: "curl ${URI}; echo \$?")
println("Return value: ${retVal}") -> it printed 0
if (retVal == "0") {
println("Successfull") -> it doesn't go here
}
why the above condition can't be catched?
First of all, you seem to be using the Jenkins API incorrectly.
If all you need is the exit code of the process, use returnStatus: true:
def retVal = sh(returnStatus: true, script: "curl ${URI}")
if (retVal == 0) {
println 'success'
} else {
println "Something wrong, exit code was $retVal")
}
Now, if you really want the stdout instead, perhaps clean up the String first by calling trim() on it or try to match the String against a regex:
if (retValue ~== /\s*0\s*/) {
println "success"
} else {
println "Something wrong, exit code was '$retVal'")
}
I always put quotes around a value I print to make sure new-lines or whitespaces don't make me waste time with bad values.

Elegant way to check if multiple strings are empty

How can I check if multiple strings are empty in an elegant way? This is how I currently do it:
//if one required field is empty, close the connection
if (registerRequest.Email == "") ||
(registerRequest.PhoneNumber == "")||
(registerRequest.NachName =="") ||
(registerRequest.VorName =="") ||
(registerRequest.Password =="") ||
(registerRequest.VerificationId ==""){
//Could not proceed
w.WriteHeader(UNABLE_TO_PROCEED)
w.Write([]byte("Unable to register account."))
return
}
Note: You may use the solution below if you keep the "is-valid" condition in your handler, and also if you separate your condition into another function or method.
You can create a simple helper function, which has a variadic parameter, and you can call it with any number of string values:
func containsEmpty(ss ...string) bool {
for _, s := range ss {
if s == "" {
return true
}
}
return false
}
Example using it:
if containsEmpty("one", "two", "") {
fmt.Println("One is empty!")
} else {
fmt.Println("All is non-empty.")
}
if containsEmpty("one", "two", "three") {
fmt.Println("One is empty!")
} else {
fmt.Println("All is non-empty.")
}
Output of the above (try it on the Go Playground):
One is empty!
All is non-empty.
Your example would look like this:
if containsEmpty(registerRequest.Email,
registerRequest.PhoneNumber,
registerRequest.NachName,
registerRequest.VorName,
registerRequest.Password,
registerRequest.VerificationId) {
// One of the listed strings is empty
}
Also registerRequest is a kinda long name, it could be shortened to like r. If you can't or don't want to rename it in the surrounding code and if you want to shorten the condition, you could also do something like this:
If registerRequest is a pointer (or interface), you could also write:
if r := registerRequest; containsEmpty(r.Email,
r.PhoneNumber,
r.NachName,
r.VorName,
r.Password,
r.VerificationId) {
// One of the listed strings is empty
}
Actually you can do this even if registerRequest is not a pointer, but then the struct will be copied. If registerRequest is a struct, then you can take its address to avoid having to copy it like this:
if r := &registerRequest; containsEmpty(r.Email,
r.PhoneNumber,
r.NachName,
r.VorName,
r.Password,
r.VerificationId) {
// One of the listed strings is empty
}
As Mario Santini mentioned in comment, a way to increase testability, encapsulate this logic, and decouple it from your handler method (which judging by the number of fields looks like it is at risk of changing at a different rate than your handler) could be to put this logic in a function:
func validRequest(registerRequest ?) bool {
return registerRequest.Email == "" ||
registerRequest.PhoneNumber == "" ||
registerRequest.NachName == "" ||
registerRequest.VorName == "" ||
registerRequest.Password == "" ||
registerRequest.VerificationId == ""
}
This now supports very focused, table driven tests, that can exercise what it means to be a valid request independent of any method involving writing headers.
It allows you to verify the valid/invalid path of your enclosing function, but to have very focused tests here. It also allows you to change what it means to be a valid request and verify it independent of your enclosing function.
You can use a switch:
switch "" {
case registerRequest.Email,
registerRequest.NachName,
registerRequest.Password,
registerRequest.PhoneNumber,
registerRequest.VerificationId,
registerRequest.VorName:
w.WriteHeader(UNABLE_TO_PROCEED)
w.Write([]byte("Unable to register account."))
return
}
https://golang.org/ref/spec#Switch_statements

Is There a way to check if(do.condion=='11') in Groovy DSL

Is There a way to check if(do.condion=='11') in Groovy DSL.
if(object.member == '2') //then do my logic
I am not able to use ==. its not throwing any error it just going to next statement
If I'm understanding your DSL correctly, formatted for clarity it looks like this:
AcceptILPN {
input scanCase
if(workflowParameters.reserveVerificationModeParm.equals("1")) next AcceptSKUQuantity
if(workflowParameters.validateCarton.equals("1")) next AcceptOLPNOrTote
if(workflowDO.nextDtlPresent) next AcceptILPN else next AcceptPickCart
}
To see what's happening, here's the same code with a more formal syntax:
AcceptILPN {
input(scanCase)
if(workflowParameters.reserveVerificationModeParm.equals("1")) {
next(AcceptSKUQuantity)
}
if(workflowParameters.validateCarton.equals("1")) {
next(AcceptOLPNOrTote)
)
if(workflowDO.nextDtlPresent) {
next(AcceptILPN)
} else {
next(AcceptPickCart)
}
}
As you can see, even when the first if expression evaluates to true the following if blocks will execute because there's nothing (at least visible in the DSL) that exits the Closure prematurely. It seems you're looking for something like this:
AcceptILPN {
input(scanCase)
if(workflowParameters.reserveVerificationModeParm.equals("1")) {
next(AcceptSKUQuantity)
}
else if(workflowParameters.validateCarton.equals("1")) {
next(AcceptOLPNOrTote)
)
else if(workflowDO.nextDtlPresent) {
next(AcceptILPN)
} else {
next(AcceptPickCart)
}
}

Jenkins Groovy Script finding null testResultAction for a successful run

We have an email report writer for test suites on jenkins. It uses a groovy script to find the correct reports and then make an HTML report detailing the test status, last time ran, links etc.
hudson.model.Hudson.instance.getItems(hudson.model.FreeStyleProject).each { project ->
if(project.name.contains(searchCriteria)){
if(project.lastBuild.testResultAction == null){
tr(){
td(project.name)
td(){
b("No Results")
}
...
}
}
else{
if(project.lastBuild.testResultAction.failCount > 0){
tr(){
td(project.name)
td(){
b(style:'color:red', "FAIL")
}
...
}
}
else{
tr(){
td(project.name)
td(){
b(style:'color:red', "PASS")
}
...
}
}
}
}
}
Usually everything runs fine, but recently one or two specific builds have started to be returned consistently as "No results" i.e. their .testResultAction is null. I've checked the actual value for testResultAction, and it is indeed a null, despite them running a clean test that Jenkins itself recognises as such.
The tests have been re-ran, and the jenkins build deleted and remade; neither helped. This problem seems to be haunting certain, unrelated, builds. Is there a particular flaw in Jenkins here that I should know about that causes the testResultAction to default to null and not change? Otherwise, can anyone suggest what might be causing this to happen, or how I can stop it?
That method is deprecated and was giving me null too. I had more success with this:
project.lastBuild.getAction(hudson.tasks.test.AggregatedTestResultAction.class)
Though it can be null just because there are no tests in the project.
Anyway, here's a method for testing the results, which works for me.
def reportOnTestsForBuild(build) {
testResultAction = build.getAction(hudson.tasks.test.AggregatedTestResultAction.class);
if (testResultAction == null) {
println("No tests")
return
}
childReports = testResultAction.getChildReports();
if (childReports == null || childReports.size() == 0) {
println("No child reports")
return
}
def failures = [:]
childReports.each { report ->
def result = report.result;
if (result == null) {
println("null result from child report")
}
else if (result.failCount < 1) {
println("result has no failures")
}
else {
println("overall fail count: ${result.failCount}")
failedTests = result.getFailedTests();
failedTests.each { test ->
failures.put(test.fullDisplayName, test)
println("Failed test: ${test.fullDisplayName}\n" +
"name: ${test.name}\n" +
"age: ${test.age}\n" +
"failCount: ${test.failCount}\n" +
"failedSince: ${test.failedSince}\n" +
"errorDetails: ${test.errorDetails}\n")
}
}
}
}

Resources