我有jenkins groovy pipeline触发其他构建。它在以下脚本中完成:
for (int i = 0; i < projectsPath.size(); i++) {
stepsForParallel[jenkinsPath] = {
stage("build-${jenkinsPath}") {
def absoluteJenkinsPath = "/${jenkinsPath}/BUILD"
build job: absoluteJenkinsPath, parameters: [[$class: 'StringParameterValue', name: 'GIT_BRANCH', value: branch],
[$class: 'StringParameterValue', name: 'ROOT_EXECUTOR', value: rootExecutor]]
}
}
}
parallel stepsForParallel
问题是,我的工作依赖于其他共同的工作,即。作业X触发作业Y,作业Z触发作业Y。我想实现的是,作业X触发作业Y,作业Z等待X触发的Y的结果。
我想我需要检查所有正在运行的构建,并检查是否有相同类型的构建正在运行。如果是,那就等着吧。下面的代码可以等待编译完成:
def busyExecutors = Jenkins.instance.computers
.collect {
c -> c.executors.findAll { it.isBusy() }
}
.flatten()
busyExecutors.each { e ->
e.getCurrentWorkUnit().context.future.get()
}
我的问题是我需要告诉我需要等待哪个正在运行的作业。为此,我需要检查:
- 构建参数
- 构建环境变量
- 作业名称
我如何才能检索到这种数据?
我知道Jenkins有沉默期功能,但在期限届满后,新的工作将被触发。
编辑1
只是为了说明为什么我需要这个功能。我的工作是构建应用程序和库。应用程序依赖于库,库依赖于其他库。当构建被触发时,它会触发下游作业(它所依赖的库)。
示例依赖关系树:
A -> B,C,D,E
B -> F
C -> F
D -> F
E -> F
因此,当我触发A时,B、C、D、E被触发,F也被触发(4次)。我只想触发F一次。
我有beta/beta解决方案(下面),几乎工作。现在我有以下问题与此代码:
- 在job.future.get()结束之前,带有文本“found already running job”的echo不会刷新到屏幕
- 我有这个丑陋的“等待”(for(i = 0; i < 1000; ++i){})。这是因为get方法返回时没有设置结果字段
import hudson.model.*
def getMatchingJob(projectName, branchName, rootExecutor){
result = null
def busyExecutors = []
for(i = 0; i < Jenkins.instance.computers.size(); ++i){
def computer = Jenkins.instance.computers[i]
for(j = 0; j < computer.getExecutors().size(); ++j){
def executor = computer.executors[j]
if(executor.isBusy()){
busyExecutors.add(executor)
}
}
}
for(i = 0; i < busyExecutors.size(); ++i){
def workUnit = busyExecutors[i].getCurrentWorkUnit()
if(!projectName.equals(workUnit.work.context.executionRef.job)){
continue
}
def context = workUnit.context
context.future.waitForStart()
def parameters
def env
for(action in context.task.context.executionRef.run.getAllActions()){
if(action instanceof hudson.model.ParametersAction){
parameters = action
} else if(action instanceof org.jenkinsci.plugins.workflow.cps.EnvActionImpl){
env = action
}
}
def gitBranchParam = parameters.getParameter("GIT_BRANCH")
def rootExecutorParam = parameters.getParameter("ROOT_EXECUTOR")
gitBranchParam = gitBranchParam ? gitBranchParam.getValue() : null
rootExecutorParam = rootExecutorParam ? rootExecutorParam.getValue() : null
println rootExecutorParam
println gitBranchParam
if(
branchName.equals(gitBranchParam)
&& (rootExecutor == null || rootExecutor.equals(rootExecutorParam))
){
result = [
"future" : context.future,
"run" : context.task.context.executionRef.run,
"url" : busyExecutors[i].getCurrentExecutable().getUrl()
]
}
}
result
}
job = getMatchingJob('project/module/BUILD', 'branch', null)
if(job != null){
echo "found already running job"
println job
def done = job.future.get()
for(i = 0; i < 1000; ++i){}
result = done.getParent().context.executionRef.run.result
println done.toString()
if(!"SUCCESS".equals(result)){
error 'project/module/BUILD: ' + result
}
println job.run.result
}
1条答案
按热度按时间zzlelutf1#
我也有类似的问题要解决。不过,我所做的是迭代作业(因为活动作业可能还没有在执行器上执行)。
在我的解决方案中,触发是这样工作的:
这样,作业将按其触发原因分组,可以使用
我给给予每个作业它所拥有的直接上游作业的列表。然后,作业可以检查上游作业是否已完成同一组中的生成,
从那里开始,一旦上游构建的列表被制作出来,我就等待他们。
如果一个上游构建失败,则中止当前构建(这很好地翻译为“中止构建”而不是“失败构建”)。
完整的代码在那里:https://github.com/doudou/autoproj-jenkins/blob/use_autoproj_to_bootstrap_in_packages/lib/autoproj/jenkins/templates/library.pipeline.erb
我的解决方案的主要缺点是,当有很多构建等待时,等待是昂贵的CPU明智的。有内置的
waitUntil
,但它导致了死锁(我还没有尝试过管道插件的最后一个版本,可能已经解决了)。我正在寻找解决这个问题的方法-这就是我发现你的问题的原因。