Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/jenkins/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jenkinsfile-脚本管道语法中的条件阶段执行_Jenkins_Groovy_Jenkins Pipeline - Fatal编程技术网

Jenkinsfile-脚本管道语法中的条件阶段执行

Jenkinsfile-脚本管道语法中的条件阶段执行,jenkins,groovy,jenkins-pipeline,Jenkins,Groovy,Jenkins Pipeline,我们正在为我们的Jenkinsfile使用脚本管道语法,它定义了许多构建和部署代码的阶段。我们有一个用例,如果我正在进行完整构建,我希望运行所有阶段,但如果我需要执行一些AWS路由,则只运行一个特定阶段。我知道我可以使用if()跳过一个阶段或运行一个阶段。问题是我不想将if条件应用到我的Jenkins文件中的每个阶段 在新的声明性管道语法中,使用stage..when选项可以轻松实现这一点。我们的基础设施中使用了大量定制Groovy helper函数,因此目前我不可能从脚本管道语法切换到新的声明

我们正在为我们的
Jenkinsfile
使用脚本管道语法,它定义了许多构建和部署代码的阶段。我们有一个用例,如果我正在进行完整构建,我希望运行所有阶段,但如果我需要执行一些AWS路由,则只运行一个特定阶段。我知道我可以使用
if()
跳过一个阶段或运行一个阶段。问题是我不想将
if
条件应用到我的
Jenkins文件中的每个阶段

在新的声明性管道语法中,使用
stage..when
选项可以轻松实现这一点。我们的基础设施中使用了大量定制Groovy helper函数,因此目前我不可能从脚本管道语法切换到新的声明性管道语法。我在现有的
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文档中找不到任何可以提供这种方法的东西


有没有人能找到更好的方法来合并它?

我不使用脚本化管道,但我很确定这就是您的方法(将条件阶段包含在
if
中)

如果您希望它的行为更像声明性的,您可以将
If
语句放在每个阶段中。这样,阶段仍然可以可视化。当他们实际上没有做任何事情时,这可能是可取的,也可能不是可取的


我认为切换到声明性将是在blue ocean UI中以不同方式显示跳过的阶段的唯一方法(由于
when
子句,它们在被跳过时看起来不同),但您当前的解决方案实际上拥有最小的代码。这对我来说似乎并不令人讨厌,但这类事情可能是主观的

我也不喜欢在我的stage{}中有一个冗余的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)
    })
}

根据上的评论,当
支持脚本化管道时,听起来不像是添加了
。作为一种潜在的解决方法,有一个共享库实现了脚本化管道的
when
语句:

我将使用环境变量跳过阶段

stage("Release"){
    steps{
        // Release procedure
    }
    when {
        allOf{
            branch 'release'
            not{
                environment name: 'JENKINS_SKIP_RELEASE', value: 'TRUE'
            }
        }
    }
}
在我的特定工作方式中,整个管道是一个变量,因此我调整它以检查特定变量

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
}

我认为在脚本化管道中没有跳过阶段的好方法-请参阅。谢谢@mkobit。知道这一点很有帮助。谢谢@burnettk。你是对的。这是非常主观的。我会把这个问题留一点时间,以防有人过来,给我一个很好的和优雅的方式来做这件事。如果不是,我会接受你的回答。这个答案是不正确的,有一种方法可以在脚本管道中实现。一旦你找到了好的来源,这是很容易的:谢谢!真是个好主意!不是为我工作的。。。我在阶段(“Verify${stageToDisplay}”,overallBuildRun)上获得了“java.lang.IllegalArgumentException:预期命名参数,但获得了[Verify Pre-prod,true]”的并行代码execution@DeanChen你有没有用同样的方法来编写一个平行的(阶段)脚本?我找不到it@Marcello取消销售我没有为此使用并行。嗨,我使用脚本化阶段来拥有动态并行阶段。因为脚本化的时候是不可能的,但我想看到所有可能的阶段,想看到执行与否。提到的Utils.markStageSkippedForConditional(STAGE_NAME)仅在概述中工作正常,跳过的阶段现在为空,但在蓝色海洋视图中,跳过的阶段也有一个复选标记。有人也有这个吗?