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

Jenkinsfile中Groovy创建JSON文件后Shell/Python无法访问问题

问题分析与解决

根本原因

你的Groovy方法加了@NonCPS注解,这会导致这段代码运行在Jenkins Master节点的JVM中,直接使用java.io.File类操作的是Master的文件系统。而后续的sh步骤如果是在Slave/Agent节点上执行的,WORKSPACE指向的是Agent的本地工作目录——两边的文件系统完全隔离,所以Shell自然找不到Master上创建的文件。

从日志也能佐证这点:Groovy返回的文件路径虽然和Shell的pwd输出一致,但实际是Master上的对应路径,和Agent的同名路径不是同一个位置。

解决方案

方案1:改用Jenkins Pipeline原生文件操作步骤(推荐)

去掉@NonCPS注解,使用Jenkins提供的writeFile、readFile步骤,这些步骤是CPS兼容的,会自动在当前执行的Agent节点上操作文件,无需关心节点差异。

修改后的datastore.groovy代码:

def set_var(String workspaceDir, String text) {
    def filePath = "${workspaceDir}/datastore.json"
    def data = [:]
    
    // 读取现有文件(如果存在)
    if (fileExists(filePath)) {
        def existingContent = readFile(filePath)
        data = new groovy.json.JsonSlurper().parseText(existingContent)
    }
    
    // 更新数据
    data["text"] = text
    def json = groovy.json.JsonOutput.toJson(data)
    
    // 写入文件
    writeFile(file: filePath, text: json)
    
    // 验证文件存在并返回信息
    def files = findFiles(glob: "${workspaceDir}/*").collect { it.name }.join("\n")
    return "Wrote text: ${text} to file: ${filePath}; files: ${files}"
}

方案2:确保Groovy代码与Shell步骤在同一节点执行

如果必须保留@NonCPS和java.io.File操作,要确保整个代码块都在同一个Agent节点上运行。可以通过node块指定Agent,让Groovy和Shell都在该节点执行:

修改Jenkinsfile:

stage {
    steps {
        node("your-agent-label") { // 指定你的Agent标签
            script {
                if (foo.bar()) {
                    echo "set_var: " + datastore.set_var(WORKSPACE, "meow")
                    sh(script: "pwd ; ls -l")
                }
            }
        }
    }
}

注意:这种方式需要确保Agent节点的文件系统能被Groovy的File类访问到,本质是让@NonCPS代码在Agent节点的JVM中执行(需要Agent是Java节点),否则仍会有问题。

验证要点

修改后重新运行Pipeline,检查:

  • Groovy返回的文件路径对应的是Agent节点的实际目录
  • Shell的ls输出能看到datastore.json文件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 03:26:00