Jenkins流水线报错:WorkflowScript中stage块不符合0.5+版本格式要求
Jenkins流水线编译错误修复:Unknown stage section "stage"
错误信息
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: WorkflowScript: 19: Unknown stage section "stage". Starting with version 0.5, steps in a stage must be in a ‘steps’ block. @ line 19, column 5
问题根源
你的流水线代码违反了Jenkins Declarative Pipeline的核心语法规则:
stage不能直接嵌套在另一个stage下,必须通过stages块作为中间层级,stage只能是stages的直接子元素。- 原代码中在
stage('CI Build')内部直接定义了stage('GitCheckout'),同时错误地给stages块添加when条件(when是stage的专属子元素,不能作用于stages),导致编译失败。
修复后的完整代码
pipeline { agent none options { ansiColor('xterm') disableConcurrentBuilds() } parameters { string(name: 'GIT_BRANCH', defaultValue: "${params.GIT_BRANCH}", description: 'checkout branch') choice(name: 'ENVIRONMENT', choices: ['staging', 'production']) } stages { stage('CI Build') { agent { kubernetes { yamlFile("jenkins/ci.yaml") } } // 内部stages块管理所有子stage stages { stage('GitCheckout') { steps { script { updateGitlabCommitStatus name: 'jenkins', state: 'running' checkout changelog: false, poll: false, scm: [$class: 'GitSCM', branches: [[name: "${params.GIT_BRANCH}"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'LocalBranch', localBranch: "${params.GIT_BRANCH}"]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'wbfkjejkv86fnjdnfkgnde-341b26acc248', url: 'www@zzzz.yyyy.xx:xxx_xxxx/xxxxxxxx-xxxxxx.xxx']]] STAGING_IMAGE_TAG = sh(returnStdout: true, script: 'echo "$(git rev-parse HEAD)"').trim() } } } // Staging环境专属步骤,通过when条件控制执行 stage('Staging Deployment') { when { beforeAgent true expression { "${params.ENVIRONMENT}" == 'staging' } } stages { stage('Stage GitCheckout') { steps { script { updateGitlabCommitStatus name: 'jenkins', state: 'running' checkout changelog: false, poll: false, scm: [$class: 'GitSCM', branches: [[name: "${params.GIT_BRANCH}"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'LocalBranch', localBranch: "${params.GIT_BRANCH}"]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'a2836a86-51b2-4c73-af15-341b26acc248', url: 'zzz@yyyyyy.xxxx.yyy:xxxx_yyy/ffff-wwww.xxx']]] STAGING_IMAGE_TAG = sh(returnStdout: true, script: 'echo "$(git rev-parse HEAD)"').trim() } } } stage('Prepare Staging') { steps { container('node') { sh "npm install" sh "npm run test" sh "npm run build:stage" } } } stage('Prepare Staging Docker') { steps { script { STAGING_IMAGE_TAG="${STAGING_IMAGE_TAG}-${params.ENVIRONMENT}" dockerImage = docker.build("${GITLAB_REGISTRY_ENDPOINT}/feedback-app-ui:${STAGING_IMAGE_TAG}") docker.withRegistry( GITLAB_REGISTRY_URL, GITLAB_REGISTRY_CREDS ) { dockerImage.push() } } } } } } // Production环境专属步骤,通过when条件控制执行 stage('Production Deployment') { when { beforeAgent true expression { "${params.ENVIRONMENT}" == 'production' } } stages { stage('Prepare Production') { steps { container('node') { sh "npm install" sh "npm run test" sh "npm run build:prod" } } } stage('Prepare Production Docker') { steps { script { // 修复原代码未定义PROD_IMAGE_TAG的问题,复用之前的提交ID标签 PROD_IMAGE_TAG="${STAGING_IMAGE_TAG}-${params.ENVIRONMENT}" dockerImage = docker.build("${GITLAB_REGISTRY_ENDPOINT}/feedback-app-ui:${PROD_IMAGE_TAG}") docker.withRegistry( GITLAB_REGISTRY_URL, GITLAB_REGISTRY_CREDS ) { dockerImage.push() } } } } } } } post { always { script { notifyBuild(currentBuild.result, 'CI build status') } } failure { updateGitlabCommitStatus name: 'jenkins', state: 'failed' } success { updateGitlabCommitStatus name: 'jenkins', state: 'success' } } } } }
关键修改说明
- 层级修正:在
stage('CI Build')内部添加stages块,所有子stage都放在这个块下,符合Declarative Pipeline的语法要求。 - 条件逻辑调整:将原代码中针对不同环境的步骤,分别包裹在带
when条件的父stage中,通过参数判断是否执行该分支的步骤。 - 变量修复:修正了
PROD_IMAGE_TAG未定义的问题,复用之前获取的Git提交ID作为基础标签。 - 代码格式优化:调整了
docker.push()的缩进,确保代码块闭合正确,避免隐式语法错误。
内容的提问来源于stack exchange,提问作者ketan kanade
相关产品推荐
相关产品推荐

