使用 Jenkinsfile/pipline 插件无法将 WORKSPACE 识别为目录

Unable to recognize WORKSPACE as directory using Jenkinsfile/pipline plugin

我正在尝试在目录中递归搜索文件,因此无法使用 findFiles。 我已经通过手动登录到从站看到了目录,但在下面的代码中无法识别。当我使用 isDirectory() 时它说 false 因此稍后在使用 dir.listFiles() 时它 return null.

代码如下:

def recursiveFileSearch(File dir, filename, filesPath) {

  File[] files = dir.listFiles() // It returns null here as it cannot recognize it as directory
  echo "$files" 
  for (int i=0; i < files.size(); i++) {
    if (files[i].isDirectory()) {
      recursiveFileSearch(files[i], filename, filesPath)
    } else {
      if (files[i].getAbsolutePath().contains(filename)) {
        filesPath.add(files[i].getAbsolutePath())
        return filesPath
      }
    }
  }
  return filesPath
}

node('maven') {
      git 'https://github.com/rupalibehera/t3d.git'
      sh 'mvn clean install'
      File currentDir = new File(pwd())

      def isdir = currentDir.isDirectory()
      println "isdir:${isdir}" // The output here is False
      def isexist = currentDir.exists()
      println "isexist:${isexist}" // The output here is False
      def canread = currentDir.canRead()
      println "canread:${canread}" // The output here is False
      def filesPath = []
      def openshiftYaml = recursiveFileSearch(currentDir, "openshift.yml", filesPath)
} 

我不确定这里出了什么问题。

但以下是一些观察结果:

任何 pointers/help 表示赞赏

我找到了答案, 要从 Jenkinsfile 搜索工作区中的任何文件,您可以使用 findFiles 步骤, 我确实尝试过这个,但我传递了不正确的 glob。现在我只是做 def files = findFiles(glob: '**/openshift.yml') \ it returns the path of file

通常,运行 sh 一步即可完成您需要的任何工作。你不能使用管道脚本中的java.io.File或类似的东西。它不会 运行 在代理上,而且也不安全,这就是为什么在沙盒模式保持开启(默认)时任何此类尝试都会被拒绝的原因。

您正在 运行 解决 Using File in Pipeline Description 问题。我太了解了。文件对象和 NIO 可以很好地分解路径,但它们的 isDirectory、exists 和其他方法 运行 在 master 上作为 Jenkinsfile 的一部分而不是在节点上。所以,所有在 master 上的使用看起来都很棒,因为文件在工作区中。在一个节点上全部使用,失败。

简而言之,不要那样做。使用 fileExists()pwd()、findFiles 等

如果您创建了一个 shareLibrary 并想在 Jenkins 之外的代码上使用单元测试,那么您可以创建一个依赖于脚本对象的门面('this' 来自管道)

Class 用于共享库

class PipelineUtils implements Serializable {
    static def pipelineScript = null;

    /**
     * Setup this fascade with access to pipeline script methods
     * @param jenkinsPipelineScript
     * @return
     */
    static initialize(def jenkinsPipelineScript) {
        pipelineScript = jenkinsPipelineScript
    }

    /**
     * Use pipelineScript object ('this' from pipeline) to access fileExists
     * We cannot use Java File objects for detection as the pipeline script runs on master and uses delegation/serialization to
     * get to the node.  So, File.exists() will be false if the file was generated on the node and that node isn't master.
     * https://support.cloudbees.com/hc/en-us/articles/230922128-Pipeline-Using-java-io-File-in-a-Pipeline-description
     * @param target
     * @return true if path exists
     */
    static boolean exists(Path target) {
        if (!pipelineScript) {
            throw new Exception("PipelineUtils.initialize with pipeline script not called - access to pipeline 'this' required for access to file detection routines")
        }

        if (! target.parent) {
            throw new Exception('Please use absolutePaths with ${env.WORKSPACE}/path-to-file')
        }
        return pipelineScript.fileExists(target.toAbsolutePath().toString())
    }

    /**
     * Convert workspace relative path to absolute path
     * @param path relative path
     * @return node specific absolute path
     */
    static def relativeWorkspaceToAbsolutePath(String path) {
        Path pwd = Paths.get(pipelineScript.pwd())
        return pwd.resolve(path).toAbsolutePath().toString()
    }

    static void echo(def message) {
        pipelineScript.echo(message)
    }
}

class 用于测试

class JenkinsStep { 静态布尔文件存在(定义路径){ return 新文件(路径).exists() }

static def pwd() {
    return System.getProperty("user.dir")
}

static def echo(def message) {
    println "${message}"
}

}

在詹金斯中的用法

PipelineUtils.initialize(this)
println PipelineUtils.exists(".")
// calls jenkins fileExists()

在单元测试中的使用

PipelineUtils.initialize(new JenkinsStep())
println PipelineUtils.exists(".")
// calls File.exists