Jenkins共享库实例化util类并在workflowscript中使用

jol*_*iva 3 groovy shared-libraries jenkins jenkins-pipeline

我正在创建自己的Jenkins共享库,以便在管道之间重用一些代码.我知道如何创建步骤(确实很容易)但是当我想在jenkins文件中使用我的"utils类"(或者像Jenkins在日志中所说的WorkflowScript中)时,我遇到了问题.我将"Util class"称为位于文件夹src/my/domain/...中的groovy类,它有很多方法,例如,我想创建一个这样的日志类:

# src/my/domain/group

package my.domain.group

class Console implements Serializable {

    def log(msg) {
        spit(msg, '\033[34m')
    }

    def error(msg) {
        spit(msg, '\033[31m')
    }

    def warning(msg){
        spit(msg, '\033[33m')
    }

    def success(msg){
        spit(msg, '\033[32m')
    }

    private def spit(msg, color){
        ansiColor('xterm') {
            echo color + msg + '\033[0m'
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

然后我尝试在/vars/library.groovy中的文件中实例化,因此可以使用一些代码从Jenkinsfile访问,例如:

node("mynode"){
   console.log("Hello World!")
} 
Run Code Online (Sandbox Code Playgroud)

我的想法是避免在所有脚本中实例化控制台并自动生成,我尝试过几样的事情

# vars/library.groovy

import my.domain.group.Console
import groovy.transform.Field

@Field String console = new Console() 
Run Code Online (Sandbox Code Playgroud)

要么

# vars/library.groovy

import my.domain.group.Console

def load(){
    this.console = new Console() 
    // And also
    console = new Console()
}
Run Code Online (Sandbox Code Playgroud)

但是当试图从jenkins文件访问时,我总是得到错误:groovy.lang.MissingPropertyException:没有这样的属性:类的控制台:WorkflowScript

我理解这意味着实例不在正确的范围内,因此脚本无法直接看到,但我该怎么做?

谢谢!

Adr*_*per 10

看起来你vars在Jenkins文件中错误地使用了你的脚本,但我会尝试解决一些混淆:)

  1. vars目录中定义的Groovy脚本的文件名称为Jenkinsfile中的"自定义"步骤.假设您的脚本名称保留library.groovy,您的Jenkins文件应如下所示

    node ("mynode") {
         library("Hello World!")
    } 
    
    Run Code Online (Sandbox Code Playgroud)

    或者(因为括号是可选的)

    node ("mynode") {
         library "Hello World!"
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 此外,vars脚本应仅包含一个名为call必需的导入函数.由于您希望将日志消息作为字符串传递,因此该call函数还需要一个参数.所以你的library.groovy脚本vars可能看起来像这样

    # vars/library.groovy
    
    import my.domain.group.Console
    
    def call(msg){
        Console console = new Console(steps) 
        console.log(msg)
    }
    
    Run Code Online (Sandbox Code Playgroud)

    call函数内部,您可以使用Jenkins文件中的所有基本Jenkins步骤(sh,bat等),以及通过import(如您的Console类)导入的任何Groovy/Java类.

    您可能已经注意到,我还向类steps的构造函数添加了一个变量(不必手动声明或实例化)Console.这是必要的,因为您无法直接在src目录中定义的任何类中使用任何Jenkins步骤.结果,方法

    private def spit(msg, color){           
        ansiColor('xterm') {
            echo color + msg + '\033[0m'
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    不会起作用,因为echo是Jenkins的一步.为了echo在类中使用,可以将steps变量传递给构造函数并将其存储在类中的另一个变量中.然后你可以调用所有Jenkins的步骤steps.echo "Hello World"

    # src/my/domain/group
    
    package my.domain.group
    
    class Console implements Serializable {
    
         def steps
    
         Console(steps) {
             this.steps = steps
         }
    
         def log(msg) {
             spit(msg, '\033[34m')
         }
    
         def error(msg) {
             spit(msg, '\033[31m')
         }
    
         def warning(msg){
             spit(msg, '\033[33m')
         }
    
         def success(msg){
             spit(msg, '\033[32m')
         }
    
         private def spit(msg, color){
             ansiColor('xterm') {
                 steps.echo color + msg + '\033[0m'
             }
         }
    }
    
    Run Code Online (Sandbox Code Playgroud)

这应该使它工作.

你应该考虑重命名你的library.groovy内部vars(例如myLog.groovy).然后你的Jenkinsfile看起来像这样

node ("mynode") {
    myLog "Hello World!"
}
Run Code Online (Sandbox Code Playgroud)

为了使用您的Console类的其他方法,您可以在其中创建其他脚本vars.使用它们可能看起来像这样

node ("mynode") {
    myLog "Hello World!"
    myWarning "Hello World!"
    myError "Hello World!"
    mySuccess "Hello World!"
}
Run Code Online (Sandbox Code Playgroud)

(我使用my前缀来避免与已经存在的Jenkins步骤发生名称冲突.例如,该error步骤已存在并在Jenkinsfile中调用它将取消您的构建)

有关共享库的更多信息,请访问https://jenkins.io/doc/book/pipeline/shared-libraries/查看Jenkins文档.

您可以在https://jenkins.io/doc/pipeline/steps/workflow-basic-steps/找到所有基本Jenkins步骤的完整列表.

让詹金斯和管道工作可能是一个巨大的麻烦,但最终它是值得的.我希望这段文字能有所帮助.祝你好运,快乐编码:)