我有一个共享库存储库,其结构如下:
(root)
+- src
| +- com
| +- company
| +- DeploySteps.groovy
+- vars
| +- MainDeploySteps.groovy
此库通过Jenkinsfile导入到作业中,如下所示:
library identifier: 'jenkinslib@master', retriever: modernSCM(
[$class : 'GitSCMSource',
remote : 'git@url.to.git:jenkinslib.git',
credentialsId: 'jenkins-credentials'])
groovy有一个方法(例如CheckoutSCM),我希望将它包含在Jenkinsfile中。
DeploySteps.groovy:
def CheckoutSCM() {
useful steps here
}
是否有可能在Jenkinsfile中包含此特定方法,如
import com.company.DeploySteps
然后像这样使用它:
CheckoutSCM('repo-here')
在Jenkinsfile之后?我读了documentation很多次,但没有找到答案是有可能从src
文件夹导入一些东西,而不仅仅是从vars
。
我为什么这么问是因为现在进口的时候:import com.company.DeployUtils
,然后尝试调用方法CheckoutSCM()
,请参见Jenkins控制台输出中的错误:
java.lang.NoSuchMethodError:在步骤中找不到这样DSL方法'CheckoutSCM'
下面列出了可用的方法,其中肯定没有地雷CheckoutSCM
)
那么,是否有可能将类从src
文件夹导入到Jenkinsfile?
P.S.我可以在Jenkinsfile MainDeploySteps中访问
MainDeploySteps {}
然而没有问题。
1条答案
按热度按时间fnx2tebb1#
我只是想补充一个答案,以解决OP和后续评论中的几个问题。
共享库只暴露'vars'目录中全局变量,将该变量包含到Jenkinsfile中,我理解对吗?尝试将任何其他内容直接从'src'文件夹包含到Jenkinsfile中并不是它的设计方式,因为'src'类旨在从'vars'目录包含到变量中。
首先让我给予一下共享库的背景。有两种类型被称为动态共享库(使用
library
步骤定义)和全局共享库(在Jenkins全局配置中定义并使用@Library
注解访问)。这两者之间的两个重要区别是:Jenkinsfile
中被静态引用,并作为Jenkinsfile
编译的一部分被解析,但这对于动态共享库是不可能的,因为这些库是在运行时定义的,并且类不能在编译时被交叉检查。OP使用了动态共享库的概念,这意味着类不能被静态引用。然而,动态共享库中的一些特性是可以利用的。这些细节可以在文档中找到,但这里是一个总结:
library
step返回库的表示形式,可以将其赋给变量以供将来使用,类似于def myLib = library identifier: ...
def myCls = myLib.com.mycom.mypkg.MyClass
new
函数示例化一个新示例,它的工作原理与new
操作符非常相似。new
示例化一个对象,那么你也可以通过示例访问静态成员(正常的Groovy语义适用)。在这两种类型的库中,var文件使用相同的机制(也称为全局var和自定义步骤)公开,因此在用法上没有区别。而且,var文件在库的上下文中执行,因此在var文件中,无论类是在全局库中还是在动态共享库中,都不需要特殊的语法来访问类。
现在要回答OP中真实的的问题,可以从动态共享库调用
CheckoutSCM
。如果它被定义为静态函数,则可以使用myLib.com.company.DeploySteps.CheckoutSCM('repo-here')
调用它;如果它被定义为非静态方法,但是在这两种情况下,DeploySteps
类都无法访问steps API,因此即使是简单的echo
也无法工作。一个传统的解决方法是提供Jenkinsfile
的this
示例作为一个参数(例如CheckoutSCM(this, 'repo-here')
),然后将其赋值给函数中的steps
参数(可以命名为任何名称)。然后,您将调用steps
参数上的所有步骤调用,例如steps.echo '...'
。