Jenkinsfile - Script Pipeline语法中的条件阶段执行

时间:2017-08-19 23:30:54

标签: jenkins groovy jenkins-pipeline

我们正在为Jenkinsfile使用脚本管道语法,该语法已经定义了很多阶段来构建和部署我们的代码。我有一个用例,如果我正在执行 完整构建 ,我想运行所有阶段,但如果我需要执行某些AWS路由,则只运行一个特定阶段。我知道我可以使用if(<expression>)跳过舞台或跑舞台。问题是我不想将if条件应用到Jenkinsfile的每个阶段。

在新的声明性管道语法中,使用stage..when选项可以轻松实现。我们的基础架构中使用了很多自定义Groovy辅助函数,所以此时我无法从脚本管道语法切换到新的声明性管道语法。我最终在现有Jenkinsfile上做的事情是这样的......

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

已更改为

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

对我来说这感觉有点哈哈,我无法在Jenkins文档上找到任何提供这种方法的好方法。

有没有人有更好的方法可以加入这个?

4 个答案:

答案 0 :(得分:20)

我也不喜欢在阶段{} 中设置冗余 if {} 块的想法。 我通过覆盖舞台解决了这个问题,如下所示

def stage(name, execute, block) {
    return stage(name, execute ? block : {echo "skipped stage $name"})
}

现在您可以按如下方式禁用舞台

stage('Full Build', false) { 
    ...
}

<强>更新 您还可以使用以下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)
    })
}

答案 1 :(得分:2)

我没有使用脚本管道,但我非常确定您采用的方式(将条件阶段括在if中)。< / p>

如果您希望它更像声明,那么您可以在每个阶段中放置if语句。这样,阶段仍然可视化。当他们没有真正做任何事情时,这可能是也可能不合适。

我认为切换到声明将是在蓝海UI中以不同方式显示跳过的阶段的唯一方法(当它们由于when子句而被跳过时它们看起来不同),但实际上你有最小的代码与您当前的解决方案。它对我来说似乎并不神奇,但这种事情可能是主观的。 :)

答案 2 :(得分:2)

根据对JENKINS-47286的评论,听起来似乎不会向Scripted Pipeline添加when支持。作为一种潜在的解决方法,有一个共享库为脚本管道实现when语句:https://github.com/comquent/imperative-when

答案 3 :(得分:0)

我会使用环境变量跳过阶段。

stage("Release"){
    steps{
        // Release procedure
    }
    when {
        allOf{
            branch 'release'
            not{
                environment name: 'JENKINS_SKIP_RELEASE', value: 'TRUE'
            }
        }
    }
}

在我处理整个管道的特定方式中,是variable in a shared library,因此我对其进行了调整以检查特定的变量。

def call(body) {

    // Execute the body and get parameters back.
    def params = [:]
    body.resolveStrategy = Closure.DELEGATE_FIRST
    body.delegate = params
    body()

    if (params.skip_release){
        env.JENKINS_SKIP_RELEASE = 'TRUE'
    }

[...]

然后我所有的Jenkinsfile看起来像一堆参数。

@Library('shared') _

myGeneralizedPipeline {
    skip_release = true
    //Other parameters comes in this body
}