ไปป์ไลน์ที่เขียนสคริปต์ของเจนกินส์หรือไปป์ไลน์ที่เปิดเผย


101

ฉันกำลังพยายามแปลงขั้นตอนการทำงานพื้นฐานของโครงการแบบเก่าเป็นไปป์ไลน์ตาม Jenkins ในขณะที่อ่านเอกสารฉันพบว่ามีไวยากรณ์สองแบบที่แตกต่างกันชื่อscriptedและdeclarative. เช่นการdeclarativeเปิดตัวไวยากรณ์ของเว็บ Jenkins เมื่อเร็ว ๆ นี้ (ปลายปี 2016) แม้ว่าจะมีการเปิดตัวไวยากรณ์ใหม่ Jenkins ก็ยังสนับสนุนไวยากรณ์แบบสคริปต์เช่นกัน

ตอนนี้ฉันไม่แน่ใจว่าสถานการณ์ใดทั้งสองประเภทนี้จะเข้ากันได้ดีที่สุด ดังนั้นจะdeclarativeเป็นอนาคตของท่อเจนกินส์หรือไม่

ใครก็ตามที่สามารถแบ่งปันความคิดเห็นเกี่ยวกับไวยากรณ์ทั้งสองประเภทนี้


2
ฉันไม่เห็นอะไรเลยเกี่ยวกับการเลิกใช้สคริปต์และนั่นอาจเป็นเรื่องที่น่าตกใจเมื่อพิจารณาถึงช่องว่างของคุณลักษณะระหว่างการประกาศและสคริปต์
Matt Schuchard

@MattSchuchard คุณยังดูเหมือนถูกต้อง 3 ปีต่อมาตอนนี้ ฉันได้ก้าวกระโดดเพื่อแก้ไขปัญหานั้นในตอนนี้
cellepo

คำตอบ:


90

เมื่อ Jenkins Pipeline ถูกสร้างขึ้นครั้งแรก Groovy ได้รับเลือกให้เป็นรากฐาน Jenkins ได้ส่งมอบเครื่องมือ Groovy ที่ฝังมาเป็นเวลานานเพื่อมอบความสามารถในการเขียนสคริปต์ขั้นสูงสำหรับผู้ดูแลระบบและผู้ใช้ นอกจากนี้ผู้ดำเนินการของ Jenkins Pipeline พบว่า Groovy เป็นรากฐานที่มั่นคงในการสร้างสิ่งที่เรียกว่า DSL "Scripted Pipeline"

เนื่องจากเป็นสภาพแวดล้อมการเขียนโปรแกรมที่มีคุณสมบัติครบถ้วน Scripted Pipeline จึงมอบความยืดหยุ่นและความสามารถในการขยายให้กับผู้ใช้ Jenkins เป็นจำนวนมาก โดยทั่วไปแล้วเส้นโค้งการเรียนรู้ Groovy ไม่เป็นที่ต้องการสำหรับสมาชิกทุกคนในทีมที่กำหนดดังนั้น Declarative Pipeline จึงถูกสร้างขึ้นเพื่อเสนอไวยากรณ์ที่ง่ายและมีความคิดเห็นมากขึ้นสำหรับการเขียน Jenkins Pipeline

ทั้งสองเป็นระบบย่อย Pipeline เดียวกันที่อยู่ข้างใต้ ทั้งคู่เป็นการใช้งาน "Pipeline as code" ที่ทนทาน พวกเขาทั้งสองสามารถใช้ขั้นตอนที่สร้างขึ้นในไปป์ไลน์หรือปลั๊กอินที่มีให้ ทั้งสองสามารถใช้ไลบรารีที่ใช้ร่วมกันได้

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

คัดลอกมาจากhttps://jenkins.io/doc/book/pipeline/syntax/#compare


5
ฉันพยายามย้ายงานไปป์ไลน์ที่เปิดเผยชุดหนึ่งไปยังไปป์ไลน์แบบมีสคริปต์เนื่องจากเป็น "ตัวเลือกที่เหมาะสำหรับผู้ใช้ระดับสูงและผู้ที่มีความต้องการที่ซับซ้อนมากขึ้น" แทบจะไม่มีเอกสารประกอบสำหรับไปป์ไลน์แบบสคริปต์ ไม่มี. มันแทบไร้ประโยชน์แบบนี้ นี่คือความแตกต่างใหญ่ที่ผู้คนควรตระหนักถึง
cauchy

