【发布时间】:2020-10-23 06:19:43
【问题描述】:
我正在使用 Jenkins 来自动化并行 JMeter 测试。这被设置为两个独立的 Jenkins 管道作业,父作业和子作业。
子作业接受一系列参数并针对目标服务执行 JMeter 测试。这是有效的,并且在每个构建中归档四个 CSV 和一个 XML 文件。
父作业在不同节点上并行执行子作业多次。目前它在测试中执行了两次,但最终打算一次生成 10 或 20 个子作业。并行执行工作,每次执行父作业时,子作业记录两个构建,并将它们的工件存档。
问题是如何配置 Copy Artifacts 插件以从子作业中检索工件,以便将它们存档在父作业中。
- 我尝试了 buildParameter 选项(CC_DGN_Test 是子作业的名称)。我在子作业中创建了一个名为
ParentBuildTag的参数,类型为Build selector for Copy Artifact。Permission to Copy Artifact复选框已选中,Projects to allow copy artifacts字段设置为*。
post {
always {
script {
print "buildParameter('${BUILD_TAG}') == " + buildParameter("${BUILD_TAG}")
copyArtifacts optional: false, projectName: 'CC_DGN_Test', selector: buildParameter("${BUILD_TAG}")
archiveArtifacts "*.xml"
}
cleanWs()
}
}
构建参数被填充到子作业中,如下所示:
stage('Node 2') {
agent { node { label 'PIPELINE' } }
steps {
script {
node2 = build job: 'CC_DGN_Test',
parameters: [
string(name: 'dummy', value: "2"),
string(name: 'ParentBuildTag', value: "${BUILD_TAG}"),
string(name: 'Labels', value: "JMETER"),
...additional parameters snipped...
]
}
}
}
控制台日志显示错误:
Error when executing always post condition:
hudson.AbortException: Unable to find a build for artifact copy from: CC_DGN_Test
at hudson.plugins.copyartifact.CopyArtifact.perform(CopyArtifact.java:412)
at org.jenkinsci.plugins.workflow.steps.CoreStep$Execution.run(CoreStep.java:80)
at org.jenkinsci.plugins.workflow.steps.CoreStep$Execution.run(CoreStep.java:67)
at org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution.lambda$start$0(SynchronousNonBlockingStepExecution.java:47)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
没有任何内容被复制到父级。构建标记已正确打印到控制台日志(来自 post{} 中的打印语句)。
08:18:52 buildParameter('jenkins-CC_DGN_TrickleTest-45') == @buildParameter(<anonymous>=jenkins-CC_DGN_TrickleTest-45)
这种方法看起来很有希望,但我认为存在语法问题...我想我应该告诉 copyArtifacts 插件使用 ParentBuildTag 参数,其中值为“jenkins-CC_DGN_TrickleTest-45”,但我没有找到描述语法的示例。
- 我已尝试为子作业使用特定的内部版本号。
stage('Node 2') {
agent { node { label 'PIPELINE' } }
steps {
script {
node2 = build job: 'CC_DGN_Test',
parameters: [
string(name: 'dummy', value: "2"),
string(name: 'ParentBuildTag', value: "${BUILD_TAG}"),
string(name: 'Labels', value: "JMETER"),
...additional parameters snipped...
]
print "Build number (node 2) = " + node2.number //prints build number to console e.g. "Build number (node 2) = 102"
copyArtifacts optional: false, filter: '*.xml, *.csv', fingerprintArtifacts: true, projectName: 'CC_DGN_Test', selector: specific(node2.number)
}
}
}
内部版本号正确打印到控制台日志,但没有记录错误,也没有复制任何内容。
- 我尝试了 buildParameter 方法的替代语法,但没有奏效。
properties([parameters([
[$class: 'BuildSelectorParameter',
defaultSelector: upstream(fallbackToLastSuccessful: true),
description: '',
name: 'ParentBuildTag']])
])
copyArtifacts(
projectName: 'CC_DGN_Test',
selector: [
class: 'ParameterizedBuildSelector',
parameterName: 'ParentBuildTag'
]
);
再次,我怀疑我需要告诉它为 ParentBuildTag 使用什么值,但我借用的语法示例没有显示如何做到这一点。 “上游...”部分只是我从示例中复制的内容,不是我认为需要的内容,但在我的测试中包含它似乎无害。
- 我尝试在节点阶段的“构建作业”命令之后进行存储,并在后期阶段取消存储。这导致构建作业命令之后的 stash 命令出错(“14:00:19 分支节点 1 失败”)和后期阶段的 unstash 命令出错(“错误:没有文件包含在 stash 'node1xml '")。
stash includes: '*.xml', name: 'node1xml'
unstash 'node1xml'
- 我已尝试将子作业的最低要求部分移至父作业,而不是调用子作业。这确实存储了一些工件,只要我以不同的方式命名它们(如果不对底层 JMeter 脚本进行重大更改,就无法更改某些工件),但我宁愿不必将变量传递给 JMeter 脚本根据 Jenkins 构建参数修改文件名。这对我的口味来说太过耦合了,我喜欢为每个子作业分别创建一个构建记录。
这是当前的父作业配置,为简洁起见,在一些地方剪掉了:
pipeline {
agent { node { label 'PIPELINE' } }
options {
timeout(time: 1, unit: 'HOURS')
buildDiscarder(logRotator(numToKeepStr: '100'))
timestamps()
}
environment {
node1 = ""
node2 = ""
}
stages {
stage('Clean Up') {
steps {
cleanWs()
}
}
stage('Test') {
parallel {
stage('Node 1') {
agent { node { label 'PIPELINE' } }
steps {
script {
node1 = build job: 'CC_DGN_Test',
parameters: [
string(name: 'dummy', value: "1"),
string(name: 'ParentBuildTag', value: "${BUILD_TAG}"),
string(name: 'Labels', value: "JMETER"),
...additional parameters snipped...
]
}
}
}
stage('Node 2') {
agent { node { label 'PIPELINE' } }
steps {
script {
node2 = build job: 'CC_DGN_Test',
parameters: [
string(name: 'dummy', value: "2"),
string(name: 'ParentBuildTag', value: "${BUILD_TAG}"),
string(name: 'Labels', value: "JMETER"),
...additional parameters snipped...
]
}
}
}
}
}
}
post {
always {
script {
copyArtifacts optional: false, projectName: 'CC_DGN_Test', selector: buildParameter("${BUILD_TAG}")
archiveArtifacts "*.xml"
}
cleanWs()
}
}
}
根据当前配置,我的目标是让父作业在作业完成后总共包含 8 个 CSV 和 2 个 XML,但目前父作业没有存档任何内容。 copyArtifact 语法哪里出了问题?
【问题讨论】:
-
你能解决这个问题吗?
-
@edt_devel 不,我做不到。目前,子作业有一个管道步骤,它们处理自己的工件。父作业的存在只是为了生成配置数量的子作业,并保存计划定义。
标签: jenkins jenkins-pipeline jenkins-plugins