脚本化管道:包装阶段

Mat*_*sdm 2 groovy jenkins jenkins-pipeline

我希望能够在 Jenkins 中包装一个“阶段”,这样我就可以在阶段的开始和结束时执行自定义代码,例如:

myStage('foo') {
}
Run Code Online (Sandbox Code Playgroud)

我想我可以通过使用元类来做到这一点:

           //Wrap stages to automatically trace
           def originalMethod = this.metaClass.getMetaMethod("stage", null)
           this.metaClass.myStage = { args ->
                   println "Beginning of stage"
                   println "Args: " + args
                   def result = originalMethod.invoke(delegate, args)
                   println "End of stage"
                   return result
           }
Run Code Online (Sandbox Code Playgroud)

但看起来 Groovy 脚本本身是一个 Binding,它没有元类:

groovy.lang.MissingPropertyException: No such property: metaClass for class: groovy.lang.Binding
Run Code Online (Sandbox Code Playgroud)

我仍在学习 Groovy 和 Jenkins Pipeline 的工作原理,所以也许我只是错过了一些东西。

Vas*_*kka 5

我不熟悉元类概念,但我认为解决您的问题的一个简单方法是将包装阶段定义为函数。以下是如何定义此类函数的示例:

def wrappedStage(name, Closure closure) {
    stage(name) {
        echo "Beginning of stage"
        def result = closure.call()
        echo "End of stage"
        return result
    }
}
Run Code Online (Sandbox Code Playgroud)

这就是你如何称呼它:

wrappedStage('myStage') {
    echo 'hi'
}
Run Code Online (Sandbox Code Playgroud)

wrappedStage仅当舞台主体实际返回某些内容时,的返回值才有意义,例如:

  1. 如果你调用另一个工作,例如:

    wrappedStage('myStage') {
        build job: 'myJob'
    }
    
    Run Code Online (Sandbox Code Playgroud)

    您将得到返回值org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper,您可以使用它来访问您运行的作业的信息,例如结果、变量等

  2. 如果您在控制台上打印一些内容,例如:

    wrappedStage('myStage') {
        echo 'hi'
    }
    
    Run Code Online (Sandbox Code Playgroud)

    你会回来的null

请注意,在我的示例中,我没有打印 args,因为根据我的理解stage,它只需要 2 个参数;阶段名称和它应该运行的闭包。阶段的名称已经打印在日志中,我不知道打印你要执行的代码会获得多少价值,但如果这是你想做的事情,请看看这个

如果您对想要包装的内容有更具体的情况,您可以向包装器添加更多参数,并通过这些额外参数打印您想要的所有信息。