Jenkinsfile - Conditional stage execution in the Script Pipeline syntax

浪子不回头ぞ 提交于 2019-11-29 04:01:07

问题


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?


回答1:


I don't use scripted pipelines, but I'm pretty sure that's the way you'd do it (enclosing the conditional stages in an if).

If you want it to act a bit more like declarative, you could put if statements inside each stage instead. That way the stages would still be visualized. This may or may not be desirable when they didn't actually do anything.

I think switching to declarative will be the only way to get the skipped stages displayed differently in the blue ocean UI (they look different when they are skipped due to a when clause), but you actually have the smallest code with your current solution. It doesn't seem hacky to me, but that sort of thing can be subjective. :)




回答2:


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)
    })
}



回答3:


Per the comments on JENKINS-47286, it doesn't sound like adding when support to Scripted Pipeline will happen. As a potential workaround, there is a shared library implementing the when statement for scripted pipelines: https://github.com/comquent/imperative-when



来源:https://stackoverflow.com/questions/45777169/jenkinsfile-conditional-stage-execution-in-the-script-pipeline-syntax

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!