在Jenkins中同一作业的多个构建中复制构件文件

8
我正在使用MultiJob插件,并有一个作业(Job-A)多次触发Job-B。 我的要求是从每个构建中复制一些工件(xml文件)。
我遇到的困难是,使用“最后成功的构建”选项的Copy Artifact插件仅会获取 Job-B 最后一个构建,而我需要从在 Job-A 同一构建上触发的所有构建中进行复制。
流程如下: Job-A开始并触发:
`Job-A` -->
   Job-B build #1
   Job-B build #2
   Job-B build #3
   ** copy artifcats of all last 3 builds, not just #3 **

注意: Job-B 可以在同一次运行中在不同的从机上执行(我通过设置上游作业-A的参数动态地设置从机运行)。

当所有构建完成时,我希望Job-A从构建#1,#2和#3复制工件,而不仅仅是从最后一个构建中复制。 我该如何做到这一点?


最后成功构件的想法是始终拥有最新的稳定构件可供下载。在您的示例中,假设构建#2失败了,那么应该从中复制构件吗? - Vitalii Elenhaupt
是的,不管构建状态如何,我希望复制工件。 - etaiso
3个回答

7

这里是更通用的Groovy脚本;它使用了Groovy插件和copyArtifact插件;请查看代码注释中的说明。

它只是将所有下游作业的构件复制到上游作业的工作空间中。

如果您多次调用同一作业,则可以在copyArtifact的“target”参数中使用作业编号来保持构件分开。

// This script copies artifacts from downstream jobs into the upstream job's workspace.
//
// To use, add a "Execute system groovy script" build step into the upstream job
// after the invocation of other projects/jobs, and specify
// "/var/lib/jenkins/groovy/copyArtifactsFromDownstream.groovy" as script.

import hudson.plugins.copyartifact.*
import hudson.model.AbstractBuild
import hudson.Launcher
import hudson.model.BuildListener
import hudson.FilePath

for (subBuild in build.builders) {
  println(subBuild.jobName + " => " + subBuild.buildNumber)
  copyTriggeredResults(subBuild.jobName, Integer.toString(subBuild.buildNumber))
}

// Inspired by http://kevinormbrek.blogspot.com/2013/11/using-copy-artifact-plugin-in-system.html
def copyTriggeredResults(projName, buildNumber) {
   def selector = new SpecificBuildSelector(buildNumber)

   // CopyArtifact(String projectName, String parameters, BuildSelector selector,
   // String filter, String target, boolean flatten, boolean optional)
   def copyArtifact = new CopyArtifact(projName, "", selector, "**", null, false, true)

   // use reflection because direct call invokes deprecated method
   // perform(Build<?, ?> build, Launcher launcher, BuildListener listener)
   def perform = copyArtifact.class.getMethod("perform", AbstractBuild, Launcher, BuildListener)
   perform.invoke(copyArtifact, build, launcher, listener)
}

3
我建议您采用以下方法:
  1. Use Execute System Groovy script from Groovy Plugin to execute the following script:

    import hudson.model.*
    
    // get upstream job
    def jobName = build.getEnvironment(listener).get('JOB_NAME')
    def job = Hudson.instance.getJob(jobName)
    def upstreamJob = job.upstreamProjects.iterator().next()
    
    // prepare build numbers
    def n1 = upstreamJob.lastBuild.number
    def n2 = n1 - 1
    def n3 = n1 - 2
    
    // set parameters
    def pa = new ParametersAction([
      new StringParameterValue("UP_BUILD_NUMBER1", n1.toString()),
      new StringParameterValue("UP_BUILD_NUMBER2", n2.toString()),
      new StringParameterValue("UP_BUILD_NUMBER3", n3.toString())
    ])
    Thread.currentThread().executable.addAction(pa)
    

    This script will create three environment variables which correspond to three last build numbers of upstream job.

  2. Add three build steps Copy artifacts from upstream project to copy artifacts from last three builds of upstream project (use environment variables from script above to set build number):

enter image description here

  1. Run build and checkout build log, you should have something like this:

    Copied 2 artifacts from "A" build number 4
    Copied 2 artifacts from "A" build number 3
    Copied 1 artifact from "A" build number 2
    

注意:也许需要调整脚本以捕捉异常情况,例如“上游项目只有两个构建”,“当前作业没有上游作业”,“当前作业有多个上游作业”等。


1
谢谢你的回答和解决方案,但我正在寻找更通用的东西。例如,下游项目的数量会因运行而异。我猜这可以从脚本中更改,但那样我就必须“手动”复制工件,而不是通过插件。 - etaiso

0
您可以使用“执行Shell”构建步骤中的以下示例。 请注意,它只能从Jenkins主机器上运行,并且调用此步骤的作业也必须触发MultiJob。
#--------------------------------------
# Copy Artifacts from MultiJob Project
#--------------------------------------
PROJECT_NAME="MY_MULTI_JOB"
ARTIFACT_PATH="archive/target"
TARGET_DIRECTORY="target"

mkdir -p $TARGET_DIRECTORY
runCount="TRIGGERED_BUILD_RUN_COUNT_${PROJECT_NAME}"

for ((i=1; i<=${!runCount} ;i++))
do
   buildNumber="${PROJECT_NAME}_${i}_BUILD_NUMBER"
   cp $JENKINS_HOME/jobs/$PROJECT_NAME/builds/${!buildNumber}/$ARTIFACT_PATH/* $TARGET_DIRECTORY
done

#--------------------------------------

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接