We are using the Script Pipeline syntax for our Jenkinsfile
which has a lot of stage defined to build and deploy our code. We have a use case where I want to run all my stages if I am doing a Full Build but only run one specific stage if I need to perform some AWS routing. I know I can use the if(<expression>)
to skip a stage or run a stage. Problem is I don't want to apply that if
condition to every stage in my Jenkinsfile
.
In the new Declarative Pipeline syntax this is easily possible using the stage..when
option. We have a lot of custom Groovy helper function used in our infrastructure so it is not possible at this point for me to switch from the Script Pipeline syntax to the new Declarative Pipeline syntax. What I ended up doing on my existing Jenkinsfile
is something like this..
Original Jenkinsfile
stage('Checkout Code') {}
stage('Build') {}
parallel(
stage('Sonar Analysis') {}
stage('CLM Analysis') {}
stage('Security Analysis') {}
)
stage('Build Docker Image') {}
...
...
stage('QA Deploy') {}
stage('QA Routing') {}
...
...
stage('Prod Deploy') {}
stage('Prod Routing') {}
Changed to
if (fullDeploy){
stage('Full Build') {
stage('Checkout Code') {}
stage('Build') {}
parallel(
stage('Sonar Analysis') {}
stage('CLM Analysis') {}
stage('Security Analysis') {}
)
stage('Build Docker Image') {}
...
...
stage('QA Deploy') {}
stage('QA Routing') {}
...
...
stage('Prod Deploy') {}
stage('Prod Routing') {}
}
}
if (routeOnly){
stage('Prod Routing') {}
}
This feels a little hacky to me and I couldn't find any things on the Jenkins docs that provides a good way to do this.
Has anyone got a better way in which I can incorporate this?
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.
Creating Your Jenkins Pipeline Script. Pipelines have specific sentences or elements to define script sections, which follow the Groovy syntax.
In the pipeline job 'Test A' - Stage 'Checkout_A' it calls other pipeline job 'Test B' - Stage 'Checkout_B' , after that stage in Test B is completed the controller should retun back to pipeline job 'Test A' and execute Stage ('Build_A') which again calls pipeline job 'Test B' - Stage ('Build_B') then controller should ...
I also disliked the idea of having a redundant if{} block inside my stage{}. I solved this by overwriting the stage as follows
def stage(name, execute, block) {
return stage(name, execute ? block : {echo "skipped stage $name"})
}
now you can disable a stage as follows
stage('Full Build', false) {
...
}
Update You could also mark stage skipped using below def
import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
def stage(name, execute, block) {
return stage(name, execute ? block : {
echo "skipped stage $name"
Utils.markStageSkippedForConditional(STAGE_NAME)
})
}
(Built on top of culmat's answer https://stackoverflow.com/a/46784839/9993205)
Below provides 2 choices:
vars/stageConditional.groovy
:
import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
def skipped(name, execute, block){
log.HEADER "STAGE: $name"
return stage(name, execute ? block : {
echo "Skipped (shown in UI) stage $name"
Utils.markStageSkippedForConditional(STAGE_NAME)
})
}
def hidden(name, execute, block) {
log.HEADER "STAGE: $name"
if (execute){
return stage(name, block)
} else {
echo "Hidden (not shown in UI) stage $name"
}
}
Usage: it is a drop-in replacements for a stage
, with condition added.
Example: unless dockerize
is true
, both stages are hidden (note: stage is inside stage). Otherwise build, but publish conditionally (e.g. not in bugfix/feature branch), marking stage as skipped.
stageConditional.hidden('Java: build Docker image', plan.docker.dockerize) {
gradlew('buildImage')
stageConditional.skipped('Java: push Docker image', plan.publish.publish) {
gradlew('pushImage')
}
}
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