Jenkins 脚本化管道:必须指定 $class 并实现 class jenkins.scm.api.SCMSource

Jenkins scripted pipeline: must specify $class with an implementation of class jenkins.scm.api.SCMSource

我有一个詹金斯多分支管道。显然它已成功检出主存储库(文件在工作区中可见)。

但是后来我调用了这个方法。目标是检出(在专用子文件夹中)以下存储库和我从主回购检出的同一分支(例如,如果主回购在“我的目标分支名称”检出,则“bar”回购应该还尝试检查分支“my-target-branch-name”或“master”作为后备。事实上,整个用例即使与 documentation of the resolveScm step (page might load slowly, be patient)[=17= 中描述的不一样,也是相似的]

checkout resolveScm(source: git(url: 'git@example.com:foo/bar.git', credentialsId: 'xxx'), targets: [env.BRANCH_NAME, 'master'])

但是我得到一个错误:

16:40:38  java.lang.UnsupportedOperationException: must specify $class with an implementation of class jenkins.scm.api.SCMSource
16:40:38    at org.jenkinsci.plugins.structs.describable.DescribableModel.resolveClass(DescribableModel.java:574)
16:40:38    at org.jenkinsci.plugins.structs.describable.DescribableModel.coerce(DescribableModel.java:473)
16:40:38    at org.jenkinsci.plugins.structs.describable.DescribableModel.buildArguments(DescribableModel.java:409)
16:40:38    at org.jenkinsci.plugins.structs.describable.DescribableModel.instantiate(DescribableModel.java:329)
16:40:38    at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:302)
16:40:38    at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:193)
16:40:38    at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:122)
16:40:38    at groovy.lang.MetaClassImpl.invokeMethodOnGroovyObject(MetaClassImpl.java:1278)
16:40:38    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1172)
16:40:38    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
16:40:38    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:42)
16:40:38    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
16:40:38    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
16:40:38    at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.methodCall(DefaultInvoker.java:20)
16:40:38  Caused: java.lang.IllegalArgumentException: Could not instantiate {source={GIT_AUTHOR_EMAIL=jenkins.donotreply@example.com, GIT_AUTHOR_NAME=Jenkins, GIT_BRANCH=origin/master, GIT_COMMIT=xxx, GIT_COMMITTER_EMAIL=jenkins.donotreply@example.com, GIT_COMMITTER_NAME=Jenkins, GIT_LOCAL_BRANCH=master, GIT_PREVIOUS_COMMIT=yyy, GIT_PREVIOUS_SUCCESSFUL_COMMIT=yyy, GIT_URL=git@example.com:foo/bar.git}, targets=[my-target-branch-name, master]} for org.jenkinsci.plugins.workflow.multibranch.ResolveScmStep
16:40:38    at org.jenkinsci.plugins.structs.describable.DescribableModel.instantiate(DescribableModel.java:334)
16:40:38    at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:302)
16:40:38    at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:193)
16:40:38    at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:122)
16:40:38    at groovy.lang.MetaClassImpl.invokeMethodOnGroovyObject(MetaClassImpl.java:1278)
16:40:38    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1172)
16:40:38    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
16:40:38    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:42)
16:40:38    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
16:40:38    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
16:40:38    at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.methodCall(DefaultInvoker.java:20)
16:40:38    at fooBar.call(fooBar.groovy:14)
16:40:38    at fooBar.call(fooBar.groovy:258)
16:40:38    at ___cps.transform___(Native Method)
...

我哪里错了?

这里是 Jenkinsfile 的完整定义:

pipeline {

    agent { label 'small || big' }

    stages {

        stage('Build') {
            steps {
                sh "ls -la"
                sh "rm -rf secondrepo && mkdir secondrepo"
                dir('secondrepo') {
                    checkout resolveScm(source: git(url: 'git@example.com:foo/bar.git', credentialsId: 'xxx'), targets: [env.BRANCH_NAME, 'master'])
                }
            }
        }

    }

}

问题似乎是在脚本中调用 git(...) 时发生冲突。 resolveScmsource 参数需要一个 jenkins.scm.api.SCMSource 的实例。但是,如果像文档中那样调用 git(),那么它似乎更匹配 functionName in GitStep and create an instance of GitSCM,它 而不是 SCMSource 的子类,这是错误的。 相反,通过调用 git,它应该匹配 git symbol in GitSCMSource

因此,为了解决这个问题,我通过将参数指定为映射来强制实例化 GitSCMSource

checkout resolveScm(source: [$class: 'GitSCMSource', remote: 'git@example.com:foo/bar.git', credentialsId: 'xxx', traits: [gitBranchDiscovery()]], targets: [env.BRANCH_NAME, 'master'])