如何参数化 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.
但也许有人已经遇到了这个问题并得到了提示?
编辑
到目前为止我发现了什么:
- 如果我将
BuildSelector
对象存储在某个变量中,它会抛出 NotSerializableException
.
但是,如果我不先将它传递给某个变量,而是在对 copyArtifacts
的方法调用中进行调用,则 NotSerializableException
不会发生 - 至少现在不会:
node {
copyArtifacts(
projectName: 'sourceJob',
selector: getSelectorFromParam(params.copyArtifactSelector)
)
}
想法
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')
}
我希望有人觉得这有用。
我们在 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.
但也许有人已经遇到了这个问题并得到了提示?
编辑
到目前为止我发现了什么:
- 如果我将
BuildSelector
对象存储在某个变量中,它会抛出NotSerializableException
. 但是,如果我不先将它传递给某个变量,而是在对
copyArtifacts
的方法调用中进行调用,则NotSerializableException
不会发生 - 至少现在不会:node { copyArtifacts( projectName: 'sourceJob', selector: getSelectorFromParam(params.copyArtifactSelector) ) }
想法
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')
}
我希望有人觉得这有用。