Jenkins: nie można zdefiniować zmiennej na etapie potoku


106

Próbuję utworzyć deklaratywny skrypt potoku Jenkins, ale mam problemy z prostą deklaracją zmiennej.

Oto mój skrypt:

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

Jednak pojawia się ten błąd:

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

Jestem na Jenkins 2.7.4 i Pipeline 2.4.

Odpowiedzi:


101

Model deklaratywny dla Jenkins Pipelines ma ograniczony podzbiór składni, na który pozwala w stageblokach - zobacz przewodnik po składni, aby uzyskać więcej informacji . Możesz ominąć to ograniczenie, zawijając kroki w script { ... }blok, ale w rezultacie utracisz walidację składni, parametrów itp. W scriptbloku.


5
A jeśli chcę użyć tej zmiennej poza blokiem skryptu?
Jan Steinke,

3
aby używać zmiennej poza blokiem skryptu, sprawdź ten stackoverflow.com/questions/43879733/ ...
Senthil A Kumar

56

Myślę, że błąd nie pochodzi z określonej linii, ale z pierwszych 3 linii. Spróbuj tego zamiast tego:

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

Myślę, że miałeś kilka dodatkowych wierszy, które są nieprawidłowe ...

EDYTOWAĆ

Z deklarowanej dokumentacji modelu potoku wynika , że environmentdo zadeklarowania zmiennych należy użyć bloku deklaracji, np .:

pipeline {
   environment {
     FOO = "foo"
   }

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

1
Możesz również dodać blok środowiska do etapu (np. Jeśli zmienna zależy od czegoś, co zostało zrobione na wcześniejszym etapie).
Tereza Tomcova

34

Zgadzam się z @ Pom12, @abayer. Aby uzupełnić odpowiedź, musisz dodać blok skryptu

Spróbuj czegoś takiego:

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
Zwróć uwagę, że w tym przykładzie założono, że istnieje już zdefiniowana zmienna środowiskowa „ENVIRONMENT_NAME” dostępna dla jenkins.
Alberto

1
Czy blok skryptu może zmienić wartości środowiska?
pitchblack408

Tak, możesz zmienić wartość środowiska wewnątrz bloku de script.
NicoPaez

8

W Jenkins 2.138.3 istnieją dwa różne typy rurociągów.

Potoki deklaratywne i oparte na skryptach.

„Deklaratywne potoki to nowe rozszerzenie potoku DSL (w zasadzie jest to skrypt potoku z tylko jednym krokiem, krokiem potoku z argumentami (zwanymi dyrektywami). Te dyrektywy powinny mieć określoną składnię. Celem tego nowego formatu jest to, że jest bardziej rygorystyczny i dlatego powinien być łatwiejszy dla nowych użytkowników potoków, umożliwiać edycję graficzną i nie tylko. Potoki skryptowe to rozwiązanie zastępcze dla zaawansowanych wymagań ”.

Jenkins Pipeline: Agent kontra Węzeł?

Oto przykład użycia zmiennych środowiskowych i globalnych w potoku deklaratywnym. Z tego, co mogę powiedzieć, środowisko jest statyczne po ustawieniu.

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

W powyższym kodzie pojawia się następujący błąd: [Pipeline] Początek potoku [Pipeline] readMavenPom [Pipeline] Koniec rurociągu org.jenkinsci.plugins.workflow.steps.MissingContextVariableException: Brak wymaganej klasy kontekstu hudson.FilePath Być może zapomniałeś otoczyć kod z krokiem, który to zapewnia, na przykład: node
mancocapac

Nie, to działało tak, jak jest. Jest to potok deklaratywny. Agent w dowolny sposób oznacza, że ​​może działać na dowolnym węźle
pitchblack408

@ pitchblack408, masz rację, miałem [agenta brak] na szczycie mojego rurociągu. Nie wiesz, co masz na myśli, mówiąc: środowisko jest statyczne po ustawieniu? Można je zmienić w skrypcie, np. Script {IMAGE = "newVal}
mancocapac

Przykład, spójrz na OBRAZ. Nie jest zmienną, która może lub powinna zostać zmieniona przez rurociąg. Rozumiem, że po zdefiniowaniu należy go traktować jako wartość statyczną jako część środowiska.
pitchblack408

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.