在 Jenkins 管道中读取文件时出现“文件未找到”异常

Nic*_*Man 2 groovy jenkins jenkins-groovy jenkins-pipeline

文件位于/opt/apps/workspace/build32/target/site/result.htmlLinux 工作节点上。构建在/opt/apps/workspace/build32文件夹下运行。下面是我正在使用的代码片段。

if (fileExists("/opt/apps/workspace/build32/target/site/result.html")) {
  echo "result.html file exist"
}
else {
  echo " File does not exist"
}
def file = new File("/opt/apps/workspace/build32/target/site/result.html").collect{it}
def index = file.findIndexOf{ it ==~ /.*Result.*/ }
echo "file[index]"
Run Code Online (Sandbox Code Playgroud)

输出:

Running in /opt/apps/workspace/build32. 
[pipeline] result.html file exist 
[pipeline] build status UNSTABLE build message there was an error on stage Test, result.html (No such file or directory)
Run Code Online (Sandbox Code Playgroud)

Szy*_*iak 7

问题

您需要注意,运行任何任意 Groovy(或 Java)代码始终会在 Jenkins master 上执行,无论哪个工作节点在管道中执行代码。Jenkins Pipeline 步骤是此规则的一个例外,它们在当前工作节点上执行。因此:

fileExists("/opt/apps/workspace/build32/target/site/result.html")
Run Code Online (Sandbox Code Playgroud)

打印预期输出,因为fileExists这是标准 Jenkins Pipeline 步骤,因此它在工作区中创建文件的工作节点上执行。值得一提的是,管道步骤可以在steps { }块内或在块内使用script { }声明性管道的块内使用,或者直接在脚本化管道代码中使用。

你打电话时:

def file = new File("/opt/apps/workspace/build32/target/site/result.html").collect{it}
Run Code Online (Sandbox Code Playgroud)

您收到错误是因为new File(...)在 Jenkins 主节点上执行,并且其工作区不包含在工作节点的工作区中创建的文件。

解决方案

readFile您可以使用管道步骤,而不是执行任意 Groovy 代码- 该步骤将使用当前工作节点及其工作区读取文件。您可以使用相对路径访问工作区中的文件,因此类似这样的内容应该读取文件的内容:

def file = readFile(file: 'target/site/result.html')
Run Code Online (Sandbox Code Playgroud)

请记住,该readFile步骤将文件的内容作为单个返回String,因此如果您想逐行处理它,您可能必须执行以下操作:

def lines = readFile(file: 'target/site/result.html').readLines()
Run Code Online (Sandbox Code Playgroud)

以下代码将从List<String>文件中生成一行。根据您的 Jenkins 配置,该String.readLines()方法可能需要先列入白名单,然后才能在 Jenkins 管道代码中使用它。