向 Jenkins 共享库提供参数
Feeding parameters to Jenkins shared library
我有一个用于我的 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{}
。功能代码如下:
詹金斯文件:
@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
}
当你得到一个错误“没有这样的 DSL 方法...”时,它通常只是意味着参数的类型和实际传递的参数不兼容,这里就是这种情况。
函数examFun()
需要一个数组,但你实际上传递的是一个ArrayList
。正如 中所解释的,低级数组在 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
方法。我一直在用这个。
我有一个用于我的 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{}
。功能代码如下:
詹金斯文件:
@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
}
当你得到一个错误“没有这样的 DSL 方法...”时,它通常只是意味着参数的类型和实际传递的参数不兼容,这里就是这种情况。
函数examFun()
需要一个数组,但你实际上传递的是一个ArrayList
。正如
试试这个:
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
方法。我一直在用这个。