64 votes

Pipeline déclaratif Jenkinsfile définissant des vars env dynamiques

Je suis novice en matière de pipeline Jenkins ; je suis en train de définir un pipeline à syntaxe déclarative et je ne sais pas si je peux résoudre mon problème, car je n'ai pas trouvé de solution.

Dans cet exemple, j'ai besoin de passer une variable au plugin ansible (dans l'ancienne version j'utilisais un ENV_VAR ou en l'injectant depuis un fichier avec le plugin inject) cette variable provient d'un script.

C'est mon scénario idéal (mais il ne fonctionne pas à cause de l'environnement{}) :

pipeline {
  agent { node { label 'jenkins-node'}}

  stages {
    stage('Deploy') {
      environment {
        ANSIBLE_CONFIG = '${WORKSPACE}/chimera-ci/ansible/ansible.cfg'
        VERSION = sh("python3.5 docker/get_version.py")
      }
      steps {
        ansiblePlaybook credentialsId: 'example-credential', extras: '-e version=${VERSION}', inventory: 'development', playbook: 'deploy.yml'
      }
    }
  }
}

J'ai essayé d'autres façons de tester le fonctionnement des env vars dans un autre post, par exemple :

pipeline {
  agent { node { label 'jenkins-node'}}

  stages {
    stage('PREPARE VARS') {
      steps {
        script {
          env['VERSION'] = sh(script: "python3.5 get_version.py")
        }
        echo env.VERSION
      }
    }
  }
}

mais "echo env.VERSION" retourne null.

J'ai également essayé le même exemple avec : - VERSION= python3.5 get_version.py - VERSION= python3.5 get_version.py > props.file (et essayer de l'injecter, mais je n'ai pas trouvé comment)

Si cela n'est pas possible, je le ferai dans le rôle ansible.

UPDATE

Il y a un autre "problème" dans Ansible Plugin, pour utiliser les vars dans les extra vars, il doit avoir des guillemets doubles au lieu de simples.

ansiblePlaybook credentialsId: 'example-credential', extras: "-e version=${VERSION}", inventory: 'development', playbook: 'deploy.yml'

130voto

burnettk Points 6712

Vous pouvez créer des variables avant le démarrage du bloc pipeline. Vous pouvez avoir sh retourner stdout pour l'assigner à ces variables. Vous n'avez pas la même flexibilité pour assigner des variables d'environnement dans le système de gestion de l'environnement. environment stanza. Remplacez donc par python3.5 get_version.py où j'ai echo 0.0.1 dans le script ici (et assurez-vous que votre script python renvoie juste la version à stdout) :

def awesomeVersion = 'UNKNOWN'

pipeline {
  agent { label 'docker' }
  stages {
    stage('build') {
      steps {
        script {
          awesomeVersion = sh(returnStdout: true, script: 'echo 0.0.1').trim()
        }
      }
    }
    stage('output_version') {
      steps {
        echo "awesomeVersion: ${awesomeVersion}"
      }
    }
  }
}

La sortie du pipeline ci-dessus est :

awesomeVersion: 0.0.1

0 votes

Je crois que si vous voulez définir une variable d'environnement réelle, vous devez ajouter en préambule env. . env.awesomeVersion = sh(...

1 votes

Vous pouvez lire les variables d'environnement dans un fichier Jenkins en utilisant env.SOMETHING. je ne suis pas sûr que vous puissiez également les mettre à jour de cette façon. heureusement, le PO n'avait pas réellement besoin de variables d'environnement. La réponse de Kevin Higgins vaut également le coup d'œil. Votre kilométrage peut varier, car echo est utilisable à des endroits où vos scripts personnalisés ne le sont pas.

1 votes

Pour information, j'ai essayé ceci SANS déclarer la variable avant le bloc pipeline, et cela fonctionne également. Je ne suis pas contre le fait de déclarer la variable comme indiqué, cela rend explicite qu'elle est destinée à être utilisée dans plus d'une étape, je veux juste dire que ce n'est pas nécessaire.

