我正在构建一个共享库,我想要它有类定义,例如:
class Kubernetes implements Serializable{
def script
Kubernetes(script){this.script = script}
def someMethod(){ ... }
}
我已将此类定义放在共享库 git repo 中,路径为
src/foo/bar/Kubernetes.groovy
。我正在使用 jenkinsfile 顶部的以下步骤导入共享库,在任何节点或管道指令之外:library identifier: 'custom-lib@master', retriever: modernSCM(
[$class: 'GitSCMSource',
remote: '<my-git-remote>',
credentialsId: '<my-credentials-id>'])
import foo.bar.*
我已经验证了这个库正在被拉取,因为我可以引用在
vars/
目录中创建的自定义 DSL 步骤。但是,当我编辑管道文件以创建该类的实例时,管道启动时会立即引发错误:org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 1276: unable to resolve class Kubernetes
@ line 1276, column 16.
def kube = new Kubernetes(this)
^
1 error
at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310)
at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:958)
at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:605)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:554)
at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268)
at groovy.lang.GroovyShell.parseClass(GroovyShell.java:688)
at groovy.lang.GroovyShell.parse(GroovyShell.java:700)
at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.doParse(CpsGroovyShell.java:133)
at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.reparse(CpsGroovyShell.java:127)
at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.parseScript(CpsFlowExecution.java:557)
at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.start(CpsFlowExecution.java:518)
at org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:290)
at hudson.model.ResourceController.execute(ResourceController.java:97)
at hudson.model.Executor.run(Executor.java:429)
Finished: FAILURE
据我所知,在抛出该错误之前甚至没有执行库拉取。但据我所知,这正是 Jenkins docs 中演示此功能的方式。我是否需要做一些不同的事情才能正确加载库?
最佳答案
动态加载库不会将类直接导入管道的类路径 - 这就是为什么您会收到此异常,无论您是引用完全限定的类名还是尝试导入(这也会失败)。
关于 library
步骤的 Jenkins 文档解释了如何加载库中定义的类:
在你的情况下,这意味着做这样的事情:
def kub = library( identifier: 'my-custom-library@master', retriever: modernSCM([
$class: 'GitSCMSource', remote: 'file:///var/jenkins_home/libraries', credentialsId: ''
])).foo.bar.Kubernetes.new(this)
println kub
这是我用于测试的本地示例库。当我运行管道时,它会成功并向控制台显示以下输出:
Started by user admin
[Pipeline] library
Loading library my-custom-library@master
Attempting to resolve master from remote references...
> git --version # timeout=10
> git ls-remote -h -t file:///var/jenkins_home/libraries # timeout=10
Found match: refs/heads/master revision 92e5e92f84f04293a405b2e05ec6497781ac3e47
> git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
> git config remote.origin.url file:///var/jenkins_home/libraries # timeout=10
Fetching without tags
Fetching upstream changes from file:///var/jenkins_home/libraries
> git --version # timeout=10
> git fetch --no-tags --progress file:///var/jenkins_home/libraries +refs/heads/*:refs/remotes/origin/*
Checking out Revision 92e5e92f84f04293a405b2e05ec6497781ac3e47 (master)
> git config core.sparsecheckout # timeout=10
> git checkout -f 92e5e92f84f04293a405b2e05ec6497781ac3e47
Commit message: "commit"
> git rev-list --no-walk 92e5e92f84f04293a405b2e05ec6497781ac3e47 # timeout=10
[Pipeline] echo
foo.bar.Kubernetes@4ae7edb1
[Pipeline] End of Pipeline
Finished: SUCCESS
定义全局库
我在 Jenkins 管道中没有使用太多动态库加载,我实际上使用了全局库定义,例如:
在这种情况下,我可以使用以下命令加载库:
@Library('default_jenkins_libs@master') _
import foo.bar.Kubernetes
def kub = new Kubernetes(this)
println kub
这个例子产生与上面粘贴的类似的输出。希望能帮助到你。
关于Jenkins 共享库与 Jenkinsfile 中的类引用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50978421/