在 Jenkins 管道中读取文件时获取文件未找到异常

Getting File not found exception on reading a file in Jenkins pipeline

文件位于 Linux 工作节点上的 /opt/apps/workspace/build32/target/site/result.html。该版本位于 /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]"

输出:

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)

问题

您需要注意 运行 任何任意 Groovy(或 Java)代码总是在您的 Jenkins master 上执行,无论哪个工作节点执行您的代码管道。 Jenkins 流水线步骤是该规则的一个例外,它们在当前工作节点上执行。这就是为什么:

fileExists("/opt/apps/workspace/build32/target/site/result.html")

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

当你打电话时:

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

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

解决方案

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

def file = readFile(file: 'target/site/result.html')

请记住,readFile 步骤 returns 文件的内容作为单个 String,所以如果你想逐行处理它,你可能有做这样的事情:

def lines = readFile(file: 'target/site/result.html').readLines()

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