Jenkins: Impossibile definire la variabile nella fase della pipeline


106

Sto cercando di creare uno script di pipeline Jenkins dichiarativo ma ho problemi con la semplice dichiarazione di variabili.

Ecco il mio script:

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

Tuttavia, ottengo questo errore:

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

Sono su Jenkins 2.7.4 e Pipeline 2.4.

Risposte:


101

Il modello dichiarativo per Jenkins Pipelines ha un sottoinsieme limitato di sintassi che consente nei stageblocchi: vedere la guida alla sintassi per maggiori informazioni . Puoi aggirare tale restrizione avvolgendo i tuoi passaggi in un script { ... }blocco, ma di conseguenza perderai la convalida della sintassi, dei parametri, ecc. All'interno del scriptblocco.


5
E se volessi utilizzare quella variabile al di fuori del blocco di script?
Jan Steinke

3
per l'utilizzo di variabili al di fuori del blocco di script controllare questo stackoverflow.com/questions/43879733/...
Senthil Kumar A

56

Penso che l'errore non provenga dalla riga specificata ma dalle prime 3 righe. Prova questo invece:

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

Penso che tu abbia alcune righe in più che non sono valide ...

MODIFICARE

Dalla documentazione del modello di pipelineenvironment dichiarativa , sembra che tu debba usare un blocco di dichiarazione per dichiarare le tue variabili, ad esempio:

pipeline {
   environment {
     FOO = "foo"
   }

   agent none
   stages {
       stage("first") {
           sh "echo ${FOO}"
       }
   }
}

1
Puoi anche aggiungere un blocco di ambiente in una fase (ad esempio se la tua variabile dipende da qualcosa fatto in un passaggio precedente).
Tereza Tomcova

34

D'accordo con @ Pom12, @abayer. Per completare la risposta è necessario aggiungere il blocco di script

Prova qualcosa di simile:

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"
            }
        }
    }
}

4
Si noti che questo esempio presuppone che esista già una variabile di ambiente definita "ENVIRONMENT_NAME" accessibile a jenkins.
Alberto

1
Il blocco di script può modificare i valori dell'ambiente?
pitchblack408

Sì, puoi modificare il valore dell'ambiente all'interno del blocco di script.
NicoPaez

8

In Jenkins 2.138.3 ci sono due diversi tipi di condutture.

Pipeline dichiarative e con script.

"Le pipeline dichiarative sono una nuova estensione della pipeline DSL (è fondamentalmente uno script di pipeline con un solo passaggio, un passaggio di pipeline con argomenti (chiamate direttive), queste direttive dovrebbero seguire una sintassi specifica. Il punto di questo nuovo formato è che è più rigoroso e quindi dovrebbe essere più facile per chi è alle prime armi con le pipeline, consentire l'editing grafico e molto altro ancora. Le pipeline con script sono il fallback per i requisiti avanzati. "

pipeline di jenkins: agente vs nodo?

Di seguito è riportato un esempio di utilizzo di variabili globali e di ambiente in una pipeline dichiarativa. Da quello che posso dire, l'ambiente è statico dopo essere stato impostato.

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

Ottengo il seguente errore dal codice precedente: [Pipeline] Start of Pipeline [Pipeline] readMavenPom [Pipeline] End of Pipeline org.jenkinsci.plugins.workflow.steps.MissingContextVariableException: Classe di contesto richiesta hudson.FilePath mancante Forse hai dimenticato di circondare il codice con uno step che prevede questo tipo: nodo
mancocapac

No, ha funzionato così com'è. È una pipeline dichiarativa. L'agente significa che può funzionare su qualsiasi nodo
pitchblack408

@ pitchblack408, hai ragione, avevo [nessun agente] in cima alla mia pipeline. Non sei sicuro di cosa intendi per: gli ambienti sono statici dopo essere stati impostati? Possono essere modificati all'interno di uno script, ad esempio script {IMAGE = "newVal}
mancocapac

Esempio, guarda l'IMMAGINE. Non è una variabile che può o deve essere modificata dalle condutture. A quanto mi risulta, deve essere trattato come un valore statico dopo la definizione come parte dell'ambiente.
pitchblack408

0

Stai utilizzando una pipeline dichiarativa che richiede un'istruzione di script per eseguire il codice Groovy. Questa è un'enorme differenza rispetto alla pipeline con script in cui ciò non è necessario.

La documentazione ufficiale dice quanto segue:

L'istruzione di script accetta un blocco di pipeline con script e lo esegue nella pipeline dichiarativa.

pipeline {
   agent none
   stages {
       stage("first") {
           script {
               def foo = "foo" 
               sh "echo ${foo}"
           }
       }
   }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.