30voto

Dans Jenkins 2.76, j'ai pu simplifier la solution de @burnettk en :

pipeline {
  agent { label 'docker' }
  environment {
    awesomeVersion = sh(returnStdout: true, script: 'echo 0.0.1')
  }
  stages {
    stage('output_version') {
      steps {
        echo "awesomeVersion: ${awesomeVersion}"
      }
    }
  }
}

5 votes

J'ai essayé celle-ci, mais si je définis awesomeVersion dans une autre étape avant l'étape output_verison, cela n'est pas mis à jour dans la variable.

4 votes

Notez que cette solution n'est pas une simplification de la solution de Burnettk. Elle est différente en ce qu'elle définit une variable d'environnement. La solution de burnettk utilise une variable Groovy. C'est pourquoi sa mise à jour dans une autre étape ne fonctionne pas comme souhaité.

2 votes

Toujours +1 car c'est très utile de savoir que l'on peut définir une variable d'environnement avec une balise sh étape.

6voto

dpinya Points 84

En utilisant le plugin "pipeline utility steps", vous pouvez définir des variables générales disponibles pour toutes les étapes à partir d'un fichier de propriétés. Par exemple, laissez props.txt comme :

version=1.0
fix=alfa

et mélanger script et pipeline déclaratif Jenkins comme :

def props
def VERSION
def FIX
def RELEASE

node {
   props = readProperties file:'props.txt'
   VERSION = props['version']
   FIX = props['fix']
   RELEASE = VERSION + "_" + FIX
}

pipeline {
   stages {
      stage('Build') {
         echo ${RELEASE}
      }
   }
}

3voto

Emmanuel B. Points 109

Une variation possible de la réponse principale est de fournir la variable en utilisant un autre pipeline au lieu d'un script sh.

exemple (définir le pipeline des variables) : mon pipeline de set-env-variables

script
{
    env.my_dev_version = "0.0.4-SNAPSHOT"
    env.my_qa_version  = "0.0.4-SNAPSHOT"
    env.my_pp_version  = "0.0.2"
    env.my_prd_version = "0.0.2"
    echo " My versions  [DEV:${env.my_dev_version}] [QA:${env.my_qa_version}] [PP:${env.my_pp_version}] [PRD:${env.my_prd_version}]"
}

(utiliser ces variables) dans un autre pipeline my-set-env-variables-test

script 
{
    env.dev_version = "NOT DEFINED DEV"
    env.qa_version  = "NOT DEFINED QA"
    env.pp_version  = "NOT DEFINED PP"
    env.prd_version = "NOT DEFINED PRD"
}

stage('inject variables') {

    echo "PRE DEV version = ${env.dev_version}"
    script 
    {
       // call set variable job
       def variables = build job: 'my-set-env-variables'
       def vars = variables.getBuildVariables()
      //println "found variables" + vars
      env.dev_version = vars.my_dev_version
      env.qa_version  = vars.my_qa_version
      env.pp_version  = vars.my_pp_version
      env.prd_version = vars.my_prd_version
    }
}

stage('next job') {
    echo "NEXT JOB DEV version = ${env.dev_version}"
    echo "NEXT JOB QA version = ${env.qa_version}"
    echo "NEXT JOB PP version = ${env.pp_version}"
    echo "NEXT JOB PRD version = ${env.prd_version}"

}

0voto

krad Points 569

Vous pouvez également déposer toutes vos variables dans un fichier, puis utiliser la syntaxe '-e @file'. Ceci est très utile si vous avez beaucoup de variables à remplir.

steps {
  echo "hello World!!"
  sh """
  var1: ${params.var1}
  var2: ${params.var2}
  " > vars
  """
  ansiblePlaybook inventory: _inventory, playbook: 'test-playbook.yml', sudoUser: null, extras: '-e @vars'
}

0 votes

Pouvez-vous ajouter un lien vers la documentation ? Je n'ai pas réussi à trouver quelque chose d'utile.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X