如何从 Jenkins 管道 Groovy 脚本调用资源文件中定义的 bash 函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40213654/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to invoke bash functions defined in a resource file from a Jenkins pipeline Groovy script?
提问by Ad N
We are using the Pipeline Shared Librariesplugin to factorize the code common to our different Jenkins pipelines.
我们正在使用管道共享库插件来分解我们不同 Jenkins 管道的通用代码。
From its documentation, it offers a resources
top-level folder for non-Groovy files. As we rely on different bash functions, we would like to host them in a separate .sh
file (thus they could also be used by other processes than Jenkins).
The same documentation tells us about using libraryResource
step to load those resource files. We can successfully call this method within our Groovy script, giving it our resource file name as argument (function.sh
). But from here, we were not able to find a way to invoke the foofoo
function defined in function.sh
from the same Groovy script.
从它的文档 中,它resources
为非 Groovy 文件提供了一个顶级文件夹。由于我们依赖于不同的 bash 函数,我们希望将它们托管在一个单独的.sh
文件中(因此它们也可以被 Jenkins 之外的其他进程使用)。相同的文档告诉我们如何使用libraryResource
step 加载这些资源文件。我们可以在 Groovy 脚本中成功调用此方法,将我们的资源文件名作为参数 ( function.sh
)。但是从这里开始,我们无法找到从同一个 Groovy 脚本调用 中foofoo
定义的函数的方法function.sh
。
sh "foofoo" #error: foofoo is not defined
We also tried to first source it like this:
我们还尝试像这样首先获取它:
sh "source function.sh && foofoo"
But it fails at the source
step, stating that function.sh
is not found.
但它在这source
一步失败,说明function.sh
没有找到。
What would be the correct procedure to invoke a bash function defined in function.sh
调用中定义的 bash 函数的正确过程是什么? function.sh
回答by Yuri G.
According to the documentation
根据文档
External libraries may load adjunct files from a resources/ directory using the libraryResource step. The argument is a relative pathname, akin to Java resource loading:
外部库可以使用 libraryResource 步骤从 resources/ 目录加载附属文件。参数是一个相对路径名,类似于 Java 资源加载:
def request = libraryResource 'com/mycorp/pipeline/somelib/request.json'
The file is loaded as a string, suitable for passing to certain APIs or saving to a workspace using writeFile.
It is advisable to use an unique package structure so you do not accidentally conflict with another library.
该文件作为字符串加载,适合传递给某些 API 或使用 writeFile 保存到工作区。
建议使用独特的包结构,以免意外与其他库发生冲突。
I assume the following will work
我认为以下将起作用
def functions = libraryResource 'com/mycorp/pipeline/somelib/functions.sh'
writeFile file: 'functions.sh', text: functions
sh "source function.sh && foofoo"
回答by anuj0901
Since you are using Jenkins Pipelines V2, it would be better for you to create a shared library for this. The code below will work. Along with writing the file, you will need to provide execute privilege to the file as well:
由于您使用的是 Jenkins Pipelines V2,因此最好为此创建一个共享库。下面的代码将起作用。除了写入文件,您还需要为文件提供执行权限:
def scriptContent = libraryResource "com/corp/pipeline/scripts/${scriptName}"
writeFile file: "${scriptName}", text: scriptContent
sh "chmod +x ${scriptName}"
Hope this helps!!
希望这可以帮助!!
回答by TurboElectricLtd
All the previous answers are poor solutions as the script is parsed as a text file when it is transferred which corrupts it.
所有以前的答案都是糟糕的解决方案,因为脚本在传输时被解析为文本文件,这会损坏它。
Quotes etc are messed up and it attempts to substitute variables.
报价等被弄乱了,它试图替换变量。
It needs to be transferred verbatim.
它需要逐字传输。
The only solutions are to store the script on a file server, download it and run it e.g.:
唯一的解决方案是将脚本存储在文件服务器上,下载并运行它,例如:
sh """
wget http://some server/path../yourscript.sh
chmod a+x yourscript.sh
"""
...or checkout the script from the repo directly and use it locally like this:
...或直接从 repo 签出脚本并在本地使用它,如下所示:
withCredentials([usernamePassword(
credentialsId: <git access credentials>,
usernameVariable: 'username',
passwordVariable: 'password'
)])
{
sh """
git clone http://$username:$password@<your git server>/<shared library repo>.git gittemp
cd gittemp
git checkout <the branch in the shared library>
cd ..
mv -vf gittemp/<path to file>/yourscript.sh ./
"""
}
...then later run your script:
...然后稍后运行您的脚本:
sh "./yourscript.sh ...."
回答by Gregory
Use bash shebang (#!/bin/bash) at the beginning of your sh step to tell Jenkins to use bash, and then load your lib like you would in bash, e.g.:
在 sh 步骤的开头使用 bash shebang (#!/bin/bash) 告诉 Jenkins 使用 bash,然后像在 bash 中一样加载你的库,例如:
sh '''#!/bin/bash
. path/to/shared_lib.bash
myfunc $myarg
'''
Mind the fact, that path/to/shared_lib.bash
has be checked in your repo in order for this to work.
请注意,这path/to/shared_lib.bash
已在您的回购中进行了检查以使其正常工作。