我有一个 Jenkins 自由式项目,其参数化构建可以在大量步骤中设置变量。对于一个简单的示例,“版本”设置为“1.0.0-prerelease”,可以在稍后的“执行 Windows 批处理命令”步骤中用作
%Version%
或在其他一些步骤中用作 $Version
。
其中一个源文件(特别是 MSBuild XML props 文件)也包含此值,因此我不想更新 Jenkins 项目构建,而是想从 XML 文件中读取此值。
我尝试使用带有脚本的 Environment Injector 插件,但是它似乎在主 Jenkins 服务器上运行,而不是构建服务器上,因此无法访问签出的源文件。
Build Environment -> Inject environment variables to the build process -> Groovy script
def text= new File("$WORKSPACE\\Example.props").text
def xml= new XmlSlurper().parseText(text)
def map = [:]
map["Version"] = xml.PropertyGroup.Version
return map
[EnvInject] - Executing scripts and injecting environment variables after the SCM step.
[EnvInject] - Evaluating the Groovy script content
[EnvInject] - [ERROR] - Problems occurs on injecting env vars defined in the build wrapper: org.jenkinsci.lib.envinject.EnvInjectException: Failed to evaluate the script. java.io.FileNotFoundException: C:\jenkins\workspace\test\Example.props (The system cannot find the path specified). See system log for more info
是否有某种方法可以在构建节点上运行脚本或以其他方式从源签出中读取文件?
此时,我试图避免重写所有项目(例如,使用管道,或者拥有一个独立的“构建脚本”来完成所有操作,而不是许多自由式步骤)。
您的问题确实是这样一个事实:当您尝试访问代理工作区上的路径(当然主节点上不存在)时,Groovy 系统脚本将始终在 Jenkins 主节点上运行。
一种解决方案是使用 FilePath 类而不是
File
:
公共最终类 FilePath
与 File 不同,FilePath 始终表示当前计算机上的文件路径,而 FilePath 表示特定代理或控制器上的文件路径。尽管如此,FilePath 的使用方式与 File 非常相似。
它公开了一堆操作(我们应该添加更多操作,只要它们通常有用),并且当针对远程节点上的文件调用时,FilePath 会远程执行必要的代码,从而提供半透明的文件操作。
使用此类可以让您访问代理工作区上的远程文件。
您可以尝试以下操作:
// Initiate the Remote Path
def remotePath = new FilePath(build.workspace, 'Example.props')
// Read the file and parse it
def xml= new XmlSlurper().parseText(remotePath.readToString())
def map = [:]
map["Version"] = xml.PropertyGroup.Version
return map