Jenkinsfile pipeline.environment 值从 env.getEnvironment() 中排除

Jenkinsfile pipeline.environment values excluded from env.getEnvironment()

(edited/updated 来自原始 post 以尝试解决对问题是什么的困惑)

问题是: Jenkinsfile environment 部分中设置的值未添加到对象 returned通过 env.getEnvironment()

问题是:如何获得完整环境的地图,包括在环境部分分配的值?因为 env.getEnvironment() 不会那样做。

Jenkins 文件示例:

pipeline {
    agent any
    environment {
        // this is not included in env.getEnvironment()
        ONE = '1'
    }
    stages {
        stage('Init') {
            steps {
                script {
                    // this is included in env.getEnvironment()
                    env['TWO'] = '2'
                }
            }
        }
        stage('Test') {
            steps {
                script {
                    // get env values as a map (for passing to groovy methods)
                    def envObject = env.getEnvironment()
                    
                    // see what env.getEnvironment() looks like
                    // notice ONE is not present in the output, but TWO is
                    // ONE is set using ONE = '1' in the environment section above
                    // TWO is set using env['TWO'] = '2' in the Init stage above
                    println envObject.toString()
                    
                    // for good measure loop through the env.getEnvironment() map
                    // and print any value(s) named ONE or TWO
                    // only TWO: 2 is output
                    envObject.each { k,v ->
                        if (k == 'ONE' || k == 'TWO') {
                            println "${k}: ${v}"
                        }
                    }
                    
                    // now show that both ONE and TWO are indeed in the environment
                    // by shelling out and using the env linux command
                    // this outputs ONE=1 and TWO=2
                    sh 'env | grep -E "ONE|TWO"'
                }
            }
        }
    }
}

输出(envObject.toString() 的输出缩短为 ... 除了相关部分):

[Pipeline] {
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Init)
[Pipeline] script
[Pipeline] {
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Test)
[Pipeline] script
[Pipeline] {
[Pipeline] echo
[..., TWO:2]
[Pipeline] echo
TWO: 2
[Pipeline] sh
+ env
+ grep -E ONE|TWO
ONE=1
TWO=2
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline

请注意 env.getEnvironment() 对象中缺少一个,但存在两个。

另请注意,ONE 和 TWO 都是在实际环境中设置的 ,我不是在询问如何访问环境或如何遍历值 return由 env.getEnvironment() 编辑。问题是 env.getEnvironment() 没有 return 环境中的所有值,它排除了在 Jenkinsfile 的 environment 部分中设置的任何值。

env.getEnvironment() 方法的输出不会 return 列表或地图,因此很难用 each 进行迭代,但您可以采取一些解决方法来完成这项工作。

import groovy.json.JsonSlurper
pipeline {
    agent any;
    environment { 
        ONE = 1
        TWO = 2
    }
    stages {
        stage('debug') {
            steps {
                script {
                    def jsonSlurper = new JsonSlurper()
                    def object = jsonSlurper.parseText(env.getEnvironment().toString())
                    assert object instanceof Map 
                    
                    object.each { k,v ->
                        echo "Key: ${k}, Value: ${v}"
                    } 
                }
            }
        }
    }
}

注意 - env.getEnvironment().toString() 会给你一个 JSON String 。在解析 JOSN 字符串时,如果 groovy jsonSlurper.parseText 发现任何特殊字符,它将通过错误

您还可以围绕 env Jenkins API 进行一些探索,找到一个合适的方法 return 地图或列表,以便您可以使用 each

我会获取环境并借助属性将其转换为地图

pipeline {
agent any
environment {
    // this is not included in env.getEnvironment()
    ONE = '1'
}
stages {
    stage('Init') {
        steps {
            script {
                // this is included in env.getEnvironment()
                env['TWO'] = '2'
            }
        }
    }
    stage('Test') {
        steps {
            script {
            

                 def envProp = readProperties text: sh (script: "env", returnStdout: true).trim()
                 Map envMapFromProp = envProp as Map
                 echo "ONE=${envMapFromProp.ONE}\nTWO=${envMapFromProp.TWO}"


                // now show that both ONE and TWO are indeed in the environment
                // by shelling out and using the env linux command
                // this outputs ONE=1 and TWO=2
                sh 'env | grep -E "ONE|TWO"'
            }
        }
    }
}
}

我没有给你“为什么”的答案,但你可以通过 readProperties 步骤解析 env 的输出来作弊并获得地图。

def envMap = readProperties(text: sh(script: 'env', returnStdout: true))
println(envMap.getClass())
println("${envMap}")