Jenkins: Tidak dapat menentukan variabel dalam tahap pipeline

106

Saya mencoba membuat skrip pipeline Jenkins deklaratif tetapi mengalami masalah dengan deklarasi variabel sederhana.

Ini skrip saya:

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

Namun, saya mendapatkan kesalahan ini:

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

Saya menggunakan Jenkins 2.7.4 dan Pipeline 2.4.

Malcolm Crum
sumber

Jawaban:

101

Model Deklaratif untuk Jenkins Pipelines memiliki subset sintaks terbatas yang diizinkan dalam stageblok - lihat panduan sintaks untuk info lebih lanjut . Anda dapat melewati batasan itu dengan membungkus langkah Anda dalam satu script { ... }blok, tetapi akibatnya, Anda akan kehilangan validasi sintaks, parameter, dll di dalam scriptblok tersebut.

abayer
sumber
5
Bagaimana jika saya ingin menggunakan variabel itu di luar blok skrip?
Jan Steinke
3
untuk menggunakan variabel di luar blok skrip periksa stackoverflow.com/questions/43879733/…
Senthil A Kumar
56

Menurut saya kesalahan tidak datang dari baris yang ditentukan tetapi dari 3 baris pertama. Coba ini sebagai gantinya:

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

Saya pikir Anda memiliki beberapa baris tambahan yang tidak valid ...

EDIT

Dari dokumentasi model pipeline deklaraktif , tampaknya Anda harus menggunakan environmentblok deklarasi untuk mendeklarasikan variabel Anda, misalnya:

pipeline {
   environment {
     FOO = "foo"
   }

   agent none
   stages {
       stage("first") {
           sh "echo ${FOO}"
       }
   }
}
Pom12
sumber
1
Anda juga dapat menambahkan blok lingkungan ke dalam suatu tahapan (misalnya jika variabel Anda bergantung pada sesuatu yang dilakukan pada langkah sebelumnya).
Tereza Tomcova
34

Setuju dengan @ Pom12, @abayer. Untuk melengkapi jawaban Anda perlu menambahkan blok skrip

Coba sesuatu seperti ini:

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
sumber
4
Perhatikan bahwa contoh ini mengasumsikan bahwa sudah ada variabel lingkungan yang ditentukan "ENVIRONMENT_NAME" yang dapat diakses oleh jenkins.
Alberto
1
Bisakah blok skrip mengubah nilai lingkungan?
pitchblack408
Ya, Anda dapat mengubah nilai lingkungan di dalam blok de script.
NicoPaez
8

Di Jenkins 2.138.3 ada dua jenis pipa yang berbeda.

Pipeline Deklaratif dan Scripted.

"Pipeline deklaratif adalah ekstensi baru dari pipeline DSL (ini pada dasarnya adalah skrip pipeline dengan hanya satu langkah, langkah pipeline dengan argumen (disebut arahan), arahan ini harus mengikuti sintaks tertentu. Inti dari format baru ini adalah bahwa itu lebih ketat dan karena itu akan lebih mudah bagi mereka yang baru mengenal pipeline, memungkinkan pengeditan grafis dan banyak lagi. pipeline dengan skrip adalah pengganti untuk persyaratan lanjutan. "

pipeline jenkins: agen vs node?

Berikut adalah contoh penggunaan variabel lingkungan dan global dalam Declarative Pipeline. Dari apa yang saya tahu bahwa lingkungan menjadi statis setelah ditetapkan.

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
sumber
Saya mendapatkan kesalahan berikut dari kode di atas: [Pipeline] Start of Pipeline [Pipeline] readMavenPom [Pipeline] End of Pipeline org.jenkinsci.plugins.workflow.steps.MissingContextVariableException: Diperlukan kelas konteks hudson.FilePath hilang Mungkin Anda lupa mengelilingi kode dengan langkah yang menyediakan ini, seperti: node
mancocapac
Tidak, itu berfungsi sebagaimana mestinya. Ini adalah pipa deklaratif. Agen berarti dapat bekerja pada node mana pun
pitchblack408
@ pitchblack408, Anda benar Saya memiliki [agen tidak ada] di bagian atas saluran saya. Tidak yakin apa yang Anda maksud dengan: lingkungan statis setelah disetel? Mereka dapat diubah dalam skrip, misalnya skrip {IMAGE = "newVal}
mancocapac
Contoh, lihat GAMBAR. Ini bukan variabel yang dapat atau harus diubah oleh pipeline. Menurut pemahaman saya, ini harus diperlakukan sebagai nilai statis setelah definisi sebagai bagian dari lingkungan.
pitchblack408
0

Anda menggunakan Declarative Pipeline yang memerlukan langkah skrip untuk menjalankan kode Groovy. Ini adalah perbedaan besar dibandingkan dengan Scripted Pipeline yang tidak memerlukannya.

The dokumentasi resmi mengatakan berikut:

Langkah skrip mengambil satu blok Scripted Pipeline dan menjalankannya di Declarative Pipeline.

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