如何在Jenkins Job DSL中创建可扩展的基础作业?

时间:2019-07-03 14:27:34

标签: jenkins inheritance groovy jenkins-groovy jenkins-job-dsl

我正在尝试创建基本作业,以减少工作之间的重复。我做了以下操作,但是不起作用:

def baseJob(Map m, Closure c = {}) {
    type = m.type ?: 'dev'
    pipelineJob("prefix-${m.name}") {
        parameters {
            stringParam('ONE', 'one', 'Description one')
        }
        c()
    }
}

baseJob(type: 'release', name: 'test') {
    parameters { // <-- Fails here
        stringParam('TWO', 'two', 'Description two')
    }
}

我收到以下错误:

  

错误:(脚本,第12行)没有方法签名:script.parameters()适用于参数类型:(script $ _run_closure1 $ _closure4)值:[script $ _run_closure1 $ _closure4 @ 18b249b3]

以下按预期工作:

def baseJob(Map m, Closure c = {}) {
    type = m.type ?: 'dev'
    pipelineJob("prefix-${m.name}") {
        parameters {
            stringParam('ONE', 'one', 'Description one')
        }
        parameters { // <-- This is fine
            stringParam('TWO', 'two', 'Description two')
        }
        c()
    }
}

baseJob(type: 'release', name: 'test')

所以问题不在于我多次打parameters。问题似乎是我从闭包内部调用了parameters

我想相信有一种执行闭包的方法,因此可以正确地调用parameters。但是,我怀疑我必须先学习更多有关Groovy和Jenkins Job DSL的知识,然后才能弄清楚。所以我希望有人知道如何做。

如果您有替代解决方案来完成可扩展的基础工作,那也是一个有效的答案。

2 个答案:

答案 0 :(得分:1)

  

答案:方法parameters未在脚本内实现。 它实际上是在管道Closure委托类中实现的

此代码可以帮助您了解那里发生的事情。...

class Test {
    void printMe()
    {
        println "I am in test"
    }    
}

void test(Closure cl)
{
    Test t = new Test()
    cl.delegate = t
    cl()
}

def callMe = { printMe()}
test { 
    printMe() // This will run
    callMe() // This will fail
}

您的情况: pipeline (String arg, Closure pipeLineClosure)

pipeLineClousure 已在类X 中实现,可以在其中找到parameters方法。像下面的代码所示,

class X
{
  ...
  parameters (Closure cl)
}

因此可能的实现方式可能是:

class Custom{
    String val1
    String val2
    String val3
}

def baseJob(Map m, List<Custom> l) {
    type = m.type ?: 'dev'
    pipelineJob("prefix-${m.name}") {
        l.each{v->
            parameters {
                stringParam(v.val1, v.val2, v.val3)
            }
        }
    }
}

List l = []
l.add new Custom(val1: 'ONE', val2: 'one', val3: 'description')
// can be add more values
baseJob(type: 'release', name: 'test', l)

希望有帮助

答案 1 :(得分:1)

您只需要将要调用的闭包的代理设置为您所在的闭包的代理即可:

List<String> data = new LinkedList<>();

def baseJob(Map m, Closure c = {}) { type = m.type ?: 'dev' pipelineJob("prefix-${m.name}") { parameters { stringParam('ONE', 'one', 'Description one') } c.delegate = delegate // <-- Just add this line c() } } baseJob(type: 'release', name: 'test') { parameters { stringParam('TWO', 'two', 'Description two') } } 包含当前正在执行的闭包的委托。