我如何正确地重构这个脚本化的Jenkins管道,将公共代码存储在一个文件中?

我如何正确地重构这个脚本化的Jenkins管道,将公共代码存储在一个文件中?,jenkins,jenkins-pipeline,jenkins-groovy,Jenkins,Jenkins Pipeline,Jenkins Groovy,背景:我是一名硬件设计师,试图与Jenkins一起改进我们的验证方法 我在这里查阅了很多关于Jenkins文件和groovy以及include的问题,但似乎没有一个能解决我的问题。我想让我的团队的其他成员尽可能地轻松,让他们在一个简单的数据结构中指定他们希望在此目录中运行的所有作业,例如: def targets = [ "Build number 1" : "make build", "Some other run command" : "custom_script" ] 我的想法是

背景:我是一名硬件设计师,试图与Jenkins一起改进我们的验证方法

我在这里查阅了很多关于Jenkins文件和groovy以及include的问题,但似乎没有一个能解决我的问题。我想让我的团队的其他成员尽可能地轻松,让他们在一个简单的数据结构中指定他们希望在此目录中运行的所有作业,例如:

def targets = [
  "Build number 1" : "make build",
  "Some other run command" : "custom_script"
]
我的想法是创建一个模板文件供他们使用,看起来像这样:

def targets = [.....]
node {
   scm......

   load "common/Jenkinsfile"
}
然后是common/Jenkins文件,其中包含将这些目标转化为阶段的代码:

    try {
    targets.each {entry ->
        stage (entry.key) {
           sh "${complicated_command_prefix} $entry.value  ${complicated_command_suffix}"
        }
      }
    }
    catch (e) {
    emailext (
     // yadda yadda
            )
       throw e  
   }
如果我将该代码直接放在Jenkins文件中而不是load命令中,则可以实现这一点。但是很明显,load做的事情比C预处理器的#include更复杂,因为代码不能与load一起工作

首先,我得到一个与未定义的目标相关的错误(因为它可能超出了加载文件的范围)。有人建议在目标之前添加“env.”作为前缀,这解决了语法错误,但没有实际执行任何阶段

那么…我如何才能正确地将“目标”传递给加载的文件,以便正确地处理在那里生成的阶段?或者,有没有其他方法可以让这项工作做得更好


编辑:我已经尝试将我的“def目标”直接粘贴到加载的公共文件中,这些阶段得到了正确的处理。所以问题不在于加载的文件没有执行它应该执行的操作,而在于它没有从父文件接收“targets”的值。

找到了答案!我发现了这一点,这解释了如果我省略def,变量将在外部可见。的确如此。现在我定义了没有def的目标。成功

这是一种可能的重构方法,同时将
target
的隐式依赖项转换为显式依赖项,使代码更易于理解和维护

模板文件:

def targets=[…]
节点{
scm。。。。。。
processTargets=加载“公共/文件”
processTargets(目标)
}
common/Jenkinsfile:

void调用(映射目标){
试一试{
targets.each{entry->
舞台(入口,钥匙){
sh“${complexed_command_prefix}$entry.value${complexed_command_suffix}”
}
}
}
捕获(e){
电子邮件文本(
//雅达雅达
)
掷e
}
}
//非常重要:返回script类的实例,load()将返回该实例
还这个
通过定义标准的
call
函数,可以像调用函数一样调用
load
返回的对象:
processTargets(targets)
。 如果定义了不同名称的函数,可以这样调用它们:

def targets = [.....]
node {
   scm......

   load "common/Jenkinsfile"
}
common=load“common/Jenkinsfile”
common.myFunction1(foo)
common.myFunction2(bar)

删除
def
会创建一个丑陋的全局变量。我会在“common/jenkinsfile”中定义一个函数,并将
targets
作为一个显式参数传递,以明确依赖关系。哎哟,从来没有接受过答案。你的答案可能更好,但在这种情况下,我需要一个快速和肮脏的版本,我的工作。这看起来非常有用,但我得到了我的答案工作迅速,即使它是混乱和“坏”,它足够好,我的需要。