Jenkins: ไม่สามารถกำหนดตัวแปรในขั้นตอนไปป์ไลน์


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

รูปแบบการ declarative สำหรับเจนกินส์ท่อมีเซตที่ จำกัด ของไวยากรณ์ว่ามันช่วยในstageบล็อก - ดูคู่มือไวยากรณ์สำหรับข้อมูลเพิ่มเติม คุณสามารถข้ามข้อ จำกัด นั้นได้โดยการรวมขั้นตอนของคุณไว้ในscript { ... }บล็อก แต่ด้วยเหตุนี้คุณจะสูญเสียการตรวจสอบความถูกต้องของไวยากรณ์พารามิเตอร์และอื่น ๆ ภายในscriptบล็อก


5
จะเกิดอะไรขึ้นถ้าฉันต้องการใช้ตัวแปรนั้นนอกบล็อกสคริปต์?
ม.ค. Steinke

3
สำหรับการใช้ตัวแปรนอกบล็อกสคริปต์ตรวจสอบstackoverflow.com/questions/43879733/…
Senthil A Kumar

56

ฉันคิดว่าข้อผิดพลาดไม่ได้มาจากบรรทัดที่ระบุ แต่มาจาก 3 บรรทัดแรก ลองสิ่งนี้แทน:

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

ฉันคิดว่าคุณมีบรรทัดพิเศษบางอย่างที่ไม่ถูกต้อง ...

แก้ไข

จากเอกสารประกอบโมเดลไปป์ไลน์ที่เปิดเผยดูเหมือนว่าคุณต้องใช้environmentบล็อกการประกาศเพื่อประกาศตัวแปรของคุณเช่น:

pipeline {
   environment {
     FOO = "foo"
   }

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

1
คุณยังสามารถเพิ่มบล็อกสภาพแวดล้อมลงในพื้นที่งาน (เช่นถ้าตัวแปรของคุณขึ้นอยู่กับสิ่งที่ทำในขั้นตอนก่อนหน้านี้)
Tereza Tomcova

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" ที่เจนกินส์สามารถเข้าถึงได้
Alberto

1
บล็อกสคริปต์สามารถเปลี่ยนค่าสภาพแวดล้อมได้หรือไม่
pitchblack408

ได้คุณสามารถเปลี่ยนค่าสภาพแวดล้อมภายในบล็อกสคริปต์
NicoPaez

8

ใน Jenkins 2.138.3 มีท่อสองประเภทที่แตกต่างกัน

ไปป์ไลน์ที่เปิดเผยและสคริปต์

"ไปป์ไลน์ประกาศเป็นส่วนขยายใหม่ของ DSL ไปป์ไลน์ (โดยพื้นฐานแล้วจะเป็นสคริปต์ไปป์ไลน์ที่มีเพียงขั้นตอนเดียวคือขั้นตอนไปป์ไลน์ที่มีอาร์กิวเมนต์ (เรียกว่าคำสั่ง) คำสั่งเหล่านี้ควรเป็นไปตามไวยากรณ์เฉพาะประเด็นของรูปแบบใหม่นี้คือ มีความเข้มงวดมากขึ้นดังนั้นจึงควรง่ายกว่าสำหรับผู้ที่เพิ่งเริ่มใช้ไปป์ไลน์อนุญาตให้แก้ไขกราฟิกและอื่น ๆ อีกมากมายไปป์ไลน์แบบสคริปต์เป็นทางเลือกสำหรับข้อกำหนดขั้นสูง "

jenkins ไปป์ไลน์: ตัวแทน vs โหนด?

นี่คือตัวอย่างของการใช้สภาพแวดล้อมและตัวแปรส่วนกลางใน Declarative Pipeline จากสิ่งที่ฉันสามารถบอกได้ว่าสภาพแวดล้อมนั้นคงที่หลังจากตั้งค่าแล้ว

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

ฉันได้รับข้อผิดพลาดต่อไปนี้จากโค้ดด้านบน: [Pipeline] Start of Pipeline [Pipeline] readMavenPom [Pipeline] End of Pipeline org.jenkinsci.plugins.workflow.steps.MissingContextVariableException: ฮัดสันคลาสบริบทที่จำเป็น FilePath หายไปบางทีคุณอาจลืมล้อมรอบ รหัสที่มีขั้นตอนที่ระบุเช่น: node
mancocapac

ไม่มันทำงานตามที่เป็นอยู่ มันเป็นท่อที่เปิดเผย ตัวแทนหมายความว่ามันสามารถทำงานบนโหนดใดก็ได้
pitchblack408

@ pitchblack408 คุณถูกต้องฉันมี [agent none] ที่ด้านบนสุดของไปป์ไลน์ ไม่แน่ใจว่าคุณหมายถึงอะไร: สภาพแวดล้อมคงที่หลังจากที่ตั้งค่าแล้ว? สามารถเปลี่ยนแปลงได้ภายในสคริปต์เช่นสคริปต์ {IMAGE = "newVal}
mancocapac

ตัวอย่างดูที่ IMAGE ไม่ใช่ตัวแปรที่สามารถหรือควรเปลี่ยนโดยท่อ ฉันเข้าใจว่าต้องถือว่าเป็นค่าคงที่หลังจากนิยามเป็นส่วนหนึ่งของสิ่งแวดล้อม
pitchblack408

0

คุณกำลังใช้Declarative Pipelineซึ่งต้องใช้script-stepเพื่อรันโค้ด Groovy นี่เป็นความแตกต่างอย่างมากเมื่อเทียบกับScripted Pipelineซึ่งไม่จำเป็น

เอกสารอย่างเป็นทางการกล่าวว่าต่อไปนี้:

ขั้นตอนสคริปต์ใช้บล็อกของ Scripted Pipeline และดำเนินการใน Declarative Pipeline

pipeline {
   agent none
   stages {
       stage("first") {
           script {
               def foo = "foo" 
               sh "echo ${foo}"
           }
       }
   }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.