You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jenkins循环生成多参数并行任务仅触发单个Job问题排查

问题

我编写了带不同参数的并行编译任务Jenkinsfile,期望调用同一build job(compile2)并传入不同参数,但实际仅触发一个compile2任务。Jenkinsfile代码如下:

stage('compile'){
        steps{
            script{
                tasks = BUILD_TASKS.split(',')
                def jobs = [:]
                for (arg in tasks)
                {
                    arg_sub = arg.split('_')
                    sh "echo ${arg_sub}"
                    pub = arg_sub[0]
                    arc = arg_sub[1]
                    doc = arg_sub[2]
                    jobs["${pub}_${arc}_${doc}"] = {stage("${pub}_${arc}_${doc}") {retry(1){
                                                              build job: 'compile2', parameters: 
                                                              [
                                                              string(name: 'DOCKER_IMG', value: "xxx:${doc}"),
                                                              string(name: 'PUBLIC_CLOUD', value: pub),
                                                              string(name: 'ARCHITECTURE', value: arc)
                                                              ]}}}
                }
                
                parallel jobs
                }
            }
        }

执行后,预期会启动多个带不同参数的compile2任务,但实际仅启动一个compile2 #27任务,日志重复显示:

[YES_amd_7u]Starting building: compile2 #27
[YES_amd_7u]Starting building: compile2 #27
[YES_arm_8u]Starting building: compile2 #27
[YES_arm_8u]Starting building: compile2 #27
....

且该compile2 #27任务日志中重复显示:

Started by upstream project "AutoRelease" build number 49
Started by upstream project "AutoRelease" build number 49
Started by upstream project "AutoRelease" build number 49
Started by upstream project "AutoRelease" build number 49
....

另外,若手动编写并行任务块(如下)则可正常工作,生成多个不同编号的compile2任务:

parallel{
   YES_amd_7u:{
      build job xxxxxx
   },
   YES_arm_7u:{
      build job xxxxxx
   }
}

对应的日志为:

[YES_amd_7u]Starting building: compile2 #31
[YES_amd_7u]Starting building: compile2 #32
[YES_arm_8u]Starting building: compile2 #33
[YES_arm_8u]Starting building: compile2 #34
....
原因与解决方法

问题原因

核心问题是Groovy闭包的延迟绑定特性加上未正确声明局部变量,导致所有并行任务共享同一组参数值:

  1. 循环内的pub、arc、doc等变量未用def修饰,属于脚本级全局变量,所有闭包共享同一个变量引用。
  2. Groovy闭包是延迟执行的,当parallel jobs启动并行任务时,循环已经执行完毕,所有闭包都会读取这些全局变量的最终值(即循环最后一次迭代的参数)。
  3. Jenkins检测到多个参数完全一致的构建请求,会复用同一个正在执行的build任务,因此出现重复启动同一任务的日志。

解决方法

给循环内的所有变量添加def声明,将它们转为每次循环迭代的局部变量,让每个闭包绑定当前迭代的独立参数值:

stage('compile'){
    steps{
        script{
            def tasks = BUILD_TASKS.split(',')
            def jobs = [:]
            for (arg in tasks)
            {
                def arg_sub = arg.split('_')
                sh "echo ${arg_sub}"
                def pub = arg_sub[0]
                def arc = arg_sub[1]
                def doc = arg_sub[2]
                jobs["${pub}_${arc}_${doc}"] = {
                    stage("${pub}_${arc}_${doc}") {
                        retry(1){
                            build job: 'compile2', parameters: 
                            [
                                string(name: 'DOCKER_IMG', value: "xxx:${doc}"),
                                string(name: 'PUBLIC_CLOUD', value: pub),
                                string(name: 'ARCHITECTURE', value: arc)
                            ]
                        }
                    }
                }
            }
            
            parallel jobs
        }
    }
}

修改后,每个并行闭包都会捕获当前迭代的局部参数,传入不同的参数值给compile2任务,Jenkins就会触发各自独立的build任务,和手动编写并行块的效果一致。

内容的提问来源于stack exchange,提问作者Bobi.Liu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 23:47:48