2016-09-12 2 views
2

У меня есть трубопровод Дженкинса, который запускает несколько заданий сборки в одном проекте. Каждое задание сборки имеет разные параметры, которые динамически генерируются во время работы. Также есть строковый параметр, на котором ведомое устройство должно работать. Этот список представляет собой многострочную строку, которая делится на \ n.Как динамически запускать задания сборки?

Это то, что я получил:

def projectName = "${PROJECT_NAME}" 
def slaveList = "${SLAVE_LIST}".split("\n") 

def gradleTasks = "${GRADLE_TASKS}" 

def slaveClosure = { slaveNum -> 
    build job: projectName, parameters: [ 
        [$class: 'LabelParameterValue', name: 'slaveAol', label: slaveList[slaveNum]], 
        [$class: 'StringParameterValue', name: 'gradleTasks', value: gradleTasks] 
       ] 
} 

def parallelSlaveMap = [:] 
for (int i = 0; i < slaveList.size(); i++) { 
    parallelSlaveMap.put("slave${i}", slaveClosure(i)) 
} 

parallel(parallelSlaveMap) 

Но это у меня следующее сообщение об ошибке:

java.lang.IllegalArgumentException: Expected a closure or failFast but found slave[email protected]5caff0a8 
    at org.jenkinsci.plugins.workflow.cps.steps.ParallelStep$DescriptorImpl.newInstance(ParallelStep.java:202) 
    at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:134) 
    at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:113) 
    at groovy.lang.GroovyObject$invokeMethod.call(Unknown Source) 
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) 
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) 
    at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:151) 
    at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:21) 
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:115) 
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:103) 
    at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:149) 
    at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:146) 
    at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:15) 
    at WorkflowScript.run(WorkflowScript:44) 

Для справки, строка 44 в сценарии есть линия «параллельно».

Что я делаю неправильно? Я не уверен, есть ли более простой способ динамического создания параллельных заданий сборки на основе списка параметров ведомых.

ответ

0

Звонок в slaveClosure(i) инициализирует объект и присваивает его карте, что неожиданно для jenkins. Если бы вы использовали этот шаблон, вам, вероятно, понадобилась бы внешняя функция вокруг замыкания, которая возвращает замыкание, не оценивая его. Вместо этого я использую следующий метод для создания параллельных заданий. Сохранение значения индекса на каждой итерации важно, так как закрытие оценивается во время выполнения.

def projectName = "${PROJECT_NAME}" 
def slaveList = "${SLAVE_LIST}".split("\n") 
def slaveMap = [:] 
def gradleTasks = "${GRADLE_TASKS}" 

for (int i = 0; i < slaveList.size(); i++) { 
    def index = i 
    slaveMap['slave' + index] = {build job: projectName, parameters: [ 
        [$class: 'LabelParameterValue', name: 'slaveAol', label: slaveList[index]], 
        [$class: 'StringParameterValue', name: 'gradleTasks', value: gradleTasks] 
       ] 
    } 
} 

parallel slaveMap