I want by pipeline to run on any branch that matches the pattern alerta/ (and anything beyond the slash (/).
So I have tried the following 2 approaches in terms of Jenkinsfile
expression {
env.BRANCH_NAME ==~ 'alerta\/.*'
}
expression {
env.BRANCH_NAME == '*/alerta/*'
}
both of them have the corresponding stages being skipped.
How should I format my when conditional to meet my purpose?
You forgot to return the state in the expression
expression
Execute the stage when the specified Groovy expression evaluates to
true, for example: when { expression { return params.DEBUG_BUILD } }
Note that when returning strings from your expressions they must be
converted to booleans or return null to evaluate to false. Simply
returning "0" or "false" will still evaluate to "true".
pipeline {
agent any
stages {
stage('alerta-branch'){
when{
expression {
return env.BRANCH_NAME ==~ /alerta\/.*/
}
}
steps {
echo 'run this stage - ony if the branch contains alerta in branch name'
}
}
}
}
This should work for you
Related
From my experience with Jenkins declarative-syntax pipelines, I'm aware that you can conditionally skip a stage with a when clause. E.g.:
run_one = true
run_two = false
run_three = true
pipeline {
agent any
stages {
stage('one') {
when {
expression { run_one }
}
steps {
echo 'one'
}
}
stage('two') {
when {
expression { run_two }
}
steps {
echo 'two'
}
}
stage('three') {
when {
expression { run_three }
}
steps {
echo 'three'
}
}
}
}
...in the above code block, there are three stages, one, two, and three, each of whose execution is conditional on a boolean variable.
I.e. the paradigm is that there is a fixed superset of known stages, of which individual stages may be conditionally skipped.
Does Jenkins pipeline script support a model where there is no fixed superset of known stages, and stages can be "looked up" for conditional execution?
To phrase it as pseudocode, is something along the lines of the following possible:
my_list = list populated _somehow_, maybe reading a file, maybe Jenkins build params, etc.
pipeline {
agent any
stages {
if (stage(my_list[0]) exists) {
run(stage(my_list[0]))
}
if (stage(my_list[1]) exists) {
run(stage(my_list[1]))
}
if (stage(my_list[2]) exists) {
run(stage(my_list[2]))
}
}
}
?
I think another way to think about what I'm asking is: is there a way to dynamically build a pipeline from some dynamic assembly of stages?
For dynamic stages you could write either a fully scripted pipeline or use a declarative pipeline with a scripted section (e. g. by using the script {…} step or calling your own function). For an overview see Declarative versus Scripted Pipeline syntax and Pipeline syntax overview.
Declarative pipeline is better supported by Blue Ocean so I personally would use that as a starting point. Disadvantage might be that you need to have a fixed root stage, but I usually name that "start" or "init" so it doesn't look too awkward.
In scripted sections you can call stage as a function, so it can be used completely dynamic.
pipeline {
agent any
stages {
stage('start') {
steps {
createDynamicStages()
}
}
}
}
void createDynamicStages() {
// Stage list could be read from a file or whatever
def stageList = ['foo', 'bar']
for( stageName in stageList ) {
stage( stageName ) {
echo "Hello from stage $stageName"
}
}
}
This shows in Blue Ocean like this:
I have a Jenkinsfile which will be triggered by GitLab (using Webhooks).
I want to skip the whole Jenkinsfile's execution if a particular condition is not met.
One way to do this is to apply the same condition on each stage
pipeline {
agent any
stages {
stage ('Stage 1') {
when {
expression {
//Expression
}
}
//do something
}
stage ('Stage 2') {
when {
expression {
//Expression
}
}
//do something
}
stage ('Stage 3') {
when {
expression {
//Expression
}
}
//do something
}
.
.
.
.
}
}
But this seems weird as I want the same condition to be applied for all the stages.
Can we apply similar condition over stages itself ? Like this?
pipeline {
agent any
stages {
when {
expression {
//Expression
}
}
stage ('Stage 1') {
//do something
}
stage ('Stage 2') {
//do something
}
stage ('Stage 3') {
//do something
}
.
.
.
.
}
}
"Can we apply 'when' condition in 'stages' of a Jenkinsfile?" No.
Per Pipeline Syntax, when is only allowed within a stage.
The when directive allows the Pipeline to determine whether the stage should be executed depending on the given condition. The when directive must contain at least one condition. If the when directive contains more than one condition, all the child conditions must return true for the stage to execute. This is the same as if the child conditions were nested in an allOf condition (see the examples below). If an anyOf condition is used, note that the condition skips remaining tests as soon as the first "true" condition is found.
More complex conditional structures can be built using the nesting conditions: not, allOf, or anyOf. Nesting conditions may be nested to any arbitrary depth.
Can you simply have a first stage with the expression and fail/abort the pipeline if met?
I have a declarative pipeline jenkinsfile, in which I have 4 stages.
I would like to make so that whenever a specific stage executes(this stage is conditional therefor it will not always execute), all stages after this one are skipped.
For example purposes let's say that this stage is the first stage.
Does anyone knows a way to do it in a declarative pipeline?
Thanks in advance,
Alon
Define a boolean variable e.g. skip = false in the pipeline. When you enter your conditional stage set the variable to true. Make other stages (2-4) dependent on skip variable.
stage("1 - Your conditional stage") {
when {
...
}
steps {
script {
skip = true
}
}
stage("2") {
when {
expression {
return skip == false
}
}
}
...
stage("4") {
when {
expression {
return skip == false
}
}
}
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
I am trying to create a Jenkinsfile to handle different steps in prod vs dev environments. I was attempting to use the anyOf pattern with an expression that checks the JOB_URL environmental variable to determine which build server/build instruction to follow.
Jenkinsfile ends up looking something like the below:
stage('In Prod') {
when {
allOf {
expression { params.P1 == 'x' }
expression { params.P2 == 'y' }
expression { env.JOB_URL.contains('prod_server.com') }
}
}
...
}
stage('In Dev') {
when {
allOf {
expression { params.P1 == 'x' }
expression { params.P2 == 'y' }
expression { env.JOB_URL.contains('dev_server.com') }
}
}
...
}
Expected Behavior:
In Dev -> run In Dev step
In Prod -> run In Prod step
Actual Behavior:
In Dev -> run In Prod AND In Dev step
In Prod -> run In Prod step
Yes, I have checked to make sure that JOB_URL on the dev does not contain prod_server.com.
I have also tried !env.JOB_URL.contains('dev_server.com') as an additional expression for the prod step with the same result.
I only know enough groovy to get through Jenkins, and am somewhat new to Jenkins pipeline syntax, so maybe I've misunderstood the behavior here, but from what I understand from the Jenkins expression documentation:
when returning strings from your expressions they must be
converted to booleans or return null to evaluate to false. Simply
returning "0" or "false" will still evaluate to "true".
And as a sanity check, I confirmed that the groovy documentation says contains should be returning a boolean.
You can use a regular expression comparator in the expression to check the one of these environment variables:
built-in: JENKINS_URL and BUILD_URL (source built-in var)
plugin-provided JOB_URL (exists but can't find source)
Note: environment variable are exposed through the reserved environment variable map env (using env variable), e.g. server_url = env.JENKINS_URL.
Try something like this:
pipeline {
agent none
parameters {
string(name: 'P1', defaultValue: 'x', description: '')
string(name: 'P2', defaultValue: 'y', description: '')
}
stages {
stage('Init') {
steps {
echo "params = ${params.toString()}"
echo "env.JENKINS_URL = ${env.JENKINS_URL}"
}
}
stage('In Prod') {
when {
allOf {
expression { params.P1 == 'x' }
expression { params.P2 == 'y' }
expression { env.JENKINS_URL ==~ /.*prod_server.com.*/ }
}
}
steps {
echo "Prod"
}
}
stage('In Dev') {
when {
allOf {
expression { params.P1 == 'x' }
expression { params.P2 == 'y' }
expression { env.JENKINS_URL ==~ /.*dev_server.com.*/ }
}
}
steps {
echo "DEV"
}
}
}
}