如何为Jenkins管道中的复制工件参数化选择器

时间:2018-08-09 13:01:16

标签: jenkins jenkins-plugins jenkins-pipeline

我们在Jenkins系统中大量使用管道作业,因此需要能够使用copyArtifacts作业参数对Build selector for Copy Artifact步骤进行参数化。

首先,我发现-参数返回String时-copyArtifacts步骤需要BuildSelector的实例。

我发现了BuildSelectorParameter.getSelectorFromXml方法,可将参数转换为BuildSelector的实例,例如:

properties([parameters([
    [$class: 'BuildSelectorParameter',
    defaultSelector: upstream(fallbackToLastSuccessful: true),
    description: '',
    name: 'copyArtifactSelector']])
])

@NonCPS
static BuildSelector getSelectorFromParam(String xmlText) {
    BuildSelectorParameter.getSelectorFromXml(xmlText)
}

node {
    def selector = getSelectorFromParam(params.copyArtifactSelector)
    copyArtifacts(
            projectName: 'sourceJob',
            selector: selector
    )
}

但是,我刚刚意识到创建的BuildSelector不是Serializable。因此,现在我得到了预期的异常:

hudson.plugins.copyartifact.TriggeredBuildSelector
Caused: java.io.NotSerializableException: hudson.plugins.copyartifact.TriggeredBuildSelector
    at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:860)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)

之后,我尝试检查复制工件插件如何处理-不幸的是,我在源代码中找不到任何线索。也许它只是偶然的?创建BuildSelector的方法似乎没有创建任何可序列化的类。

但是也许有人已经遇到了这个问题并有暗示?

编辑

到目前为止我发现了什么

  • 如果我将BuildSelector对象存储在某个变量中,则会抛出NotSerializableException
  • 但是,如果我不先将其传递给某个变量,而是执行对copyArtifacts的方法调用,则NotSerializableException不会发生-至少现在不会:

    node {
        copyArtifacts(
                projectName: 'sourceJob',
                selector: getSelectorFromParam(params.copyArtifactSelector)
        )
    }
    

想法

“复制工件”插件中甚至可能还存在一个隐藏的错误,该错误可能导致发生NotSerializableException异常-还是我错过了某些东西?

问题

像更新示例中那样使用getSelectorFromParam方法是否安全?如果不安全,有没有安全的解决方案?

2 个答案:

答案 0 :(得分:2)

花了几个小时后,我遇到了同样的问题,发现它很适合我。

此处的 Copy Artifact 作业参数的生成选择器的名称为 copyArtifactSelector ,此处的上游作业名称为 sourceJob

    copyArtifacts(projectName: 'sourceJob',
                  selector: [$class: 'ParameterizedBuildSelector', 
                             parameterName: 'copyArtifactSelector'] );

注意:plugin =“ copyartifact@1.39.1”

答案 1 :(得分:0)

有点偏离主题,但是如果您想使用上游触发的管道作业中的参数(例如直接来自“ sourceJob”),则可以使用以下内容:

steps {
    build
        job: 'downstream-copyartifacts-parametrized-job',
        propagate: false,
        wait: false,
        parameters: [
            [$class: 'StringParameterValue', name: 'copyArtifactSelector', value: "<TriggeredBuildSelector />"]
        ]
}

在此示例中,TriggeredBuildSelector将使用上游作业的工件。如果您要触发使用“ sourceJob”生成的工件的第二个后续作业,这将很有用。然后,“ downstream-copyartifacts-parametrized-job”中的参数定义如下所示:

parameters {
    buildSelector(
        name: 'copyArtifactSelector',
        defaultSelector: lastSuccessful(),
        description: 'A build to take the artifacts from'
    )
}

管道中build参数的用法可以与上面所述类似:

steps {
    copyArtifacts
        filter: "/some/artifact/to/copy.zip",
        fingerprintArtifacts: true,
        projectName: 'sourceJob',  
        selector: buildParameter('copyArtifactSelector')
}

我希望有人觉得这有用。