You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jenkinsfile使用Groovy遍历文件系统时循环仅执行一次如何解决

问题原因
  • 核心问题是你在Pipeline中直接使用了Groovy原生的new File()和traverse方法:这类Java/Groovy原生的文件系统API,只会在Jenkins 主节点(master)的JVM进程中执行,而你克隆Git仓库、执行sh ls命令都是在agent节点的工作目录下操作的,主节点上不存在对应路径的文件,读取逻辑异常就会出现只遍历到第一个文件就终止的情况。
  • 次要问题:Groovy 2.4.x版本的traverse方法存在已知的闭包返回值判定bug,如果闭包内最后一行表达式的返回值为false,遍历会提前终止,你的代码逻辑也可能触发该问题。
修复方案

方案1:使用Jenkins官方推荐的findFiles步骤(首选)

该步骤属于Pipeline Utility Steps插件,绝大多数Jenkins环境默认预装,是专门用于在agent节点遍历工作区文件的官方API,不存在跨节点读取的问题,替换后的代码如下:

dir("${reposDir}/${projectTitle}/${projectName}") {
    sh "pwd"
    sh "ls -alF"

    echo "[INFO] Iterate project"
    // 递归遍历当前目录下所有类型的文件
    def allFiles = findFiles(glob: '**/*')
    allFiles.each { f ->
        println f.name
        println f.absolutePath

        if(f.name.endsWith('.sh')) {
            println "..."
            // 你的业务逻辑
        }
    }
}

方案2:通过sh命令输出遍历结果(无需额外插件)

如果你的Jenkins环境没有安装Pipeline Utility Steps插件,可以通过shell命令把遍历结果导出到Groovy变量中再处理:

dir("${reposDir}/${projectTitle}/${projectName}") {
    sh "pwd"
    sh "ls -alF"

    echo "[INFO] Iterate project"
    // 递归获取当前目录下所有文件的绝对路径,每行一个结果
    def allFilePaths = sh(
        script: "find \$(pwd) -type f",
        returnStdout: true
    ).trim().split('\n')
    
    allFilePaths.each { filePath ->
        def fileName = filePath.split('/')[-1]
        println fileName
        println filePath

        if(fileName.endsWith('.sh')) {
            println "..."
            // 你的业务逻辑
        }
    }
}
额外优化提示

你的并行stage代码存在逻辑错误:parallel branchedStages不应放在projects.each循环内部,否则每次循环只会执行单个项目的stage,无法实现多项目并行构建,需要把该语句移到循环外部。

内容的提问来源于stack exchange,提问作者Sebastian Sommerfeld

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 21:36:07