【问题标题】:Feeding parameters to Jenkins shared library向 Jenkins 共享库提供参数
【发布时间】:2020-11-06 17:37:15
【问题描述】:

我有一个用于 Jenkinsfile 的 Jenkins 共享库。我的库有一个完整的管道,它有一个在我的管道中使用的函数(我们称之为examFun())。

我的 Jenkins 文件:

@Library('some-shared-lib') _

jenkinsPipeline{
    exampleArg = "yes"
}

我的共享库文件(名为 jenkinsPipeline.groovy):

def examFun(){
  return [
     new randClass(name: 'Creative name no 1', place: 'London')
     new randClass(name: 'Creating name no 2', place: 'Berlin')
  ]
}

def call(body) {
    def params= [:]
    body.resolveStrategy = Closure.DELEGATE_FIRST
    body.delegate = params
    body()

    pipeline {
        // My entire pipeline is here
        // Demo stage
        stage("Something"){
          steps{
            script{
              projectName = params.exampleArg
            }
          }
        }

    }
}

class randClass {
    String name
    String place
}

它工作正常,但examFun() 的值是硬编码的,将来可能需要更改。因此,我希望能够从我的 Jenkinsfile 中更改它们(就像我可以更改 exampleArg 一样)。按照this的文章,我尝试了以下:

我将examFun() 更改为

def examFun(String[] val){
  return [
     new randClass(name: val[0], place: 'London')
     new randClass(name: val[1], place: 'Berlin')
  ]
}

并从我的 Jenkinsfile 中调用它,如下所示

@Library('some-shared-lib') _

jenkinsPipeline.examFun(['Name 1','Name 2'])
jenkinsPipeline{
    exampleArg = "yes"
}

但这不起作用(可能是因为我的库是通过 def call(body){} 构建的)。之后,我尝试将 jenkinsPipeline.groovy 拆分为 2 个文件:第一个文件包含我的管道部分,第二个文件包含 examFun()randClass。我修改了我的 Jenkinsfile 如下:

@Library('some-shared-lib') _
def config = new projectConfig() // New groovy filed is called 'projectConfig.groovy'
config.examFun(["Name 1","Name 2"])

jenkinsPipeline{
    exampleArg = "yes"
}

但又没有成功。错误总是说

No such DSL method 'examFun()' found among steps

更新 - 新错误

感谢 zett42 ,我已经成功解决了这个错误。但是,我遇到了下面提到的另一个错误:

java.lang.NullPointerException: Cannot invoke method getAt() on null object

为了解决这个问题,就我而言,我需要将examFun() 分配给我的Jenkinsfile 中的一个变量,并将其作为jenkinsPipeline{} 中的参数传递。功能代码如下: Jenkins 文件

@Library('some-shared-lib') _

def list = jenkinsPipeline.examFun(['Name 1','Name 2'])
def names = jenkinsPipeline.someFoo(list)
jenkinsPipeline{
    exampleArg = "yes"
    choiceArg = names
}

jenkinsPipeline.groovy

def examFun(List<String> val){
  return [
     new randClass(name: val[0], place: 'London')
     new randClass(name: val[1], place: 'Berlin')
  ]
}
def call(body) {
    def params= [:]
    body.resolveStrategy = Closure.DELEGATE_FIRST
    body.delegate = params
    body()

    pipeline {
        // My entire pipeline is here
        parameters{
          choice(name: "Some name", choices: params.choiceArg, description:"Something")
        }
        // Demo stage
        stage("Something"){
          steps{
            script{
              projectName = params.exampleArg
            }
          }
        }

    }
}

def someFoo(list) {
    def result = []
    list.each{
        result.add(it.name)
    }
    return result
}

class randClass {
    String name
    String place
}

【问题讨论】:

    标签: jenkins groovy jenkins-shared-libraries


    【解决方案1】:

    当你得到一个错误“no such DSL method...”时,通常只是意味着参数的类型和实际传递的参数不兼容,这里就是这种情况。

    函数examFun() 需要一个数组,但您实际上传递的是一个ArrayList。正如this answer 中解释的那样,低级数组在 Groovy 中并不是真正的惯用语。

    试试这个:

    def examFun(List<String> val){
      return [
         new randClass(name: val[0], place: 'London')
         new randClass(name: val[1], place: 'Berlin')
      ]
    }
    

    List 是更通用的接口,由ArrayList 实现。

    现在,您的第一个 jenkinsfile 示例应该可以工作了:

    jenkinsPipeline.examFun(['Name 1','Name 2'])
    

    您实际上可以拥有其他命名方法,即使您已经拥有call 方法。我一直在用这个。

    【讨论】:

    • 这确实解决了我的错误。但是,我现在确实收到java.lang.NullPointerException: Cannot invoke method getAt() on null object 错误。该错误似乎来自需要examFun() 才能工作的脚本的一部分。我把所有东西都放在一个 groovy 文件中。
    • 我认为这是因为examFun() 被调用了两次:首先是通过jenkinsPipeline.examFun(['Name 1','Name 2']),然后是jenkinsPipeline{}(可能会覆盖它?不确定这是否属实)。
    • @Joe 请编辑您的问题以在底部添加您当前的代码(请保持原始问题不变,以便我们拥有“历史”)。
    • 添加了我当前的代码,以及我试图用来解决当前问题的链接。
    • 我想通了 - 我需要将 jenkinsPipeline.examFun(['Name 1','Name 2']) 存储为某个变量,并将此变量作为参数传递给 jenkinsPipeline{}。我将在我的答案中进行编辑,但会接受你的作为最终答案,因为它处理的是原始问题。
    猜你喜欢
    • 2018-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多