You need to enable JavaScript to run this app. Jenkins声明式流水线中如何在自定义函数内读取全局变量值
优惠活动
大模型
产品
解决方案
定价
更多

Jenkins声明式流水线中如何在自定义函数内读取全局变量值

问题根因

该报错本质是Jenkins流水线的Groovy作用域隔离导致的:

  • 在pipeline块外层用def FAILED_STAGE定义的变量,属于Groovy脚本的局部变量,不是WorkflowScript类的成员属性
  • 流水线执行到pipeline内部的script块时,CPS转换机制会将块内的变量赋值绑定到闭包的局部作用域,不会回写到外层脚本的局部变量
  • 等到post块调用自定义函数sendSlackNotifcation时,函数的作用域链中找不到这个局部变量,沙箱校验就会抛出groovy.lang.MissingPropertyException
解决方案

方案1:使用全局env环境变量存储(推荐)

Jenkins内置的env对象是跨所有流水线作用域全局共享的,不存在作用域隔离问题,是这类场景的首选实现方式。
具体修改点:

  • 删除顶层的def FAILED_STAGE定义
  • 自定义函数中读取env.FAILED_STAGE替代原变量
  • 失败阶段的script块中,将赋值语句改为写入env对象
    修改后可直接运行的完整代码:
def sendSlackNotifcation() 
{
    if ( currentBuild.currentResult == "SUCCESS" ) {
        slackSend message: "${currentBuild.result}", channel: '#jenkins_bot2'
    }
    else {
        slackSend color : "#FF0000", message: "流水线失败于阶段:${env.FAILED_STAGE}", channel: '#jenkins_bot2'
    }
}

pipeline {
    agent any

    stages {
        stage('stage1') {
            steps{
                echo "stage1"
            }
        }     
        
        stage('stage2') {
            steps{
                echo "stage2"
            }
        }
        
        stage("Stage 3") {
            steps {
                script {
                    // 将失败阶段信息写入全局env变量
                    env.FAILED_STAGE = env.STAGE_NAME
                    echo "${env.FAILED_STAGE}"
                    error "failed for some reason."
                }
            }
        }
    }
    post {
        failure {
            sendSlackNotifcation()
        }
    }
}

方案2:显式绑定类成员作用域

如果不希望使用env对象存储自定义变量,需要将变量从脚本局部变量改为WorkflowScript类的成员属性,赋值时明确指定作用域,避免被闭包截留。
具体修改点:

  • 顶层定义变量时去掉def,直接声明FAILED_STAGE = "",使其成为类的成员属性
  • pipeline内部给变量赋值时,用this.FAILED_STAGE显式绑定到类成员
    关键修改代码片段:
// 直接声明类成员属性,不用def关键字
FAILED_STAGE = ""

def sendSlackNotifcation() 
{
    if ( currentBuild.currentResult == "SUCCESS" ) {
        slackSend message: "${currentBuild.result}", channel: '#jenkins_bot2'
    }
    else {
        slackSend color : "#FF0000", message: "流水线失败于阶段:${FAILED_STAGE}", channel: '#jenkins_bot2'
    }
}

pipeline {
    agent any
    stages {
        // 其余阶段逻辑保持不变
        stage("Stage 3") {
            steps {
                script {
                    // 显式赋值给类成员属性,避免闭包作用域截留
                    this.FAILED_STAGE = env.STAGE_NAME
                    echo "${this.FAILED_STAGE}"
                    error "failed for some reason."
                }
            }
        }
    }
    post {
        failure {
            sendSlackNotifcation()
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.04 05:06:10