6
@cauchy มีเอกสารเดียวกันสำหรับทั้งไปป์ไลน์แบบสคริปต์และแบบสำแดง แต่เนื่องจากสคริปต์นั้นมีไว้สำหรับผู้ใช้ขั้นสูงจึงไม่ใช่แบบที่แสดงก่อน แต่เอกสารทั้งหมดมีทั้งเอกสารและตัวอย่างไปป์ไลน์ที่มีสคริปต์และประกาศ คุณเพียงแค่ต้องสลับไวยากรณ์ scipted ด้านล่างแต่ละตัวอย่างเอกสารประกอบของไปป์ไลน์ที่เปิดเผย
Ilhicas

1
@Ilhicas ที่ไหน ไม่มี "สลับ" ในคู่มือผู้ใช้ คุณมีลิงค์หรือไม่? แม้แต่ขั้นตอนไปป์ไลน์บนไปป์ไลน์แบบสคริปต์ก็บอกว่าไม่มีความแตกต่างกับไปป์ไลน์ที่เปิดเผยและลิงก์ไปยังเอกสารไปป์ไลน์ที่เปิดเผยซึ่งทำให้เข้าใจผิด
cauchy

3
@cauchy ตัวอย่างjenkins.io/doc/book/pipelineด้านล่างมีการสลับไปที่jenkins.io/doc/book/pipeline/#ซึ่งขยายสคริปต์ที่เทียบเท่ากับไปป์ไลน์ที่เปิดเผย
Ilhicas

ปัญหาเกิดจากการที่คุณอ่านเอกสารไม่ถูกต้อง "นี่คือตัวอย่างของ Jenkinsfile ที่ใช้ไวยากรณ์ Declarative Pipeline ซึ่งสามารถเข้าถึงไวยากรณ์ที่เทียบเท่ากับ Scripted ได้โดยคลิกที่ลิงก์ Toggle Scripted Pipeline ด้านล่าง:" นี่อยู่ในเอกสารอย่างเป็นทางการ! อ่านแล้วคุณสามารถสร้างข้อความดังกล่าวได้ .. ถ้าพวกเขาถือเป็นจริง ..
Ilhicas

60

สิ่งที่จะต้องพิจารณาก็คือท่อที่เปิดเผยมีสคริปต์ () ขั้นตอน สิ่งนี้สามารถเรียกใช้ไปป์ไลน์ที่มีสคริปต์ได้ ดังนั้นคำแนะนำของฉันคือใช้ไปป์ไลน์ที่เปิดเผยและหากจำเป็นต้องใช้script()สำหรับไปป์ไลน์แบบสคริปต์ ดังนั้นคุณจะได้รับสิ่งที่ดีที่สุดจากทั้งสองโลก


3
คุณมีตัวอย่างของการใช้บล็อกสคริปต์ () ในไปป์ไลน์ที่เปิดเผยหรือไม่? ลิงก์นั้นไม่มีเลย
user2023861

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

สิ่งที่ฉันชอบคือไปป์ไลน์ Declaritive เหนือไปป์ไลน์แบบสคริปต์ตามที่ @CodyK กล่าวถึง ใช่ฉันยอมรับว่าเป็นสถานการณ์ที่ซับซ้อนบางอย่างซึ่งเราอาจใช้ไปป์ไลน์แบบสคริปต์ แต่การวางแผนที่ง่ายขึ้นจะช่วยลดความซับซ้อนลงได้เสมอและเวลาส่วนใหญ่จะปูทางไปสู่ไปป์ไลน์ที่เรียบง่ายขึ้น
NIK

18

