Дженкінс: Неможливо визначити змінну на стадії конвеєра


106

Я намагаюся створити декларативний сценарій конвеєра Дженкінса, але маю проблеми з простим оголошенням змінної.

Ось мій сценарій:

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

Однак я отримую цю помилку:

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

Я на Jenkins 2.7.4 та Pipeline 2.4.

Відповіді:


101

Декларативна модель для Дженкінса Трубопровід має обмежений підмножина синтаксису, який він дозволяє в stageблоках - для отримання додаткової інформації див. Посібник із синтаксису . Ви можете обійти це обмеження, загорнувши свої кроки в script { ... }блок, але, як результат, ви втратите валідацію синтаксису, параметрів тощо у межах scriptблоку.


5
Що робити, якщо я хочу використовувати цю змінну поза блоком сценарію?
Ян Штейнке

3
для використання змінної за межами блоку сценарію перевірити цей stackoverflow.com/questions/43879733/…
Senthil A Kumar

56

Я думаю, що помилка приходить не з вказаного рядка, а з перших 3 рядків. Спробуйте це замість цього:

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

Я думаю, у вас були додаткові рядки, які не відповідають дійсності ...

EDIT

З документальної декларативної документації на трубопровід , схоже, що вам потрібно використовувати environmentблок декларування для оголошення своїх змінних, наприклад:

pipeline {
   environment {
     FOO = "foo"
   }

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

1
Ви також можете додати блок середовища в етап (наприклад, якщо ваша змінна залежить від того, що було зроблено на попередньому кроці).
Тереза ​​Томкова

34

Погодьтеся з @ Pom12, @abayer. Для завершення відповіді потрібно додати блок скриптів

Спробуйте щось подібне:

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
Зверніть увагу, що цей приклад передбачає, що вже існує визначена змінна середовище "ENVIRONMENT_NAME", доступна для джинкінів.
Альберто

1
Чи може блок скриптів змінити значення середовища?
pitchblack408

Так, ви можете змінити значення середовища всередині блоку de script.
NicoPaez

8

У Jenkins 2.138.3 є два різних типи трубопроводів.

Декларативні та сценарії трубопроводів.

"Декларативні трубопроводи - це нове розширення DSL конвеєра (це в основному сценарій конвеєра лише з одним кроком, крок конвеєра з аргументами (звані директивами). Ці директиви повинні слідувати конкретному синтаксису. Суть цього нового формату полягає в тому, що він є більш суворим і тому повинен бути простішим для тих, хто починає працювати з конвеєрами, допускати графічне редагування та багато іншого.

Дженкінс трубопровід: агент проти вузла?

Ось приклад використання змінних середовища та глобальних змінних у декларативному конвеєрі. З того, що я можу сказати, навколишнє середовище є статичним після їх встановлення.

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

Я отримую таку помилку з наведеного вище коду: [Трубопровід] Початок трубопроводу [Трубопровід] readMavenPom [Трубопровід] Кінець трубопроводу org.jenkinsci.plugins.workflow.steps.MissingContextVariableException: Необхідний контекстний клас hudson.FilePath відсутній Можливо, ви забули оточити код із кроком, який забезпечує це, наприклад: node
mancocapac

Ні, це спрацювало так, як є. Це декларативний конвеєр. Агент будь-який означає, що він може працювати на будь-якому вузлі
pitchblack408,

@ pitchblack408, ти прав, у мене був [агент жоден] у верхній частині мого трубопроводу. Не знаєте, що ви маєте на увазі під собою: оточення статичні після їх встановлення? Вони можуть бути змінені в сценарії, наприклад, сценарій {IMAGE = "newVal}
mancocapac

Наприклад, подивіться на IMAGE. Не можна змінювати трубопроводи, які можуть або повинні бути змінені. Наскільки я розумію, що після визначення його слід розглядати як статичне значення як частину навколишнього середовища.
pitchblack408

0

Ви використовуєте декларативний конвеєр, для виконання якого потрібен сценарій для виконання коду Groovy. Це величезна різниця порівняно зі сценарієм трубопроводу, де це не потрібно.

В офіційній документації зазначено:

Крок сценарію займає блок сценарію трубопроводу та виконує його в декларативному конвеєрі.

pipeline {
   agent none
   stages {
       stage("first") {
           script {
               def foo = "foo" 
               sh "echo ${foo}"
           }
       }
   }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.