2

我有一个具有这种结构的共享库存储库:

(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'])

src/com/company/DeploySteps.groovy 中的 repo 中的类有一个我想包含在 Jenkinsfile 中的方法(例如 CheckoutSCM)。

部署步骤.groovy:

def CheckoutSCM() {
    useful steps here
}

是否有可能在 Jenkinsfile 中包含此特定方法,例如

import com.company.DeploySteps

然后像这样使用它:

CheckoutSCM('repo-here')

稍后在 Jenkinsfile 中?我多次阅读文档src但没有找到答案是否有可能从文件夹中导入某些内容,而不仅仅是从vars.

为什么我要问,因为现在导入时:import com.company.DeployUtils然后尝试调用方法CheckoutSCM()在 Jenkins 控制台输出中看到错误:

java.lang.NoSuchMethodError:在步骤中找不到这样的 DSL 方法“CheckoutSCM”

下面列出了可用的方法,CheckoutSCM肯定没有我的)

那么,是否有可能从src文件夹导入类到 Jenkinsfile?

PS我可以在Jenkinsfile MainDeploySteps中访问

MainDeploySteps {}

但是没有问题。

4

1 回答 1

2

我只是想添加一个答案来解决 OP 和后续评论中的几个问题。

我是否正确理解共享库仅公开“vars”目录中的全局变量以将该变量包含到 Jenkinsfile 中?虽然尝试直接从“src”文件夹将其他任何内容包含到 Jenkinsfile 中,但它的设计方式并非如此,因为“src”类旨在包含到“vars”目录中的 vars 中。

首先让我介绍一下共享库的背景知识。有两种类型称为动态共享库(使用library步骤定义)和全局共享库(在 Jenkins 全局配置中定义并使用@Library注释访问)。这两者之间的两个重要区别是:

  • 沙盒限制不适用于全局共享库中的代码,因为此类库中的代码被视为受信任的(毕竟,它是由管理员全局配置的)。动态共享库不是这种情况,因为它们是由用户定义的,因此不可信。
  • 全局共享库中的类可以静态引用Jenkinsfile并作为编译的一部分解析Jenkinsfile,但这对于动态共享库是不可能的,因为这些库是在运行时定义的,并且在编译时无法交叉检查类。

来到 OP,它使用动态共享库的概念,这意味着类不能被静态引用。但是,动态共享库中有一些功能可以利用。这些详细信息可以在文档中找到,但这里是一个摘要:

  • librarystep 返回可以分配给变量以供进一步使用的库的表示形式,例如def myLib = library identifier: ...
  • 可以使用库对象上的完全限定名称来引用类,例如def myCls = myLib.com.mycom.mypkg.MyClass
  • 您收到的不是实际的 Groovy 类,而是类似代理的对象,它只允许对底层 lass 进行有限的操作。
  • 您可以使用函数实例化一个新实例new,它的工作方式与运算符非常相似new。您传递的参数与传递给构造函数的参数相同,例如,myCls.new(arg1, arg2)
  • 您可以获得一个静态变量(尽管您不能设置它)或使用代理对象调用静态方法,就像它是真正的类一样。如果您正在使用new无论如何实例化一个对象,那么您也可以通过它访问静态成员(适用正常的 Groovy 语义)。

在这两种类型的库中,var 文件都是使用相同的机制(也称为全局 var 和自定义步骤)公开的,因此在使用上没有区别。此外,var 文件在库的上下文中执行,因此在 var 文件中,您不需要特殊的语法来访问类,无论它们是在全局还是动态共享库中。

现在要回答 OP 中的真正问题,可以CheckoutSCM从动态共享库中调用。如果它被定义为一个静态函数,它可以被调用使用myLib.com.company.DeploySteps.CheckoutSCM('repo-here'),如果它被定义为一个非静态方法,它可以被调用使用myLib.com.company.DeploySteps.new(...).CheckoutSCM('repo-here')。但是,在这两种情况下,DeploySteps该类都无法访问步骤 API,因此即使是简单的echo也无法使用。一种传统的解决方法是将 的this实例Jenkinsfile作为参数(例如CheckoutSCM(this, 'repo-here'))提供,然后将其分配给steps函数内部的参数(可以命名为任何名称)。然后,您将调用step参数上的所有步骤调用,例如step.echo '...'.

于 2021-06-01T07:46:19.397 回答