我可以使用Closure在Jenkins声明性管道中定义一个阶段吗?

时间:2018-06-01 00:36:07

标签: jenkins groovy closures jenkins-pipeline

我试图做这样的事情:

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

但它给了我这个例外:

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

是否可以将舞台定义为外部封闭,如果是 - 如何?

2 个答案:

答案 0 :(得分:4)

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

如果您对更灵活的实现管道的方式感兴趣,可以选择Scripted Pipeline方法,如果涉及到语法,则该方法并不严格 - 它仅受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, ...

声明性管道中的脚本

声明性管道defines a script step,允许您放置一个脚本化管道块。但是,它仍然不允许您动态定义阶段或/并将阶段定义提取到函数或闭包。 script步骤在舞台内执行,因此如果执行舞台,则无法在此块内进行控制。但是,在某些情况下,如果您想要执行比调用声明性管道的预定义步骤更复杂的操作,则此步骤可能非常有用。

答案 1 :(得分:1)

太晚了,但是如果有人遇到此问题,一种可能的解决方案是将生成的阶段包装在声明式脚本周围,并在生成的阶段调用.call

所以对你来说

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

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

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