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
相关产品推荐
相关产品推荐

