在 Jenkinsfile 中逐行读取文件 - groovy

Read file line by line in Jenkinsfile - groovy

我有一个简单的输入文件,每行有两个单词,并在 Jenkinsfile (groovy) 中进行解析,但看到一个问题,

pipeline {
  agent any
  stages {
    stage('Test-1') {
      steps {
        echo 'Building..'
        script {
          for (x in 1..5) {
            println x //0,1,2,3,4,5
          }
        }
      }
    }
    stage('Test-2 ') {
      steps {
      script {
        File file = new File("my_file.txt")
        def line, noOfLines = 0;
        file.withReader { reader ->
          while ((line = reader.readLine()) != null) {
            println "${line}"
            noOfLines++
          }
        }
      }
      }
    }
    stage('Test-3') {
      steps {
          script {
          def whole_file_data = readFile(file: 'my_file.txt')
            whole_file_data.eachLine { String line ->
              def (p1, p2) = line.tokenize()
              println("line:${line}")
              println("p1:${p1} & p2:${p2}")
            }
        }
      }
    }
  }
}

Test-1 可以很好地进行测试, Test-2 给我的错误是

Scripts not permitted to use new java.io.File java.lang.String. Administrators can decide whether to approve or reject this signature.

Test-3 阶段仅打印第一行并发出警告,

[Pipeline] readFile
expected to call java.lang.String.eachLine but wound up catching org.jenkinsci.plugins.workflow.cps.CpsClosure2.call; see: https://jenkins.io/redirect/pipeline-cps-method-mismatches/
line:1111 one
[Pipeline] echo

我的 Jenkins 版本是 Jenkins 2.249.1 是什么导致了问题? p1:1111 & p2:One

测试 1:

这是一个 shell 脚本迭代器。我不确定它与其他两个阶段的关系如何,但它很好。

测试 2:

这使用管道中的 File class 来读取文件系统上的文件。这有两个安全问题需要管理员批准挂起的沙箱模式启用,并且也只适用于问题中使用的 Jenkins master。事实上,您遇到了安全问题,出于所有这些原因,应该避免这种用法。

测试 3:

这在Pipeline中使用了readFile pipeline step方法。这是最佳实践,应该比测试 2 中的用法更受青睐。文件中的 String 内容被迭代,并以正确的用法打印该行。问题在于行:

def (p1, p2) = line.tokenize()

其中元组 (p1, p2)tokenize 分配给数组 return (并隐式重铸)。正如您在错误中看到的那样,此 lambda 迭代器作用域元组导致管道出现 Cps 问题。您可以通过在 script 块的末尾重新分配给 null 来解决此问题:

p1 = null
p2 = null

或者甚至不首先使用临时变量:

println("p1:${line.tokenize()[0]} & p2:${line.tokenize()[1]}")

然而,一种更安全的替代方法可能是遍历标记化的行,并在不使用换行符的情况下打印它以确保预期的格式。