Jenkins: impossible de définir la variable dans l'étape de pipeline

106

J'essaie de créer un script de pipeline Jenkins déclaratif mais j'ai des problèmes avec une simple déclaration de variable.

Voici mon script:

pipeline {
   agent none
   stages {
       stage("first") {
           def foo = "foo" // fails with "WorkflowScript: 5: Expected a step @ line 5, column 13."
           sh "echo ${foo}"
       }
   }
}

Cependant, j'obtiens cette erreur:

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 5: Expected a step @ line 5, column 13.
           def foo = "foo"
           ^

Je suis sur Jenkins 2.7.4 et Pipeline 2.4.

Malcolm Crum
la source

Réponses:

101

Le modèle déclaratif pour Jenkins Pipelines a un sous-ensemble restreint de syntaxe qu'il autorise dans les stageblocs - voir le guide de syntaxe pour plus d'informations . Vous pouvez contourner cette restriction en encapsulant vos étapes dans un script { ... }bloc, mais par conséquent, vous perdrez la validation de la syntaxe, des paramètres, etc. dans le scriptbloc.

abayer
la source
5
Que faire si je souhaite utiliser cette variable en dehors du bloc de script?
Jan Steinke
3
pour utiliser une variable en dehors du bloc de script, vérifiez ce stackoverflow.com/questions/43879733/…
Senthil A Kumar
56

Je pense que l'erreur ne vient pas de la ligne spécifiée mais des 3 premières lignes. Essayez plutôt ceci:

node {
   stage("first") {
     def foo = "foo"
     sh "echo ${foo}"
   }
}

Je pense que vous aviez des lignes supplémentaires qui ne sont pas valides ...

ÉDITER

D'après la documentation du modèle de pipeline déclaractif , il semble que vous deviez utiliser un environmentbloc de déclaration pour déclarer vos variables, par exemple:

pipeline {
   environment {
     FOO = "foo"
   }

   agent none
   stages {
       stage("first") {
           sh "echo ${FOO}"
       }
   }
}
Pom12
la source
1
Vous pouvez également ajouter un bloc d'environnement dans une étape (par exemple, si votre variable dépend de quelque chose fait dans une étape précédente).
Tereza Tomcova
34

D'accord avec @ Pom12, @abayer. Pour compléter la réponse, vous devez ajouter un bloc de script

Essayez quelque chose comme ceci:

pipeline {
    agent any
    environment {
        ENV_NAME = "${env.BRANCH_NAME}"
    }

    // ----------------

    stages {
        stage('Build Container') {
            steps {
                echo 'Building Container..'

                script {
                    if (ENVIRONMENT_NAME == 'development') {
                        ENV_NAME = 'Development'
                    } else if (ENVIRONMENT_NAME == 'release') {
                        ENV_NAME = 'Production'
                    }
                }
                echo 'Building Branch: ' + env.BRANCH_NAME
                echo 'Build Number: ' + env.BUILD_NUMBER
                echo 'Building Environment: ' + ENV_NAME

                echo "Running your service with environemnt ${ENV_NAME} now"
            }
        }
    }
}
Si Zi
la source
4
Notez que cet exemple suppose qu'il existe déjà une variable d'environnement définie "ENVIRONMENT_NAME" accessible à jenkins.
Alberto
1
Le bloc de script peut-il modifier les valeurs d'environnement?
pitchblack408
Oui, vous pouvez modifier la valeur d'environnement dans le bloc de script.
NicoPaez
8

Dans Jenkins 2.138.3, il existe deux types différents de pipelines.

Pipelines déclaratifs et scriptés.

"Les pipelines déclaratifs sont une nouvelle extension du pipeline DSL (il s'agit essentiellement d'un script pipeline avec une seule étape, une étape de pipeline avec des arguments (appelés directives), ces directives devraient suivre une syntaxe spécifique. L'intérêt de ce nouveau format est qu'il est plus strict et devrait donc être plus facile pour ceux qui découvrent les pipelines, permet l'édition graphique et bien plus encore. Les pipelines scriptés sont la solution de secours pour les exigences avancées. "

pipeline jenkins: agent vs nœud?

Voici un exemple d'utilisation des variables d'environnement et globales dans un pipeline déclaratif. D'après ce que je peux dire, l'environnement est statique une fois défini.

def  browser = 'Unknown'

pipeline {
    agent any
    environment {
    //Use Pipeline Utility Steps plugin to read information from pom.xml into env variables
    IMAGE = readMavenPom().getArtifactId()
    VERSION = readMavenPom().getVersion()


    }
    stages {
        stage('Example') {
            steps {
                script {
                    browser = sh(returnStdout: true, script: 'echo Chrome')
                }
            }
        }
        stage('SNAPSHOT') {
                when {
                    expression { 
                        return !env.JOB_NAME.equals("PROD") && !env.VERSION.contains("RELEASE")
                    }
                }
                steps {
                    echo "SNAPSHOT"
                    echo "${browser}"
                }
            }
            stage('RELEASE') {
                when {
                    expression { 
                        return !env.JOB_NAME.equals("TEST") && !env.VERSION.contains("RELEASE")
                    }
                }
                steps {
                    echo "RELEASE"
                    echo "${browser}"
                }
            }
    }//end of stages 
}//end of pipeline
pitchblack408
la source
J'obtiens l'erreur suivante du code ci-dessus: [Pipeline] Début du pipeline [Pipeline] readMavenPom [Pipeline] Fin du pipeline org.jenkinsci.plugins.workflow.steps.MissingContextVariableException: La classe de contexte requise hudson.FilePath est manquante Vous avez peut-être oublié d'entourer le code avec une étape qui fournit cela, tel que: node
mancocapac
Non, cela a fonctionné tel quel. C'est un pipeline déclaratif. Agent any signifie qu'il peut fonctionner sur n'importe quel nœud
pitchblack408
@ pitchblack408, vous avez raison, j'avais [agent aucun] au sommet de mon pipeline. Vous ne savez pas ce que vous entendez par: l'environnement est statique une fois défini? Ils peuvent être modifiés dans un script, par exemple script {IMAGE = "newVal}
mancocapac
Exemple, regardez IMAGE. Ce n'est pas une variable qui peut ou devrait être modifiée par les pipelines. Je crois comprendre que cela doit être traité comme une valeur statique après définition dans le cadre de l'environnement.
pitchblack408
0

Vous utilisez un pipeline déclaratif qui nécessite un script pour exécuter le code Groovy. C'est une énorme différence par rapport au pipeline scripté où cela n'est pas nécessaire.

La documentation officielle dit ce qui suit:

L'action de script prend un bloc de Pipeline scripté et l'exécute dans le Pipeline déclaratif.

pipeline {
   agent none
   stages {
       stage("first") {
           script {
               def foo = "foo" 
               sh "echo ${foo}"
           }
       }
   }
}
Michael Kemmerzell
la source