从Jenkinsfile中的共享库导入类

o75abkj4  于 2022-11-01  发布在  Jenkins
关注(0)|答案(1)|浏览(202)

我有一个共享库存储库,其结构如下:

(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 {}

然而没有问题。

fnx2tebb

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
  • 您接收到的不是实际的Groovy类,而是一个类似代理的对象,它只允许对底层类进行有限的操作。
  • 可以使用new函数示例化一个新示例,它的工作原理与new操作符非常相似。
  • 你可以得到一个静态变量(虽然你不能设置它)或者使用代理对象调用一个静态方法,就像它是一个真实的的类一样。如果你使用new示例化一个对象,那么你也可以通过示例访问静态成员(正常的Groovy语义适用)。

在这两种类型的库中,var文件使用相同的机制(也称为全局var和自定义步骤)公开,因此在用法上没有区别。而且,var文件在库的上下文中执行,因此在var文件中,无论类是在全局库中还是在动态共享库中,都不需要特殊的语法来访问类。
现在要回答OP中真实的的问题,可以从动态共享库调用CheckoutSCM。如果它被定义为静态函数,则可以使用myLib.com.company.DeploySteps.CheckoutSCM('repo-here')调用它;如果它被定义为非静态方法,但是在这两种情况下,DeploySteps类都无法访问steps API,因此即使是简单的echo也无法工作。一个传统的解决方法是提供Jenkinsfilethis示例作为一个参数(例如CheckoutSCM(this, 'repo-here')),然后将其赋值给函数中的steps参数(可以命名为任何名称)。然后,您将调用steps参数上的所有步骤调用,例如steps.echo '...'

相关问题