【问题标题】:Jenkins Shared Library instantiate util class and use in workflowscriptJenkins 共享库实例化 util 类并在工作流脚本中使用
【发布时间】:2017-07-06 08:20:15
【问题描述】:

我正在创建自己的 Jenkins 共享库以在管道之间重用一些代码。我知道如何创建步骤(确实很容易),但是当我想在 jenkinsfile(或 Jenkins 在日志中所说的 WorkflowScript)中访问我的“utils 类”时遇到了问题。 我将“Util 类”称为位于文件夹 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'
        }
    }

}

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

node("mynode"){
   console.log("Hello World!")
} 

这个想法是避免在所有脚本中实例化控制台并使其自动生成,我尝试了几种类似

# vars/library.groovy

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

@Field String console = new Console() 

# vars/library.groovy

import my.domain.group.Console

def load(){
    this.console = new Console() 
    // And also
    console = new Console()
}

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

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

谢谢!

【问题讨论】:

    标签: jenkins groovy shared-libraries jenkins-pipeline


    【解决方案1】:

    看起来您在 Jenkinsfile 中错误地使用了 vars 脚本,但我会尝试解决一些困惑 :)

    1. vars 目录中定义的 Groovy 脚本在 Jenkinsfile 中通过其文件名作为“自定义”步骤调用。假设您的脚本名称保持为library.groovy,您的 Jenkinsfile 应该如下所示

      node ("mynode") {
           library("Hello World!")
      } 
      

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

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

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

      call 函数中,您可以像在 Jenkinsfile 中一样使用所有基本的 Jenkins 步骤(shbat 等),以及通过 import 导入的任何 Groovy/Java 类(如您的 @ 987654339@类)。

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

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

      不起作用,因为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'
               }
           }
      }
      

    这应该可以正常工作。

    您应该考虑在vars 中重命名您的library.groovy(例如myLog.groovy)。那么你的 Jenkinsfile 可能看起来像这样

    node ("mynode") {
        myLog "Hello World!"
    }
    

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

    node ("mynode") {
        myLog "Hello World!"
        myWarning "Hello World!"
        myError "Hello World!"
        mySuccess "Hello World!"
    }
    

    (我使用 my 前缀来避免与现有 Jenkins 步骤的名称冲突。例如,error 步骤已经存在,在您的 Jenkinsfile 中调用它会取消您的构建)

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

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

    让 Jenkins 和流水线工作可能会很麻烦,但最终还是值得的。我希望这面文字墙能有所帮助。祝你好运,编码愉快:)

    【讨论】:

    • 感谢您回复阿德里安!我知道如何使用这些步骤,但我忘了把这段代码放在我的例子中对不起:-)。阅读您的答案,我是否可以理解我无法公开要直接在 Jenkins 管道中使用的类的实例?我知道在控制台中为我的每个方法创建不同步骤的选项,但我认为直接从 vars 公开控制台实例更清楚(我不知道这是否可能)然后在 Jenkins 文件中使用它直接就像我在我的例子中展示的那样。
    • 你完全可以不用vars 中的library.groovy 脚本,直接在你的Jenkinsfile 中使用Console 类。只需确保通过@Library('[LIB_NAME]') _ 导入您的共享库,其中[LIB_NAME] 是您在Jenkins 设置中指定的库的名称,而您的班级通过import my.domain.util.Console 从您的Jenkinsfile 中导入。
    • step-as-a-variable 记录在哪里,我的意思是在“官方”Jenkins Pipeline 文档中?
    • @6cef 对steps变量有更详细的解释here
    猜你喜欢
    • 2023-04-10
    • 2018-08-02
    • 2018-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多