如何通过groovy脚本获取运行jenkins构建的列表?

如何通过groovy脚本获取运行jenkins构建的列表?,jenkins,groovy,Jenkins,Groovy,有没有办法通过系统Groovy脚本获取Jenkins中运行的构建列表? 我尝试在繁忙的执行器中循环,但从执行器对象中,我无法获取构建对象: def busyExecutors = Jenkins.instance.computers .collect { c -> c.executors.findAll { it.isBusy() }

有没有办法通过系统Groovy脚本获取Jenkins中运行的构建列表? 我尝试在繁忙的执行器中循环,但从执行器对象中,我无法获取构建对象:

def busyExecutors = Jenkins.instance.computers
                                .collect { 
                                  c -> c.executors.findAll { it.isBusy() }
                                }
                                .flatten() // reminder: transforms list(list(executor)) into list(executor)

busyExecutors.each { e -> 
  println('=====print out methods of executor object=======');
  println e.metaClass.methods*.name.sort().unique();

}
我也可以针对我感兴趣的工作,比如:

def item = hudson.model.Hudson.instance.getItem("my_job");
println item.metaClass.methods*.name.sort().unique(); 
但接下来我必须循环100个(如果不是更多的话)构建,并询问每个构建是否正在运行

必须有一种更简单/更好的方法来获取正在运行的构建列表

关于如何通过System Groovy脚本(其中一些是我编写的)执行各种操作,有很多信息,但我不知道如何获得正在运行的构建列表:

// get the xml from the rest api
def builds = 'http://myJenkins/jenkins/computer/api/xml?depth=1&xpath=//url&wrapper=builds'.toURL().text
// parse the xml result
def xml = new XmlSlurper().parseText(builds)
// for each url get the job name
def jobNames = xml.url.collect{ url ->
    // regex to get the jobName and a build number
    def group = (url =~ /.*\/job\/([^\/]+)\/(\d+)/)
    println group[0] // [http://myJenkins/jenkins/job/someJob/300, someJob, 300]
    def jobName = group[0][1]
    return jobName
    // to get the build number
    // def buildNr = group[0][2]
}
println jobNames


您可以使用RESTAPI获取正在运行的构建列表。使用以下url:

http://myjenkins/jenkins/computer/api/xml?depth=1

您将得到以下响应,其中包含
元素。只有正在运行的构建
中有
元素。还请注意,正在运行的构建具有
false
值:

<computerSet>
    <busyExecutors>1</busyExecutors>
    <computer>
        ...
        <executor>
            <idle>true</idle>
            <likelyStuck>false</likelyStuck>
            <number>0</number>
            <progress>-1</progress>
        </executor>
        <executor>
            <currentExecutable>
                <number>328</number>
                <!-- This is the url from the current running build -->
                <url>http://myJenkins/jenkins/job/someJob/328/</url>             
            </currentExecutable>
            <currentWorkUnit/>
            <idle>false</idle>
            <likelyStuck>false</likelyStuck>
            <number>1</number>
            <progress>24</progress>
        </executor>
        ...
    </computer> 
<computerSet>
您将得到如下结果:

<builds>
    <url>
http://myJenkins/jenkins/job/someJob/300/
    </url>
    <url>
http://myJenkins/jenkins/job/another/332/
    </url>
</builds>

这不是特别有效(但比使用API更有效)。它将打印出所有当前运行的带有HTML链接的构建。可以在脚本控制台或通过scriptler运行

def now = new Date()  // Get the current time
// Get a list of all running jobs
def buildingJobs = Jenkins.instance.getAllItems(Job.class).findAll { 
  it.isBuilding() }

buildingJobs.each { job->
    // Enumerate all runs
    allRuns = job._getRuns()
    allRuns.each { item ->
        // If NOT currently building... check the next build for this job
        if (!item.isBuilding()) return

        // Access and calculate time information for this build.
        def startedAt = new Date(item.getStartTimeInMillis())
        def duration_mins = ((now.getTime() - item.getStartTimeInMillis()) / 60000).intValue()

        estDurationMins = (item.getEstimatedDuration() / 60000).intValue()
        String jobname = item.getUrl()
        jobname = jobname.replaceAll('job/', '')  // Strip redundant folder info.

        println "${duration_mins.toString().padLeft(5)}/" +
            "${estDurationMins.toString().padLeft(4)}  - " +
            "<a href=${baseURL}${item.getUrl()}>${jobname}</a>"
    }
}
def now=new Date()//获取当前时间
//获取所有正在运行的作业的列表
def buildingJobs=Jenkins.instance.getAllItems(Job.class).findAll{
it.isBuilding()}
buildingJobs.each{job->
//枚举所有运行
allRuns=作业。\u getRuns()
allRuns.each{item->
//如果当前未生成…请检查此作业的下一个生成
如果(!item.isBuilding())返回
//访问并计算此生成的时间信息。
def startedAt=新日期(item.getStartTimeInMillis())
def duration_mins=(now.getTime()-item.getStartTimeInMillis())/60000.intValue()
estDurationMins=(item.getEstimatedDuration()/60000).intValue()
字符串jobname=item.getUrl()
jobname=jobname.replaceAll('job/','')//删除冗余文件夹信息。
println“${duration_mins.toString().padLeft(5)}/”+
“${estDurationMins.toString().padLeft(4)}”+
""
}
}

我找到了几种不用REST API或解析XML的方法:

runningBuilds = Jenkins.instance.getView('All').getBuilds().findAll() { it.getResult().equals(null) }
这假设您没有删除或修改Jenkins中的默认“All”视图。当然,如果您确切地知道构建将在哪个视图中,您可以替换不同的视图名称。或者您可以尝试以下方法:

runningBuilds = Jenkins.instance.getItems().collect { job->
  job.builds.findAll { it.getResult().equals(null) }
}.flatten()
尽管这种方法不需要视图名称,但它也有局限性。它不会下降到文件夹或多分支管道或类似的东西。您将需要手动进入文件夹或编造一些自动操作的方法。例如,这里有一个适用于多分支管道的版本:

Jenkins.instance.getItemByFullName(multibranchPipelineProjectName).getItems().each { repository->
  repository.getItems().each { branch->
    branch.builds.each { build->
      if (build.getResult().equals(null)) {
        // do stuff here ...
      }
    }
  }
}
我认为可能有一种比
build.getResult().equals(null)
更准确的方法来确定构建是否正在运行,但我很难找到好的API文档,所以我不确定。这只是我发现的第一个使用对象内省的有效方法

同样由于缺少API文档,我不确定我在这里使用的
Jenkins.instance.getItems()
与在中使用的
Jenkins.instance.getAllItems()
之间是否存在显著差异


最后,请注意,这些都是相对低效的方法。它们会迭代每个作业的每个生成,因此,如果保存生成的长期历史记录(默认设置为每个作业只保存10个生成的历史记录)或有数千个作业,这可能需要一段时间才能运行。有关如何更有效地完成此任务的问题,请参阅。

意识到我也有同样的问题。还有一个问题是,通过执行器的循环只包括奴隶,而不包括主人。请看下面的例子。要获取作业的构建,可以在脚本顶部使用
\u getRuns()
Hint
import jenkins.model.jenkins
。我编写了一个脚本,其中使用Groovy脚本遍历API以查找信息。这有点难看,但是Jenkins的API并没有提供很多好的助手方法,所以这并不令人惊讶。请参阅类似的问题。这很有效!哇!非常感谢!我不知道你是那样做的!您传递的
Jenkins.instance.getItemByFullName()
示例是什么?我只是尝试使用我的多分支作业名称,但它没有列出作业。这不起作用
Jenkins.instance.getItemByFullName('my-pipeline-job)
@red888如果您的多分支项目名为
my project
,您的回购名为
my repo
,并且您正在尝试构建
主分支,然后全名将是
myproject/myrepo/master
。嗯,我确认现在我有了作业的正确路径,但代码片段在这里失败:
repository.getItems()
with
groovy.lang.MissingMethodException:没有方法签名:org.jenkinsi.plugins.workflow.job.WorkflowJob.getItems()适用于参数类型:()值:[]
较旧的Jenkins版本为Jenkins.instance.getView('All')返回null。因此,对于较旧的jenkins版本jenkins.instance.getView('All'),使用较小的“All”,而不是大写的“All”。
Jenkins.instance.getItemByFullName(multibranchPipelineProjectName).getItems().each { repository->
  repository.getItems().each { branch->
    branch.builds.each { build->
      if (build.getResult().equals(null)) {
        // do stuff here ...
      }
    }
  }
}