The jenkins job is not continue after checking the if statement - jenkins

stage('Checkout')
{
steps
{
checkout scm
script
{
if (params.myParam == '') { // and/or whatever condition you want
currentBuild.result = 'ABORTED'
error('myParam not set')
}
}
}
}
Above will Abort the build if parameter is null, working as expected.But when i give the value on parameter the job is still failing, not taking the value or passing the build.

The == '' (equality operator) also needs to be declared that it represents 'null' to satisfy the boolean value.
As this is not declared, any value in that parameter will meet the condition to error/false, see the slight change to your stage below:
stage('Checkout') {
steps {
checkout scm
script {
if(params.myParam == '' || params.myParam == null) {
currentBuild.result = 'ABORTED'
error('myParam not set')
} else {
//whatever condition you want
}
}
}
}

Related

Jenkins - Fail a job if condition is not met

In the Jenkins job which tests some values, I have something like this:
stage('Check value'){
if value == 5:
//return failure of a job
}
stage('Send results'){
....
}
In one stage those values are being checked, if value == 5 a job should return failure. I've tried with exit 1 and with return -1 but it doesn't work.
If you gracefully return from a stage the next stage will always run. So one way to get around this is to conditionally run all other Stages. Another solution is to simply generate an error. Refer to the following pipeline.
pipeline {
agent any
stages {
stage('Build_1') {
steps {
echo "Running!!!"
script {
def value = 5
if(value == 5) {
currentBuild.result = 'ABORTED'
error("Abort the build.")
// throw new Exception("ERRRRORRRRRR") -> Or you can throw an error.
}
}
}
}
stage('Build_2') {
steps {
echo "Running!!! 22222"
}
}
}
}

how to schedule parameterized pipelines to run just once with one parameter and the rest with another one?

