Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declarative Pipeline - Use of when condition, how to do nested conditions anyOf/allOf/not

I am stuck at how to properly use nested conditions as proposed in the Jenkins syntax.

https://jenkins.io/doc/book/pipeline/syntax/#when

This is my current stage:

stage('Build'){
when{
    anyOf{
        allOf{
            expression{env.BRANCH_NAME != 'master'}
            expression{env.AUTO_BUILD == true && env.BUILD_OPT == snapshot && env.BRANCH_NAME !=~ /feature.+/} 
        }
        expression{env.AUTO_BUILD == false}
    }
}
steps{
    echo env.AUTO_BUILD
    echo env.BUILD_OPT
    echo env.BRANCH_NAME
}

From my point of understanding is, if I set env.AUTO_BUILD = false, then this stage should be executed, since it is enclosed in an anyOf OR it would execute if my branch was e.g. develop and AUTO_BUILD = true, BUILD_OPT = snapshot.
However, this was not the case when I set AUTO_BUILD = false. The stage was not executed. Am I missing something?

like image 464
Tai Ly Avatar asked Dec 13 '18 14:12

Tai Ly


People also ask

How do you condition in Jenkins pipeline?

Jenkins “when” Directive: Execution of the pipeline stages can be controlled with conditions. These conditions must be defined in the when block within each stage. Jenkins supports a set of significant conditions that can be defined to limit stage execution. Each when block must contain at least one condition.

What block can be used to control if a stage runs in a declarative pipeline?

The top-level of the Pipeline must be a block, specifically: pipeline { } No semicolons as statement separators. Each statement has to be on its own line. Blocks must only consist of declarative sections, declarative directives, declarative steps, or assignment statements.

Can I mix declarative and scripted pipeline?

Yes you can only if you want to have external function inside step block.


1 Answers

There are two issues here in the declarative conditionals. First, looking at:

allOf {
  expression{env.BRANCH_NAME != 'master'}
  expression{env.AUTO_BUILD == true && env.BUILD_OPT == snapshot && env.BRANCH_NAME !=~ /feature.+/} 
}

the issue here is that !=~ is not a valid operator for "does not match regular expression" in Groovy. You can replace it with !(env.BRANCH_NAME =~ /feature/) like so:

allOf {
  expression{env.BRANCH_NAME != 'master'}
  expression{env.AUTO_BUILD == true && env.BUILD_OPT == snapshot && !(env.BRANCH_NAME =~ /feature/)} 
}

to achieve the behavior you desire.

Secondly, in the conditional:

expression{env.AUTO_BUILD == false}

the expression is checking for a boolean type in env.AUTO_BUILD. If the value is being assigned a string 'false', then the type check will fail and the conditional will not behave as expected. Inputting the environment env.AUTO_BUILD assignment as a boolean env.AUTO_BUILD = false and not a string env.AUTO_BUILD = 'false' will rectify this for you.

like image 59
Matt Schuchard Avatar answered Sep 23 '22 14:09

Matt Schuchard