11

我正在尝试做这样的事情:

def makeStage = {
  stage('a') {
    steps {
      echo 'Hello World'
    }
  }
} 
pipeline {
  agent none
  stages {
    makeStage()
  }
}

但它给了我这个例外:

WorkflowScript: 11: Expected a stage @ line 11, column 5.
   makeStage()
   ^

是否可以将阶段定义为外部闭包,如果可以,如何定义?

4

2 回答 2

12

超级晚了,但万一有人遇到这个问题,一个可能的解决方案是将您生成的阶段包装在脚本声明中并.call在生成的阶段调用。

所以对你来说:

def makeStage = {
  return {
    stage('a') {
      echo 'Hello World'
    }
  }
}

pipeline {
  agent none
  stages {
    stage ('hello world') {
      steps {
        script {
          makeStage().call()
        }      
      }
    }
  }
}

哎呀。编辑后,我在 makeStage 声明中的舞台('a')中有“步骤”。“步骤”是一个声明性管道指令,因此它在脚本块内引发错误。

于 2019-04-11T15:56:53.270 回答
5

您不能在声明性管道之外定义阶段。声明式管道的主要目的是提供简化和固执己见的语法,以便您可以专注于应该做什么(通过使用一些可用的步骤)而不是如何去做。

如果您对更灵活的流水线实现方式感兴趣,您可以选择脚本化流水线方法,它在语法方面并不那么严格——它仅受 Groovy 和 CPS 执行模块的限制。

您示例中的工作(脚本)管道如下所示:

#!groovy

def makeStage = {
  stage('a') {
    echo 'Hello World'
  }
} 

node {
    makeStage()
}

注意:脚本管道中没有steps方法。stage如果你把它留在那里,你会得到

java.lang.NoSuchMethodError: No such DSL method 'steps' found among 
    steps [archive, bat, build, catchError, checkout, deleteDir, dir, 
    dockerFingerprintFrom, ...

声明性管道中的脚本

声明式管道定义了一个script步骤,允许您放置一个脚本管道块。但是,它仍然不允许您动态定义阶段或/和将阶段定义提取到函数或闭包中。scriptstep 在阶段内执行,因此您无法控制此块内是否执行阶段。但是,在某些情况下,如果您想做一些比调用声明性管道的预定义步骤更复杂的事情,则此步骤可能非常有用。

于 2018-06-01T05:40:12.793 回答