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

Jenkins Pipeline编译报错:WorkflowScript第65行存在多余大括号

问题描述

在Docker环境运行Jenkins Pipeline构建两个镜像时,每次执行都报错:WorkflowScript: 65: unexpected token: },但本地Jenkinsfile仅63行,不存在第65行。尝试过多个Jenkinsfile版本,添加错误提示、echo语句及调试步骤后仍出现相同错误,且echo语句从未执行,怀疑问题出在Jenkinsfile之外。

报错日志

Started by user Elias Spycher

Checking out git https://github.com/Raisybear/cards_against_humanity into /var/jenkins_home/workspace/cards_against_humanity_pipeline@script/e46138fc9cf8660b857590cb378b6696fff12b52d585f68b61e8f5072062f6a5 to read Jenkinsfile
The recommended git tool is: NONE
No credentials specified
 > git rev-parse --resolve-git-dir /var/jenkins_home/workspace/cards_against_humanity_pipeline@script/e46138fc9cf8660b857590cb378b6696fff12b52d585f68b61e8f5072062f6a5/.git # timeout=10
Fetching changes from the remote Git repository
 > git config remote.origin.url https://github.com/Raisybear/cards_against_humanity # timeout=10
Fetching upstream changes from https://github.com/Raisybear/cards_against_humanity
 > git --version # timeout=10
 > git --version # 'git version 2.39.5'
 > git fetch --tags --force --progress -- https://github.com/Raisybear/cards_against_humanity +refs/heads/*:refs/remotes/origin/* # timeout=10
 > git rev-parse refs/remotes/origin/main^{commit} # timeout=10
Checking out Revision 6dbd5f7a38d90da89675e6bc38f19f33c7f4c92a (refs/remotes/origin/main)
 > git config core.sparsecheckout # timeout=10
 > git checkout -f 6dbd5f7a38d90da89675e6bc38f19f33c7f4c92a # timeout=10
Commit message: "Update Jenkinsfile"
 > git rev-list --no-walk 6dbd5f7a38d90da89675e6bc38f19f33c7f4c92a # timeout=10
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 65: unexpected token: } @ line 65, column 1.
   }
   ^

1 error

    at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:309)
    at org.codehaus.groovy.control.ErrorCollector.addFatalError(ErrorCollector.java:149)
    at org.codehaus.groovy.control.ErrorCollector.addError(ErrorCollector.java:119)
    at org.codehaus.groovy.control.ErrorCollector.addError(ErrorCollector.java:131)
    at org.codehaus.groovy.control.SourceUnit.addError(SourceUnit.java:349)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.transformCSTIntoAST(AntlrParserPlugin.java:225)
    at org.codehaus.groovy.antlr.AntlrParserPlugin.parseCST(AntlrParserPlugin.java:191)
    at org.codehaus.groovy.control.SourceUnit.parse(SourceUnit.java:233)
    at org.codehaus.groovy.control.CompilationUnit$1.call(CompilationUnit.java:189)
    at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:966)
    at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:626)
    at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:602)
    at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:579)
    at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:323)
    at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:293)
    at PluginClassLoader for script-security//org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox$Scope.parse(GroovySandbox.java:163)
    at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.doParse(CpsGroovyShell.java:190)
    at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.reparse(CpsGroovyShell.java:175)
    at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.parseScript(CpsFlowExecution.java:652)
    at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.start(CpsFlowExecution.java:598)
    at PluginClassLoader for workflow-job//org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:335)
    at hudson.model.ResourceController.execute(ResourceController.java:101)
    at hudson.model.Executor.run(Executor.java:446)
Finished: FAILURE

本地Jenkinsfile内容

pipeline {
    agent any

    environment {
        BACKEND_IMAGE = "backend_image"
        FRONTEND_IMAGE = "frontend_image"
    }

    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://github.com/Raisybear/cards_against_humanity'
            }
        }   
  
        stage('Backend Build') {
            steps {
                dir('Game/cards_against_humanity_backend') {
                    script {
                        sh 'docker build -t ${BACKEND_IMAGE} .'  // Baut das Docker-Image für das Backend.
                    }
                }
            }
        }

        stage('Frontend Build') {
            steps {
                dir('Game/cards_against_humanity_frontend') {
                    script {
                        sh 'docker build -t ${FRONTEND_IMAGE} .'  // Baut das Docker-Image für das Frontend.
                    }
                }
            }
        }

        stage('Run Tests') {
            steps {
                // Tests im Backend-Verzeichnis ausführen
                dir('Game/cards_against_humanity_backend') {
                    sh 'dotnet test'  // Führt die Backend-Tests aus.
                }
                // Tests im Frontend-Verzeichnis ausführen
                dir('Game/cards_against_humanity_frontend') {
                    sh 'npm install && npm test'  // Führt die Frontend-Tests aus.
                }
            }
        }

        stage('Deploy with Docker Compose') {
            steps {
                script {
                    sh 'docker-compose -f docker-compose.yml up -d'  // Startet die Container im Hintergrund.
                }
            }
        }
    }

    post {
        always {
            sh 'docker-compose -f docker-compose.yml down'  // Stoppt und entfernt die Container nach Abschluss der Pipeline.
        }
    }
}
排查与解决思路

1. 检查Jenkins脚本自动注入内容

Jenkins解析Jenkinsfile时,可能通过全局共享库、插件自动注入额外代码,导致实际编译的脚本行数超过本地文件:

  • 进入Jenkins全局配置,查看Global Pipeline Libraries,确认是否有自动加载的共享库,这类库可能在脚本前后添加代码。
  • 检查项目的Pipeline配置,是否启用了"Lightweight checkout"之外的选项,或存在其他脚本注入逻辑。

2. 清理Jenkins工作区与缓存

Jenkins可能缓存了旧版本脚本,导致解析时引用错误内容:

  • 手动删除项目工作区目录(示例路径:/var/jenkins_home/workspace/cards_against_humanity_pipeline),包括子目录@script。
  • 在Jenkins项目页面点击「Workspace」→「Delete workspace」,然后重新触发构建。

3. 检查Jenkinsfile的隐藏字符与编码

本地文件可能包含不可见换行符、Unicode空白字符,导致Jenkins解析时行数计算异常:

  • 使用命令cat -A Jenkinsfile查看文件隐藏字符,检查是否有^M、多余$或非标准字符。
  • 将Jenkinsfile复制到纯文本编辑器(如VS Code的「Plain Text」模式),以UTF-8编码重新保存后提交到仓库。

4. 修正Groovy语法细节

部分隐性语法问题可能触发解析错误:

  • 将sh命令的单引号改为双引号,因为单引号不会解析Groovy变量(原代码中${BACKEND_IMAGE}在单引号中会被当作字面量,而非环境变量):
    sh "docker build -t ${BACKEND_IMAGE} ."
    
  • 移除所有行尾注释,部分注释格式可能干扰Groovy解析逻辑。

5. 验证Jenkins插件兼容性

旧版本Pipeline核心插件可能存在解析bug:

  • 升级workflow-cps、workflow-job等核心Pipeline插件至最新稳定版。
  • 暂时禁用非必要的Pipeline相关插件,逐步排查是否存在插件冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 09:49:56