¿Cómo enumerar todas las propiedades `env` dentro del trabajo de tubería de jenkins?

105

Dada una canalización de compilación de jenkins 2.1, jenkins inyecta una envvariable en node{}. Por ejemplo, BRANCH_NAMEse puede acceder con

node {
    echo ${env.BRANCH_NAME}
    ...

Quiero hacer eco de todas las env propiedades dentro de la tubería de jenkins.

... considerando que no conozco todas las propiedades de antemano.

Estoy buscando un código como

node {
    for(e in env){
        echo e + " is " + ${e}
    }
    ...

que se haría eco de algo como

 BRANCH_NAME is myBranch2
 CHANGE_ID is 44
 ...
JamesThomasMoon1979
fuente
env es un mapa. ¿Probaste la iteración normal? like - env.each {println it}
Jayan
3
Parece un duplicado de stackoverflow.com/questions/36836806/…
Krzysztof Krasoń
3
Afaik env simplemente encapsula las variables de entorno. No creo que puedas recorrerlo. Pruebe 'sh env' en linux / 'bat set' en Windows.
Dominik Gebhart
1
@Renato @Jayan según mi comentario a continuación, env.each { name, value -> println "Name: $name -> Value $value" }imprime Name: org.jenkinsci.plugins.workflow.cps.EnvActionImpl@45c2d1ee -> Value null.
JamesThomasMoon1979
1
@ JamesThomasMoon1979 Eso es porque Pipeline rompe los cierres Groovy. Si lo corrige al estilo antiguo de Java (es decir, new ClassName() { ... }), debería funcionar. O lo ejecuta en un método etiquetado @NonCPS, luego los cierres también funcionarán dentro de eso.
Daniel C. Sobral

Respuestas:

80

Según la documentación de Jenkins para la canalización declarativa :

sh 'printenv'

Para la canalización con guiones de Jenkins :

echo sh(script: 'env|sort', returnStdout: true)

Lo anterior también clasifica sus variables env por conveniencia.

Wimateeka
fuente
1
printenves solo un comando de shell que imprime el entorno, nada específico de Jenkins. Sin argumentos es equivalente a envsin argumentos. Estoy bastante seguro de sh 'printenv | sort'que funcionará en DCL o en una tubería con script.
simon.watts
Probado y sh 'printenv | sort'de hecho funciona para una tubería declarativa de Jenkins; fwiw sh 'env | sort'también funciona (Ambos probados en Jenkins ver. 2.46.1). Lo mencioné originalmente sh 'printenv'porque se mencionó en la documentación oficial de Jenkins.
Wimateeka
1
Si pierde el returnStdout: true, entonces no necesita el eco; Es solo imprimir lo que ya imprimió el script de shell.
Ed Randall
26

Los siguientes trabajos:

@NonCPS
def printParams() {
  env.getEnvironment().each { name, value -> println "Name: $name -> Value $value" }
}
printParams()

Tenga en cuenta que lo más probable es que falle en la primera ejecución y requiera que apruebe varios métodos maravillosos para ejecutar en jenkins sandbox. Esto se hace en "administrar jenkins / aprobación de script en proceso"

La lista que obtuve incluía:

  • BUILD_DISPLAY_NAME
  • BUILD_ID
  • BUILD_NUMBER
  • BUILD_TAG
  • BUILD_URL
  • CLASSPATH
  • HUDSON_HOME
  • HUDSON_SERVER_COOKIE
  • HUDSON_URL
  • JENKINS_HOME
  • JENKINS_SERVER_COOKIE
  • JENKINS_URL
  • JOB_BASE_NAME
  • NOMBRE DEL TRABAJO
  • JOB_URL
Omri Spector
fuente
1
Esto no funciona:java.lang.UnsupportedOperationException: each on a CPS-transformed closure is not yet supported
octavian
5
¿Te aseguraste de incluir el @NonCPS?
Joe C.
1
Esta es la mejor respuesta porque funcionará fuera de un bloque de nodos . Muchas gracias por esto.
Gi0rgi0s
15

Puede lograr el resultado usando sh/ batstep y readFile:

node {
    sh 'env > env.txt'
    readFile('env.txt').split("\r?\n").each {
        println it
    }
}

Desafortunadamente, env.getEnvironment()devuelve un mapa muy limitado de variables de entorno.

luka5z
fuente
1
sh 'env > env.txt'funciona bien e incluye variables de entorno creadas por el proceso de shell. env.getEnvironment()muestra solo las variables de entorno del conjunto de Jenkins, que son un subconjunto de las que se ven en la sh 'env'técnica. Además, necesita la aprobación de seguridad del script method org.jenkinsci.plugins.workflow.support.actions.EnvironmentAction getEnvironment. Lo env.each { name, value -> println "Name: $name -> Value $value" }recomendado por @Renato @Jayan solo imprime Name: org.jenkinsci.plugins.workflow.cps.EnvActionImpl@45c2d1ee -> Value null.
JamesThomasMoon1979
¡¡¡Agradable!!! Poder imprimir todas las variables env me ayudó a descubrir que Jenkins 2 establece una var JOB_BASE_NAME que contiene el nombre del trabajo sin la carpeta en la que reside.
Bill Agee
una versión que funcione en Windows también sería increíble :)
Bas Hamer
@Bas Hamer para una versión de Windows intente reemplazar "sh" por "bat"
Sebastien
2
Me da un error java.lang.UnsupportedOperationException: llamar al público estático java.lang.Object org.codehaus.groovy.runtime.DefaultGroovyMethods.each (java.lang.Object, groovy.lang.Closure) en un cierre transformado por CPS no es aún compatible (JENKINS-26481); encapsular en un método @NonCPS, o usar bucles de estilo Java
Ben Mathews
12

¿Por qué toda esta complicación?

sh 'env'

hace lo que necesita (bajo * nix)

Andrey Regentov
fuente
Esto requiere un bloque de nodo para ejecutarse. Para mi caso de uso, necesito procesar qué entorno tendrá el nodo y luego activar un nodo en función de ciertos criterios.
Bill Warner
10

Aquí hay una secuencia de comandos rápida que puede agregar como un trabajo de canalización para enumerar todas las variables de entorno:

node {
    echo(env.getEnvironment().collect({environmentVariable ->  "${environmentVariable.key} = ${environmentVariable.value}"}).join("\n"))
    echo(System.getenv().collect({environmentVariable ->  "${environmentVariable.key} = ${environmentVariable.value}"}).join("\n"))
}

Esto enumerará las variables del sistema y de Jenkins.

Daniel
fuente
9

Forma multiplataforma de enumerar todas las variables de entorno:

if (isUnix()) {
    sh env
}
else {
    bat set
}
Terry
fuente
7

Utilizo el complemento Blue Ocean y no me gustó que cada entrada de entorno tuviera su propio bloque. Quiero un bloque con todas las líneas.

Imprime mal:

sh 'echo `env`'

Imprime mal:

sh 'env > env.txt'
for (String i : readFile('env.txt').split("\r?\n")) {
    println i
}

Imprime bien:

sh 'env > env.txt'
sh 'cat env.txt'

Imprime bien: (como lo menciona @mjfroehlich)

echo sh(script: 'env', returnStdout: true)
Jon Lauridsen
fuente
3

Las respuestas anteriores ahora son anticuadas debido a la nueva sintaxis de canalización. A continuación se imprimen las variables de entorno.

script {
        sh 'env > env.txt'
        String[] envs = readFile('env.txt').split("\r?\n")

        for(String vars: envs){
            println(vars)
        }
    }
Eddie
fuente
1
1. Necesita tenerlo en un bloque de script. 2. Están depreciando el ciclo del 'estilo maravilloso'.
Eddie
El forcon un cierre también causará problemas sin una @NonCPSanotación.
sorteo
2

Las soluciones Groovy puras que leen la envvariable global no imprimen todas las variables de entorno (por ejemplo, les faltan variables del environmentbloque, del withEnvcontexto y la mayoría de las variables específicas de la máquina del sistema operativo). Usando los pasos de shell es posible obtener un conjunto más completo, pero eso requiere un nodecontexto, que no siempre se desea.

Aquí hay una solución que utiliza el getContextpaso para recuperar e imprimir el conjunto completo de variables de entorno, incluidos los parámetros de canalización, para el contexto actual.

Advertencia: no funciona en la caja de arena Groovy. Sin embargo, puede usarlo desde una biblioteca compartida confiable.

def envAll = getContext( hudson.EnvVars )
echo envAll.collect{ k, v -> "$k = $v" }.join('\n')
zett42
fuente
1

si realmente desea recorrer la envlista, simplemente haga:

def envs = sh(returnStdout: true, script: 'env').split('\n')
envs.each { name  ->
    println "Name: $name"
}
dsaydon
fuente
0

otra forma de obtener exactamente el resultado mencionado en la pregunta:

envtext= "printenv".execute().text
envtext.split('\n').each
{   envvar=it.split("=")
    println envvar[0]+" is "+envvar[1]
}

Esto se puede ampliar fácilmente para crear un mapa con un subconjunto de variables env que coincidan con un criterio:

envdict=[:]
envtext= "printenv".execute().text
envtext.split('\n').each
{   envvar=it.split("=")
    if (envvar[0].startsWith("GERRIT_"))
        envdict.put(envvar[0],envvar[1])
}    
envdict.each{println it.key+" is "+it.value}
romano
fuente
0

Supongo que necesitabas eso en forma de script, pero si alguien más solo quiere echar un vistazo a la GUI de Jenkins, esa lista se puede encontrar seleccionando la sección "Variables de entorno" en el menú contextual izquierdo de cada compilación Seleccionar proyecto = > Seleccionar compilación => Variables de entorno

ingrese la descripción de la imagen aquí

claudo
fuente
2
Esto no siempre está disponible.
shuckc
1
No creo que esté disponible para Jenkinsfiles en absoluto. La captura de pantalla parece una construcción de estilo libre.
Jakub Bochenski
0

Encontré que esta es la forma más fácil:

pipeline {
    agent {
        node {
            label 'master'
        }
    }   
    stages {
        stage('hello world') {
            steps {
                sh 'env'
            }
        }
    }
}
Prosenjit Sen
fuente
-1

Puede obtener todas las variables de su instancia de jenkins. Solo visita:

  • $ {jenkins_host} /env-vars.html
  • $ {jenkins_host} / pipeline-syntax / globals
Dmitriy Tarasevich
fuente