Hide steps, Jenkins, Groovy - 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."
}
}
}
}

Related

Groovy pipeline if-else condition

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.

Jenkinfile When Condition for env.JOB_NAME

I have a Jenkinsfile I would like to trigger certain steps based on env.JOB_NAME. As a test I have done this;
#!/usr/bin/env groovy
pipeline {
agent any
stages {
stage('Get ID') {
when {
"${env.JOB_NAME}" == 'Notification Sender (dev)'
}
steps {
echo "${env.JOB_NAME}"
}
}
}
}
However I get the error;
WorkflowScript: 6: Expected a when condition # line 6, column 11.
when {
^
WorkflowScript: 6: Empty when closure, remove the property or add some content. # line 6, column 11.
when {
^
Can I make the stage run based on the env.JOB_NAME using the when condition?
Yes, you can.
Try the following
when {
expression {
env.JOB_NAME == 'Notification Sender (dev)'
}
}
There is full documentation on the Pipeline syntax page, but the relevant part is
expression
Execute the stage when the specified Groovy expression evaluates to true, for example: when { expression { return params.DEBUG_BUILD } }

How do I implement a retry option for failed stages in Jenkins pipelines?

I have a Jenkinsfile with multiple stages and one of them is in fact another job (the deploy one) which can fail in some cases.
I know that I can made prompts using Jenkinsfile but I don't really know how to implement a retry mechanism for this job.
I want to be able to click on the failed stage and choose to retry it.
You should be able to combine retry + input to do that
Something like that
stage('deploy-test') {
try {
build 'yourJob'
} catch(error) {
echo "First build failed, let's retry if accepted"
retry(2) {
input "Retry the job ?"
build 'yourJob'
}
}
}
you could also use timeout for the input if you want it to finish if nobody validates.
There is also waitUntil that might be useful but i haven't used it yet
Edit :
WaitUntil seems definitely the best, you should play with it a bit but something like that is cleaner :
stage('deploy-test') {
waitUntil {
try {
build 'yourJob'
} catch(error) {
input "Retry the job ?"
false
}
}
}
By the way, there is doc all of the steps here https://jenkins.io/doc/pipeline/steps
This one with a nice incremental wait
stage('deploy-test') {
def retryAttempt = 0
retry(2) {
if (retryAttempt > 0) {
sleep(1000 * 2 + 2000 * retryAttempt)
}
retryAttempt = retryAttempt + 1
input "Retry the job ?"
build 'yourJob'
}
}
This gist (not mine) was one of the better options that I found while trying to implement this functionality too. https://gist.github.com/beercan1989/b66b7643b48434f5bdf7e1c87094acb9
Changed it to a method in a shared library that just did retry or abort for my needs. Also added a max retries and made the timeout variable so that we could change it depending on the job or stage that needs it.
package com.foo.bar.jenkins
def class PipelineHelper {
def steps
PipelineHelper(steps) {
this.steps = steps
}
void retryOrAbort(final Closure<?> action, int maxAttempts, int timeoutSeconds, final int count = 0) {
steps.echo "Trying action, attempt count is: ${count}"
try {
action.call();
} catch (final exception) {
steps.echo "${exception.toString()}"
steps.timeout(time: timeoutSeconds, unit: 'SECONDS') {
def userChoice = false
try {
userChoice = steps.input(message: 'Retry?', ok: 'Ok', parameters: [
[$class: 'BooleanParameterDefinition', defaultValue: true, description: '', name: 'Check to retry from failed stage']])
} catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException e) {
userChoice = false
}
if (userChoice) {
if (count <= maxAttempts) {
steps.echo "Retrying from failed stage."
return retryOrAbort(action, maxAttempts, timeoutMinutes, count + 1)
} else {
steps.echo "Max attempts reached. Will not retry."
throw exception
}
} else {
steps.echo 'Aborting'
throw exception;
}
}
}
}
}
Example usage with a max of 2 retries that waits for 60s for input.
def pipelineHelper = new PipelineHelper(this)
stage ('Retry Example'){
pipelineHelper.retryOrAbort({
node{
echo 'Here is an example'
throw new RuntimeException('This example will fail.')
}
}, 2, 60)
}
Just remember to put nodes inside of the closure so that waiting for an input doesn't block an executor.
If you have the paid jenkins enterprise Cloudbees has a Checkpoint plugin that can better handle this, but it is not planned to be release for open source Jenkins (JENKINS-33846).

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