I have a pipeline which I just added 2 parameters to build release or debug (parameters are called release or debug). The pipeline uses cron syntax to check for changes in the SCM every 10 mins, the pipeline checks for every commit and then build release (C++ program) but I would like to build debug once a day, let's say everyday every coomit pushed from 12 to 13 will be build in debug. All of this without me having to run the pipeline and changing the parameter manually (it is set to release by default). Is there any way to do this? This is a very short version of what the pipeline looks like:
pipeline {
stages {
stage('Setup parameters') {
steps {
script {
properties([
parameters([
choice(
defaultValue: 'RELEASE',
choices: ['RELEASE', 'DEBUG'],
name: 'BUILD_CONFIG'
),
])
])
}
}
}
stage('Build release'){
when {
expression {
return params.BUILD_CONFIG == 'RELEASE'
}
}
steps{
script {
def msbuild = tool name: 'MSBuild', type: 'hudson.plugins.msbuild.MsBuildInstallation'
bat "\"${msbuild}\" /Source/project-GRDK.sln /t:Rebuild /p:configuration=\"Release Steam D3D11\""
}
}
}
stage('Build debug'){
when {
expression {
return params.BUILD_CONFIG == 'DEBUG'
}
}
steps{
script {
def msbuild = tool name: 'MSBuild', type: 'hudson.plugins.msbuild.MsBuildInstallation'
bat "\"${msbuild}\" /Source/project-GRDK.sln /t:Rebuild /p:configuration=\"Debug Steam D3D11\""
}
}
}
}
}
parameterizedCron plugin does what you need:
pipeline {
agent any
parameters {
choice(name: 'BUILD_CONFIG', choices: ['RELEASE', 'DEBUG'], defaultValue: 'RELEASE')
}
triggers {
parameterizedCron('''
1,2,3,4,5,6,7,8,9,10 * * * * % BUILD_CONFIG=RELEASE
12 * * * * % BUILD_CONFIG=DEBUG
''')
}
Another option would be to create a second job, which triggers the build job with the right parameters:
pipeline {
agent any
triggers {
cron('H 12 * * *')
}
stages {
stage('Build xxx debug') {
steps {
build job: "your-job-name-here", parameters: [
choice(name: 'BUILD_CONFIG', value: 'DEBUG')
]
}
}
}
}
It is possible to determine the cause of the build with currentBuild.rawBuild.getCause(Class<T> type). The type you are looking for is UserIdCause. Following would build a stage in case the job was not triggered by an user (manually). In this stage steps are from Build debug stage.
stage('Build debug if time triggered') {
when {
expression {
return currentBuild.rawBuild.getCause(hudson.model.Cause$UserIdCause) == null
}
}
steps {
script {
def msbuild = tool name: 'MSBuild', type: 'hudson.plugins.msbuild.MsBuildInstallation'
bat "\"${msbuild}\" /Source/project-GRDK.sln /t:Rebuild /p:configuration=\"Debug Steam D3D11\""
}
}
You will also need to add an expression to Build release and Build debug stages, in order to prevent building if the job is not triggered by an user (manually).
stage('Build release'){
when {
allOf {
expression {
return params.BUILD_CONFIG == 'RELEASE'
}
expression {
return currentBuild.rawBuild.getCause(hudson.model.Cause$UserIdCause) != null
}
}
}
...
Docu:
https://javadoc.jenkins-ci.org/hudson/model/Cause.html
https://javadoc.jenkins-ci.org/hudson/model/Run.html
How to differentiate build triggers in Jenkins Pipeline
EDIT
If you want to keep everything in one pipeline, then you need to create two new variables. Following code creates Calendar object for 12 am today and converts it to milliseconds.
Calendar date = new GregorianCalendar()
date.set(Calendar.HOUR_OF_DAY, 12);
date.set(Calendar.MINUTE, 0);
date.set(Calendar.SECOND, 0);
date.set(Calendar.MILLISECOND, 0);
def start = date.getTime().getTime()
In same way you could create a Calendar object for 1 pm today (e.g. end). With currentBuild.rawBuild.getTimestamp() you get Calendar object, when the build was scheduled. If the scheduled time is between start and end set for example a boolean variable and check it in the pipeline when block.
def buildDebug = false
def scheduled = currentBuild.rawBuild.getTimestamp().getTime().getTime()
if(scheduled > start && scheduled < end)
buildDebug = true
...
stage('Build release'){
when {
allOf {
expression {
return params.BUILD_CONFIG == 'RELEASE'
}
expression {
return currentBuild.rawBuild.getCause(hudson.model.Cause$UserIdCause) == null
}
expression {
return buildDebug == false
}
}
}
...
stage('Build debug'){
when {
allOf {
expression {
return params.BUILD_CONFIG == 'RELEASE'
}
expression {
return currentBuild.rawBuild.getCause(hudson.model.Cause$UserIdCause) == null
}
expression {
return buildDebug == true
}
}
}
How to create a Java Date object of midnight today and midnight tomorrow?

Jenkins Pipeline stage skip based on groovy variable defined in pipeline

I'm trying to skip a stage based a groovy variable and that variable value will be calculated in another stage.
In the below example, Validate stage is conditionally skipped based Environment variable VALIDATION_REQUIRED which I will pass while building/triggering the Job. --- This is working as expected.
Whereas the Build stage always runs even though isValidationSuccess variable is set as false.
I tried changing the when condition expression like { return "${isValidationSuccess}" == true ; } or { return "${isValidationSuccess}" == 'true' ; } but none worked.
When printing the variable it shows as 'false'
def isValidationSuccess = true
pipeline {
agent any
stages(checkout) {
// GIT checkout here
}
stage("Validate") {
when {
environment name: 'VALIDATION_REQUIRED', value: 'true'
}
steps {
if(some_condition){
isValidationSuccess = false;
}
}
}
stage("Build") {
when {
expression { return "${isValidationSuccess}"; }
}
steps {
sh "echo isValidationSuccess:${isValidationSuccess}"
}
}
}
At what phase does the when condition will be evaluated.
Is it possible to skip the stage based on the variable using when?
Based on a few SO answers, I can think of adding conditional block as below, But when options look clean approach. Also, the stage view shows nicely when that particular stage is skipped.
script {
if(isValidationSuccess){
// Do the build
}else {
try {
currentBuild.result = 'ABORTED'
} catch(Exception err) {
currentBuild.result = 'FAILURE'
}
error('Build not happened')
}
}
References:
https://jenkins.io/blog/2017/01/19/converting-conditional-to-pipeline/
stage("Build") {
when {
expression { isValidationSuccess == true }
}
steps {
// do stuff
}
}
when validates boolean values so this should be evaluate to true or false.
Source

Need Condition based Input Step in Jenkins pipeline script

I have three stages in jenkins pipeline script viz (1) precheck, (2) build-prod & (3) build-dr.
I have stated the input step for manual trigger at stage "build-dr"
My pipeline is condition based i.e based on user parameter in precheck stage .
Condition1: "precheck" -> "build-prod" and then "build-dr" is executed.
Condition2: "precheck" and then "build-dr" is executed (skips build-prod).
I need the input step in Condition1 and is working fine however the input step should not be executed for Condition2 i.e no popup msg with input step. Please let me know how can we put a condition around input step in stage 3 build-dr so it does not execute input step when the pipleline skips (2) build-prod.
Jenkins pipeline Script Code:
agent any
stages {
stage ("Pre-Check Parameters") {
steps {
echo "Pre-Check called in pipeline"
}
}
stage ("build-prod") {
when {
expression { params.region == 'prod_only' || params.region == 'prod_and_dr' }
}
steps {
build 'job4'
}
}
stage ("build-dr") {
input{
message "Proceed or Abort"
submitter "user1,admin"
parameters {
string(name:'username', defaultValue: 'user1', description: 'Username of the user pressing Ok')
}
}
when {
expression { params.region == 'dr_only' || params.region == 'prod_and_dr'}
}
steps {
build 'job5'
}
}
}
}
Kindly suggest.
You are currently using the input directive as described here but this prevents you to make this input conditional. You actually have to use the Input Step. Instead of adding the input field directly below the stage directive you move this into the steps block of your stage and add a script block around it to use if/else conditionals.
And take care to remove the curly brackets around you input step and to add a colon after each property.
What you have to do now is to adapt this line to your requirements:
if(Condition1 == true) Depenending on the value of your parameter.
stage("build-dr") {
when {
expression { params.region == 'dr_only' || params.region == 'prod_and_dr'}
}
steps {
script {
if(Condition1 == true) {
input message: "Proceed or Abort", submitter: "user1,admin",
parameters: [string(name:'username', defaultValue: 'user1', description: 'Username of the user pressing Ok')]
}
}
build 'job5'
}
}
Alternatively you can use an environment declaration block to declare a variable and assign a specific value to it if your second stage will be executed. But any environment value will always be typed as a String this is important for the if/else conditional. A good way to assign a value to the variable would be to add a post section to your second stage.
pipeline {
agent any
environment {
STAGE_2_EXECUTED = "0"
}
stages{
stage("....") {
steps {
....
}
}
stage("Second stage") {
when {
expression { /* Your condition */ }
}
steps {
....
}
post {
always {
script {
STAGE_2_EXECUTED = "1";
}
}
}
}
stage("Third Stage") {
steps {
script {
if(STAGE_2_EXECUTED == "1") {
input message: "Proceed or Abort", submitter: "user1,admin",
parameters: [string(name:'username', defaultValue: 'user1', description: 'Username of the user pressing Ok')]
}
}
build 'job5'
}
}
}
}

Conditional step based on currentBuild.result

I'd like a step to only be performed when the currentBuild.result is not set to UNSTABLE, this is immediately after a test step has been performed, I've managed to figure out that if this is not the case it gets set to null in my pipeline. Comparing a variable to "" should work when trying to determine that it is null, however this does not appear to work in my job step:
stage('Post test') {
when {
expression {
return (currentBuild.result == "")
}
}
steps {
Can someone please advise as to what I should be using in my conditional step expression.
Untested and not sure if this is exactly what you mean, but something like this?
stage('Post test') {
steps {
conditionalSteps {
condition {
status("Success","Success") # worst result, best result
}
steps {
shell("echo 'this is my command'")
}
}
}
}
If you want to run this at the end of a build you can just wrap it in a post. If you want to run a command while continuing the pipeline, I think you would have to wrap it in a script closure. This is untested, but I believe it will work for what you want:
stages {
stage('1') {}
stage('2') {}
stage('3') {
steps {
script {
if (currentBuild.result == "UNSTABLE") {
println "this should be unstable"
}
}
}
}
post {
unstable {
println "here be unstable"
}
}
}

Resources