你如何加载一个groovy文件并执行它
Posted
技术标签:
【中文标题】你如何加载一个groovy文件并执行它【英文标题】:How do you load a groovy file and execute it 【发布时间】:2016-10-14 11:43:22 【问题描述】:我有一个 jenkinsfile 放到我的项目的根目录中,并且想为我的管道拉入一个 groovy 文件并执行它。我能够让它工作的唯一方法是创建一个单独的项目并使用fileLoader.fromGit
命令。我想做
def pipeline = load 'groovy-file-name.groovy'
pipeline.pipeline()
【问题讨论】:
【参考方案1】:如果您的 Jenkinsfile
和 groovy 文件在一个存储库中,并且 Jenkinsfile
是从 SCM 加载的,您必须这样做:
Example.Groovy
def exampleMethod()
//do something
def otherExampleMethod()
//do something else
return this
JenkinsFile
node
def rootDir = pwd()
def exampleModule = load "$rootDir@script/Example.Groovy "
exampleModule.exampleMethod()
exampleModule.otherExampleMethod()
【讨论】:
读者,请注意,在 Groovy 中,“return this”至关重要。 @anton 同时我找到了.&
运算符(例如:def exampleMethod = example.&exampleMethod
。效果很好......
@MichaelEaster 'this' 究竟返回了什么?如果那是 gradle 脚本,它将返回一个 Project 类的实例作为绑定。但在一个普通的 groovy 文件中,我想不通。
@AntonShishkin ,$rootDir
变量是什么,它在哪里/如何设置?它是詹金斯固有的还是习惯的?我收到groovy.lang.MissingPropertyException: No such property: rootDir for class: groovy.lang.Binding
。
所以,我发现了一个警告——当运行同一作业的 2 个并发实例时,Jenkins 会将 @2
附加到工作区名称......但是,@987654330 并非如此@ 目录,这意味着 $workspace@script/Example.Groovy
在运行并发构建时将不起作用。【参考方案2】:
如果您的管道可以加载多个 groovy 文件,并且这些 groovy 文件也会在它们之间共享内容:
JenkinsFile.groovy
def modules = [:]
pipeline
agent any
stages
stage('test')
steps
script
modules.first = load "first.groovy"
modules.second = load "second.groovy"
modules.second.init(modules.first)
modules.first.test1()
modules.second.test2()
first.groovy
def test1()
//add code for this method
def test2()
//add code for this method
return this
second.groovy
import groovy.transform.Field
@Field private First = null
def init(first)
First = first
def test1()
//add code for this method
def test2()
First.test2()
return this
【讨论】:
可能会返回一些不一样的返回 this - 例如返回“This”?【参考方案3】:在执行load
之前,您必须执行checkout scm
(或从SCM 签出代码的其他方式)。
【讨论】:
这假定要加载的文件在 SCM 中。 你是对的,如果文件在 SCM 中,那么你需要在尝试加载之前从那里获取它。但是,如果库文件与主 jenkinsfile 位于同一个 repo 中,那么如果管道配置为自动提取 repo,则不必调用 checkout;在作业配置中。【参考方案4】:感谢@anton 和@Krzysztof Krasori,如果我将checkout scm
和确切的源文件结合起来效果很好
Example.Groovy
def exampleMethod()
println("exampleMethod")
def otherExampleMethod()
println("otherExampleMethod")
return this
JenkinsFile
node
// Git checkout before load source the file
checkout scm
// To know files are checked out or not
sh '''
ls -lhrt
'''
def rootDir = pwd()
println("Current Directory: " + rootDir)
// point to exact source file
def example = load "$rootDir/Example.Groovy"
example.exampleMethod()
example.otherExampleMethod()
【讨论】:
这是我需要让来自 SCM 的 Jenkins 管道工作的东西,现在我将所有常量和函数集中到一个公共的 Jenkinsfile.common.Groovy 中,在我的发布管道和我的集成之间共享测试管道。 jenkins.io/doc/pipeline/steps/workflow-cps/…【参考方案5】:非常有用的帖子,遇到了同样的问题,跟着你解决了。
我的问题是:Jenkinsfile
-> 打电话给first.groovy
-> 打电话给second.groovy
这是我的解决方案:
Jenkinsfile
node
checkout scm
//other commands if you have
def runner = load pwd() + '/first.groovy'
runner.whateverMethod(arg1,arg2)
first.groovy
def first.groovy(arg1,arg2)
//whatever others commands
def caller = load pwd() + '/second.groovy'
caller.otherMethod(arg1,arg2)
注意:参数是可选的,如果有,请添加或留空。
希望这可以进一步帮助。
【讨论】:
快速提醒一下,load() 仅在 node() 中有效。第二个 load() 有效,因为在 node() 中调用了whateverMethod()。以上是关于你如何加载一个groovy文件并执行它的主要内容,如果未能解决你的问题,请参考以下文章