ฉันเปลี่ยนไปใช้การประกาศเมื่อเร็ว ๆ นี้จากสคริปต์ด้วยตัวแทน kubernetes จนถึงเดือนกรกฎาคม '18 ไปป์ไลน์ที่เปิดเผยไม่สามารถระบุฝัก kubernetes ได้อย่างเต็มที่ อย่างไรก็ตามด้วยyamlFileขั้นตอนเพิ่มเติมคุณสามารถอ่านเทมเพลตพ็อดของคุณจากไฟล์ yaml ใน repo ของคุณได้

จากนั้นให้คุณใช้ปลั๊กอิน kubernetes ที่ยอดเยี่ยมของเช่น vscode เพื่อตรวจสอบเทมเพลตพ็อดของคุณจากนั้นอ่านลงใน Jenkinsfile ของคุณและใช้คอนเทนเนอร์ตามขั้นตอนตามที่คุณต้องการ

pipeline {
  agent {
    kubernetes {
      label 'jenkins-pod'
      yamlFile 'jenkinsPodTemplate.yml'
    }
  }
  stages {
    stage('Checkout code and parse Jenkinsfile.json') {
      steps {
        container('jnlp'){
          script{
            inputFile = readFile('Jenkinsfile.json')
            config = new groovy.json.JsonSlurperClassic().parseText(inputFile)
            containerTag = env.BRANCH_NAME + '-' + env.GIT_COMMIT.substring(0, 7)
            println "pipeline config ==> ${config}"
          } // script
        } // container('jnlp')
      } // steps
    } // stage

ดังที่ได้กล่าวไว้ข้างต้นคุณสามารถเพิ่มบล็อคสคริปต์ได้ ตัวอย่างเทมเพลตพ็อดที่มี jnlp และ docker แบบกำหนดเอง

apiVersion: v1
kind: Pod
metadata:
  name: jenkins-pod
spec:
  containers:
  - name: jnlp
    image: jenkins/jnlp-slave:3.23-1
    imagePullPolicy: IfNotPresent
    tty: true
  - name: rsync
    image: mrsixw/concourse-rsync-resource
    imagePullPolicy: IfNotPresent
    tty: true
    volumeMounts:
      - name: nfs
        mountPath: /dags
  - name: docker
    image: docker:17.03
    imagePullPolicy: IfNotPresent
    command:
    - cat
    tty: true
    volumeMounts:
      - name: docker
        mountPath: /var/run/docker.sock
  volumes:
  - name: docker
    hostPath:
      path: /var/run/docker.sock
  - name: nfs
    nfs:
      server: 10.154.0.3
      path: /airflow/dags

1
นี่เป็นคำตอบที่เป็นประโยชน์ที่สุดที่ฉันเคยเห็นมาตลอดทั้งปี: D ขอบคุณ
Trevor Rudolph

14

การประกาศดูเหมือนจะเป็นตัวเลือกที่พิสูจน์อนาคตได้มากกว่าและเป็นตัวเลือกที่ผู้คนแนะนำ เป็นเพียงโปรแกรมเดียวที่ Visual Pipeline Editor สามารถรองรับได้ รองรับการตรวจสอบความถูกต้อง และท้ายที่สุดแล้วก็มีพลังของสคริปต์มากที่สุดเนื่องจากคุณสามารถกลับไปใช้สคริปต์ได้ในบริบทส่วนใหญ่ บางครั้งมีคนคิดกรณีการใช้งานขึ้นมาซึ่งพวกเขาไม่สามารถทำในสิ่งที่ต้องการทำด้วยการเปิดเผยได้ แต่โดยทั่วไปแล้วผู้ที่ใช้สคริปต์มาระยะหนึ่งแล้วและช่องว่างของคุณลักษณะเหล่านี้มีแนวโน้มที่จะปิดลงในช่วงเวลาหนึ่ง

บริบทเพิ่มเติม: https://jenkins.io/blog/2017/02/03/declarative-pipeline-ga/


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

3
ฉันเห็นด้วยกับคุณ. คำตอบนี้ดีที่สุดในเวลาที่ฉันเขียน แต่ฉันดีใจที่ผู้เขียนเจนกินส์ได้บันทึกความแตกต่างได้ดีขึ้นในตอนนี้และทำให้ชัดเจนว่าสคริปต์จะไม่หายไปในเร็ว ๆ นี้ :)
burnettk

7

เอกสารของ Jenkins อธิบายและเปรียบเทียบทั้งสองประเภทได้อย่างเหมาะสม

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

ทั้งสองเป็นระบบย่อย Pipeline เดียวกันโดยพื้นฐานอยู่ข้างใต้ "

อ่านเพิ่มเติมที่นี่: https://jenkins.io/doc/book/pipeline/syntax/#compare


2
  1. ไปป์ไลน์ที่เปิดเผยถูกกำหนดไว้ภายในบล็อกที่มีข้อความว่า 'ไปป์ไลน์' ในขณะที่ไปป์ไลน์แบบสคริปต์ถูกกำหนดไว้ภายใน 'โหนด'
  2. ไวยากรณ์ - ไปป์ไลน์ที่เปิดเผยมี 'ขั้นตอน', 'ขั้นตอน'
  3. หากบิลด์ล้มเหลวตัวที่ประกาศจะให้ตัวเลือกในการรีสตาร์ทบิลด์จากขั้นตอนนั้นอีกครั้งซึ่งไม่เป็นจริงในอ็อพชันสคริปต์
  4. หากมีปัญหาใด ๆ ในการเขียนสคริปต์ผู้ประกาศจะแจ้งให้คุณทราบทันทีที่คุณสร้างงาน แต่ในกรณีของสคริปต์จะผ่านขั้นตอนที่เป็น 'โอเค' และแสดงข้อผิดพลาดบนพื้นที่งานซึ่งเป็น 'ไม่ตกลง'

คุณยังสามารถอ้างถึงสิ่งนี้ การอ่านที่ดีมาก -> https://e.printstacktrace.blog/jenkins-scripted-pipeline-vs-declarative-pipeline-the-4-practical-differences/ @ Szymon.Stepniak https://stackoverflow.com/users/ 2194470 / szymon-stepniak? tab = profile


0

ฉันก็มีคำถามนี้เช่นกันซึ่งทำให้ฉันมาที่นี่ ไปป์ไลน์ที่เปิดเผยดูเหมือนจะเป็นวิธีที่ต้องการอย่างแน่นอนและโดยส่วนตัวแล้วฉันพบว่ามันอ่านง่ายกว่ามาก แต่ฉันกำลังพยายามแปลงงาน Freestyle ที่มีความซับซ้อนระดับกลางเป็น Declarative และฉันพบปลั๊กอินอย่างน้อยหนึ่งปลั๊กอิน Build Blocker ที่ฉัน ไม่สามารถทำงานได้แม้ในบล็อกสคริปต์ในขั้นตอน (ฉันได้ลองใส่คำสั่ง "blockOn" ที่เกี่ยวข้องทุกที่โดยไม่มีโชคและข้อผิดพลาดในการส่งคืนมักจะเป็น "ไม่พบเมธอด DSL ดังกล่าว 'blockOn' ในขั้นตอนต่างๆ" .) ดังนั้นฉันคิดว่าการสนับสนุนปลั๊กอินเป็นปัญหาที่แยกต่างหากแม้ว่าจะมีบล็อกสคริปต์ (ใครบางคนโปรดแก้ไขฉันหากฉันผิดในเรื่องนี้) ฉันต้องใช้บล็อกสคริปต์หลายครั้งเพื่อให้ได้สิ่งที่ฉันคิดว่าเป็นพฤติกรรมง่ายๆ ทำงานเช่นการตั้งชื่อที่แสดงของบิลด์

เนื่องจากประสบการณ์ของฉันฉันกำลังเอนเอียงไปที่การทำซ้ำงานของฉันตามสคริปต์เนื่องจากการสนับสนุน Declarative ยังไม่ถึงจุดที่เราต้องการ แต่โชคไม่ดีเพราะฉันยอมรับว่านี่เป็นตัวเลือกที่พิสูจน์ได้ในอนาคตที่สุดและได้รับการสนับสนุนอย่างเป็นทางการ อาจพิจารณาจำนวนปลั๊กอินที่คุณต้องการใช้ก่อนตัดสินใจเลือก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.