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

How to parameterize selector for copy artifacts in Jenkins pipeline

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

首先我发现 - 虽然参数 returns 和 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 的方法似乎没有创建任何类型的可序列化 class.

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

编辑

到目前为止我发现了什么:

想法

Copy Artifact 插件中是否甚至可能存在一个隐藏的错误,它可能导致 NotSerializableException 异常发生 - 或者我遗漏了什么?

问题

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

我在这上面花了好几个小时后遇到了同样的问题,我发现了这个,它对我来说非常有效。

这里的 Copy Artifact 作业参数的构建选择器的名称是 copyArtifactSelector,这里的上游作业名称是 来源工作:

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

注:插件="copyartifact@1.39.1"

编辑: 同时 - 使用 copyartifact V1.43 - 支持以下语法:

    copyArtifacts(projectName: 'sourceJob',
                  selector: buildParameter('copyArtifactSelector'));

小 off-topic,但如果你想使用来自 Upstream-triggered 管道作业的参数(例如直接来自 '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'
    )
}

管道中构建参数的用法与上述类似:

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

我希望有人觉得这有用。