想象一下Jenkins工作A需要1分钟才能运行,而工作B需要5分钟。
如果我们将作业A配置为触发作业B,则作业B正在运行作业A可能在B完成之前运行5次。但是,Jenkins不会在作业B的队列中添加5个构建,这很好,因为否则快速的工作A会为不良的慢作业B创建不断增长的构建积压。
但是,现在我们希望使用parameterized trigger plugin将作业A触发器B作为参数化作业。参数化作业执行排队积压,这意味着作业A很乐意为作业B创建大量构建,这可能无法跟上。
每次触发时,为队列添加新的参数化构建是有意义的,因为参数可能不同。 Jenkins不应该总是假设新的参数化构建不需要渲染先前排队的构建。
然而,在我们的案例中,我们实际上是这样想的。作业A构建并打包我们的应用程序,然后作业B将其部署到类似生产的环境中并运行更多的集成测试。我们还有一个构建C,它可以部署到另一个环境并进行更多测试,所以这对我们来说是一个不断升级的模式。
我们希望参数化作业B的队列只保留添加的最后一个构建;每个新构建都将替换当前队列中的任何作业。
有没有很好的方法来实现这个目标?
答案 0 :(得分:6)
向作业B添加“系统Groovy脚本”预构建步骤,以检查具有相同名称的(较新的)排队作业,并在找到时解除阻止:
def name = build.properties.environment.JOB_NAME
def queue = jenkins.model.Jenkins.getInstance().getQueue().getItems()
if (queue.any{ it.task.getName() == name }) {
println "Newer " + name + " job(s) in queue, aborting"
build.doStop()
} else {
println "No newer " + name + " job(s) in queue, proceeding"
}
答案 1 :(得分:2)
你可以摆脱参数化触发插件,而是使用传统的触发。正如你所说,这会阻止作业B队列堆积。
如何将参数从A传递到B呢?使作业A在其控制台输出中产生参数。在作业B中,要获取这些构建参数,请检查最新A构建的控制台输出(可能使用Python脚本吗?)。
答案 2 :(得分:1)
这是一个解决方法:
答案 3 :(得分:1)
如果你正在使用Git,现在支持Triggering / Parameters / Pass-through选项下的“Combine Queued git hashes”。 应该实际使用的第一个Git插件版本是1.1.27(参见Jenkins-15160)
答案 4 :(得分:0)
import hudson.model.*
def q = jenkins.model.Jenkins.getInstance().getQueue()
def items = q.getItems()
for (i=0;i<items.length;i++){
if(items[i].task.getName() == "JobB"){
items[i].doCancelQueue()
}
}
答案 5 :(得分:0)
如果你只关心一些参数匹配,这里有一个更灵活的选择。当从外部触发作业(即从GitHub或Stash)触发作业时,这尤其有用,而某些参数不需要单独的构建。
如果检查的参数在当前构建和排队构建中同时存在值和存在,则当前构建将被中止,并且描述将显示将来构建包含相同的已检查参数(以及它们是什么)
如果您不希望拥有显示已中止作业的构建历史记录,则可以将其修改为取消除最后一个以外的所有其他排队作业。
checkedParams = [
"PARAM1",
"PARAM2",
"PARAM3",
"PARAM4",
]
def buildParams = null
def name = build.project.name
def queuedItems = jenkins.model.Jenkins.getInstance().getQueue().getItems()
yieldToQueuedItem = false
for(hudson.model.Queue.Item item : queuedItems.findAll { it.task.getName() == name }) {
if(buildParams == null) {
buildParams = [:]
paramAction = build.getAction(hudson.model.ParametersAction.class)
if(paramAction) {
buildParams = paramAction.getParameters().collectEntries {
[(it.getName()) : it.getValue()]
}
}
}
itemParams = [:]
paramAction = item.getAction(hudson.model.ParametersAction.class)
if(paramAction) {
itemParams = paramAction.getParameters().collectEntries {
[(it.getName()) : it.getValue()]
}
}
equalParams = true
for(String compareParam : checkedParams) {
itemHasKey = itemParams.containsKey(compareParam)
buildHasKey = buildParams.containsKey(compareParam)
if(itemHasKey != buildHasKey || (itemHasKey && itemParams[compareParam] != buildParams[compareParam])) {
equalParams = false
break;
}
}
if(equalParams) {
yieldToQueuedItem = true
break
}
}
if (yieldToQueuedItem) {
out.println "Newer " + name + " job(s) in queue with matching checked parameters, aborting"
build.description = "Yielded to future build with:"
checkedParams.each {
build.description += "<br>" + it + " = " + build.buildVariables[it]
}
build.doStop()
return
} else {
out.println "No newer " + name + " job(s) in queue with matching checked parameters, proceeding"
}
答案 6 :(得分:0)
以下是基于Ron的解决方案,但有一些修复工作在我的Jenkins 2上,包括删除java.io.NotSerializableException异常并处理getName()
的格式与{{1}的格式有些不同}}
JOB_NAME