As far as declarative pipelines go in Jenkins, I'm having trouble with the when keyword.
I keep getting the error No such DSL method 'when' found among steps
. I'm sort of new to Jenkins 2 declarative pipelines and don't think I am mixing up scripted pipelines with declarative ones.
The goal of this pipeline is to run mvn deploy
after a successful Sonar run and send out mail notifications of a failure or success. I only want the artifacts to be deployed when on master or a release branch.
The part I'm having difficulties with is in the post section. The Notifications stage is working great. Note that I got this to work without the when clause, but really need it or an equivalent.
pipeline { agent any tools { maven 'M3' jdk 'JDK8' } stages { stage('Notifications') { steps { sh 'mkdir tmpPom' sh 'mv pom.xml tmpPom/pom.xml' checkout([$class: 'GitSCM', branches: [[name: 'origin/master']], doGenerateSubmoduleConfigurations: false, submoduleCfg: [], userRemoteConfigs: [[url: 'https://repository.git']]]) sh 'mvn clean test' sh 'rm pom.xml' sh 'mv tmpPom/pom.xml ../pom.xml' } } } post { success { script { currentBuild.result = 'SUCCESS' } when { branch 'master|release/*' } steps { sh 'mvn deploy' } sendNotification(recipients, null, 'https://link.to.sonar', currentBuild.result, ) } failure { script { currentBuild.result = 'FAILURE' } sendNotification(recipients, null, 'https://link.to.sonar', currentBuild.result ) } } }
Declarative pipelines break down stages into individual stages that can contain multiple steps. Scripted pipelines use Groovy code and references to the Jenkins pipeline DSL within the stage elements without the need for steps.
Basically, declarative and scripted pipelines differ in terms of the programmatic approach. One uses a declarative programming model and the second uses an imperative programming mode. Declarative pipelines break down stages into multiple steps, while in scripted pipelines there is no need for this.
The basic statements and expressions which are valid in Declarative Pipeline follow the same rules as Groovy's syntax with the following exceptions: 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.
In the documentation of declarative pipelines, It is mentionned that you can't use when
in the post
block. when
is allowed only inside a stage directive. So what you can do is test the conditions using an if
in a script
:
post { success { script { if (env.BRANCH_NAME == 'master') currentBuild.result = 'SUCCESS' } } // failure block }
Using a GitHub Repository and the Pipeline plugin I have something along these lines:
pipeline { agent any stages { stage('Build') { steps { sh ''' make ''' } } } post { always { sh ''' make clean ''' } success { script { if (env.BRANCH_NAME == 'master') { emailext ( to: '[email protected]', subject: "${env.JOB_NAME} #${env.BUILD_NUMBER} master is fine", body: "The master build is happy.\n\nConsole: ${env.BUILD_URL}.\n\n", attachLog: true, ) } else if (env.BRANCH_NAME.startsWith('PR')) { // also send email to tell people their PR status } else { // this is some other branch } } } } }
And that way, notifications can be sent based on the type of branch being built. See the pipeline model definition and also the global variable reference available on your server at http://your-jenkins-ip:8080/pipeline-syntax/globals#env for details.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With