Jenkins 共享库中未调用构造函数

yas*_*ssc 5 groovy jenkins jenkins-groovy jenkins-pipeline jenkins-shared-libraries

我正在尝试开发共享库并具有以下目录结构

  • src/com/mycomapny
    • MyTest.groovy
  • 变量
    • 测试.groovy
  • 詹金斯档案

我的Jenkinsfile只调用test.groovy 中可用的方法和所需的输入。它导入 MyTest 并创建对象并调用构造函数,然后是执行MyTest.groovy文件中可用功能的实际方法

这里的构造函数类从未从全局 vars/test.groovy 调用

我尝试从 groovy 调用类和方法它工作正常但是当我从 jenkinsfile 调用它时它不起作用。我不知道为什么我无法调用构造函数以及我缺少什么。

我已将@NonCPS放在上面的 test.groovy 方法上,但仍然无法正常工作。

//MyTest.groovy
package com.mycompany

class MyTest implements Serializable {
    public _notification

    MyTest(Closure content) {
        notification = [:]
        content.resolveStrategy = Closure.DELEGATE_FIRST
        content.delegate = notification
        content()
        println("Entered Constructor")
        this._notification = notification
    }

}

//test.groovy
import com.mycopany.MyTest
def notify(Closure content) {
    println("This is line i am getting in the output but nothing after that")
    MyTest tester = new MyTest(content)
    println(tester._notification.colorcode)
} 

//Jenkinsfile
@library("MysharedLibrary@master") _
pipeline{
    stages {
         stage {
             steps {
                 test.notify {
                      buildno = 12
                      jobname = "Mytest"
                      colorcode = "Blue"
                 }
             }
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

在这里我只想从 jenkins 文件调用构造函数并在我的 vars/test.groovy 中打印输入值的值。

EDIT1:当我在方法“def nofity”上方使用@NonCPS 时,我的构建成功了,但除了notify 方法第一行中的print 语句外,我什么也没得到。

如果我不使用@NonCPS,我将收到以下异常

Error when executing always post condition:
com.cloudbees.groovy.cps.impl.CpsCallableInvocation

hudson.remoting.ProxyException:com.cloudbees.groovy.cps.impl.CpsCallableInvocation
Finished: FAILURE
Run Code Online (Sandbox Code Playgroud)

Szy*_*iak 3

您看到此错误是因为您在构造函数内调用闭包。相反,您应该将其提取到单独的方法中。构造函数应该用于使用初始化期间传递的值来初始化对象。例如,常见的做法是将引用传递给WorkflowScript对象,因此您可以使用管道步骤,例如echo.

请考虑对共享库代码进行以下更改:

src/com/mycompany/MyTest.groovy

package com.mycompany

class MyTest {
  final Map notification = [:]
  final Script script

  MyTest(Script script) {
    this.script = script
  }

  def notify(Closure content) {
    processContent(content)
    script.echo "Notification processed = ${notification}"
  }

  def processContent(Closure content) {
    content.resolveStrategy = Closure.DELEGATE_FIRST
    content.delegate = notification
    content()
  }
}
Run Code Online (Sandbox Code Playgroud)

变量/test.groovy

import com.mycompany.MyTest
import groovy.transform.Field

@Field
final MyTest tester = new MyTest(this)

def notify(Closure content) {
    println("This is line i am getting in the output but nothing after that")
    tester.notify(content)
    println(tester.notification.colorcode)
}
Run Code Online (Sandbox Code Playgroud)

詹金斯文件

pipeline {
    agent any

    stages {
         stage("Test") {
             steps {
                 script {
                     test.notify {
                          buildno = 12
                          jobname = "Mytest"
                          colorcode = "Blue"
                     }
                 }
             }
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

[Pipeline] Start of Pipeline
[Pipeline] node
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Test)
[Pipeline] script
[Pipeline] {
[Pipeline] echo
This is line i am getting in the output but nothing after that
[Pipeline] echo
Notification processed = [buildno:12, jobname:Mytest, colorcode:Blue]
[Pipeline] echo
Blue
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Run Code Online (Sandbox Code Playgroud)

请记住,这只是重构共享管道库代码的一种方法。您的主要目标应该是从类构造函数内部移动闭包调用。由您决定将其放置在哪里,以便它最适合您。