声明式管道中的并行运行

Parallel runs in declarative pipeline

想要并行触发少量下游作业是使用 groovy 的声明式管道。 尝试如下但遇到了问题。它正在检查条件,但似乎在并行块中遇到了问题。

stage("CHeck for downstraem jobs"){
            agent {
                node {
                  label "${AGENT}"
                  customWorkspace "${SRC}"
                }
            }       
            environment {
                UPSTREAM_PARAMS = "${SRC},${AGV}"
                ADM_FILES = sh (script: 'cd ${SRC}/repo; git diff-tree --no-commit-id --name-only -r $(git log --format="%H" -n 1) | grep "src/util"',
                    returnStatus: true
                )
                FUNC_FILES = sh (script: 'cd ${SRC}/repo; git diff-tree --no-commit-id --name-only -r $(git log --format="%H" -n 1) | grep "include"',
                    returnStatus: true
                )
                CONT_FILES = sh (script: 'cd ${SRC}/repo; git diff-tree --no-commit-id --name-only -r $(git log --format="%H" -n 1) | grep "src/test"',
                    returnStatus: true
                )
                TOOL_FILES = sh (script: 'cd ${SRC}/repo; git diff-tree --no-commit-id --name-only -r $(git log --format="%H" -n 1) | grep "tools"',
                    returnStatus: true
                )              
                
            }
            steps{
                
                echo "Build dir is ${SRC}"
                echo "CHANGED FILES ARE ${ADMIN_FILES}"
                echo "CHANGED FILES ARE ${FUNC_FILES}"
                echo "CHANGED FILES ARE ${CONT_FILES}"
                echo "CHANGED FILES ARE ${TOOL_FILES}"             
                script {
                    if (ADM_FILES == '0' && FUNC_FILES == '0' && CONT_FILES == '0') {
                        echo "trigger parallel both jobs"
                        parallel {
                            stage('Launch JOB admin'){
                                agent any
                                environment {
                                    UPSTREAM_PARAMS = "${SRC},${AGV}"
                                }
                                steps {
                                    build job: 'Downstream_admin_job', parameters: [string(name: 'UPSTREAM_PARAMS', value:"${UPSTREAM_PARAMS}")]
                                } 
                            }
                            stage('Launch job sanity'){
                                agent any
                                environment {
                                    UPSTREAM_PARAMS = "${SRC},${AGV}"
                                }
                                steps {                      
                                    build job: 'Downstream_sanity_job', parameters: [string(name: 'UPSTREAM_PARAMS', value:"${UPSTREAM_PARAMS}")]
                                }
                            
                            }
                        }
                    
                    }
                    
                    if (TOOL_FILES == '0' ) {
                        build job: 'Test_verification_job', parameters: [string(name: 'UPSTREAM_PARAMS', value:"${UPSTREAM_PARAMS}")]
                    } 
                }
            }
        }

但我不确定这里的问题是什么。不支持在“脚本”块内启动并行作业。出现以下错误。

java.lang.IllegalArgumentException: Expected named arguments but got org.jenkinsci.plugins.workflow.cps.CpsClosure2@6e72e37a
at org.jenkinsci.plugins.workflow.cps.DSL.singleParam(DSL.java:718)
at org.jenkinsci.plugins.workflow.cps.DSL.parseArgs(DSL.java:706)
at org.jenkinsci.plugins.workflow.cps.DSL.parseArgs(DSL.java:640)
at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:234)
at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:193)
at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:122)
at jdk.internal.reflect.GeneratedMethodAccessor26987.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:42)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.kohsuke.groovy.sandbox.impl.Checker.call(Checker.java:163)
at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:23)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:158)
at org.kohsuke.groovy.sandbox.impl.Checker.call(Checker.java:161)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:165)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:135)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:135)
at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17)
at WorkflowScript.run(WorkflowScript:338)
at ___cps.transform___(Native Method)
at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:86)
at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:113)
at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:83)
at jdk.internal.reflect.GeneratedMethodAccessor303.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
at com.cloudbees.groovy.cps.impl.ClosureBlock.eval(ClosureBlock.java:46)
at com.cloudbees.groovy.cps.Next.step(Next.java:83)
at com.cloudbees.groovy.cps.Continuable.call(Continuable.java:174)
at com.cloudbees.groovy.cps.Continuable.call(Continuable.java:163)

没有什么不明白的。 我们可以在另一个阶段的“步骤”块内再次开始“脚本”块内的并行阶段吗?

您用于并行命令的语法是 declarative syntax,但您在 script 块内使用它,这需要脚本语法,因此是例外。
在您的 script 块中,您应该使用并行命令的脚本语法:

parallel: Execute in parallel Takes a map from branch names to closures and an optional argument failFast > which will terminate all branches upon a failure in any other branch:

parallel firstBranch: {
    // do something
}, secondBranch: {
    // do something else
},
failFast: true|false

因此,在您的情况下,您可以使用类似以下内容的脚本语法:

 parallel(
    'Launch JOB admin' : {
        node {
            build job: 'Downstream_admin_job', parameters: [string(name: 'UPSTREAM_PARAMS', value: "${SRC},${AGV}")]
        }
    }, 
    'Launch job sanity': {
        node {
            build job: 'Downstream_sanity_job', parameters: [string(name: 'UPSTREAM_PARAMS', value: "${SRC},${AGV}")]
        }
    }
)

或者,您可以尝试通过将 if 语句替换为声明性 when 闭包来避免使用 script 块,然后您可以使用当前语法。