เมื่อเขียนไปป์ไลน์ของเจนกินส์ดูเหมือนว่าไม่สะดวกที่จะยอมรับการเปลี่ยนแปลงใหม่แต่ละครั้งเพื่อดูว่ามันทำงานได้หรือไม่
มีวิธีดำเนินการในพื้นที่โดยไม่ต้องใช้รหัสหรือไม่
เมื่อเขียนไปป์ไลน์ของเจนกินส์ดูเหมือนว่าไม่สะดวกที่จะยอมรับการเปลี่ยนแปลงใหม่แต่ละครั้งเพื่อดูว่ามันทำงานได้หรือไม่
มีวิธีดำเนินการในพื้นที่โดยไม่ต้องใช้รหัสหรือไม่
คำตอบ:
คุณไม่สามารถเรียกใช้งานสคริปต์ไปป์ไลน์ในพื้นที่ได้เนื่องจากวัตถุประสงค์ทั้งหมดคือสคริปต์เจนกินส์ (ซึ่งเป็นเหตุผลหนึ่งว่าทำไมจึงเป็นการดีที่สุดที่จะรักษารหัสJenkinsfile
ย่อของคุณซึ่งจำกัด เกี่ยวกับคุณสมบัติของ Jenkins ไว้ตรรกะการสร้างจริงของคุณควรได้รับการจัดการกับกระบวนการภายนอกหรือเครื่องมือสร้างที่คุณเรียกใช้ผ่านบรรทัดเดียวsh
หรือbat
ขั้นตอน)
หากคุณต้องการที่จะทดสอบการเปลี่ยนแปลงที่จะJenkinsfile
มีชีวิตอยู่ แต่ไม่มีการกระทำมันใช้Replayคุณลักษณะเพิ่ม 1.14
JENKINS-33925ติดตามสิ่งที่ต้องการสำหรับกรอบการทดสอบอัตโนมัติ
ฉันมีทางออกที่ทำงานได้ดีสำหรับฉัน ประกอบด้วยเจนกินส์ในท้องถิ่นที่ทำงานในนักเทียบท่าและเบ็ดเว็บ git เพื่อกระตุ้นท่อในเจนกินส์ท้องถิ่นในทุกกระทำ คุณไม่จำเป็นต้องผลักดันไปยังที่เก็บ github หรือ bitbucket ของคุณอีกต่อไปเพื่อทดสอบไปป์ไลน์
สิ่งนี้ได้รับการทดสอบในสภาพแวดล้อมแบบลินุกซ์เท่านั้น
มันค่อนข้างง่ายที่จะทำให้งานนี้แม้ว่าคำสั่งนี้จะยาวหน่อย ขั้นตอนส่วนใหญ่อยู่ที่นั่น
สร้างไฟล์ชื่อ Dockerfile แทนตำแหน่งที่คุณเลือก ฉันวางมัน/opt/docker/jenkins/Dockerfile
ลงในนี้:
FROM jenkins/jenkins:lts
USER root
RUN apt-get -y update && apt-get -y upgrade
# Your needed installations goes here
USER jenkins
สร้างภาพ local_jenkins
สิ่งนี้คุณจะต้องทำเพียงครั้งเดียวหรือหลังจากที่คุณได้เพิ่มบางสิ่งลงใน Dockerfile
$ docker build -t local_jenkins /opt/docker/jenkins/
เริ่มและรีสตาร์ท local_jenkins
ในบางครั้งคุณต้องการเริ่มและเริ่มต้นเจนกินส์ใหม่ได้อย่างง่ายดาย เช่นหลังจากรีบูตเครื่องของคุณ สำหรับเรื่องนี้ฉันทำนามแฝงที่ฉันใส่ใน.bash_aliases
โฟลเดอร์บ้านของฉัน
$ echo "alias localjenkinsrestart='docker stop jenkins;docker rm jenkins;docker run --name jenkins -i -d -p 8787:8080 -p 50000:50000 -v /opt/docker/jenkins/jenkins_home:/var/jenkins_home:rw local_jenkins'" >> ~/.bash_aliases
$ source .bash_aliases # To make it work
ตรวจสอบให้แน่ใจว่า/opt/docker/jenkins/jenkins_home
โฟลเดอร์นั้นมีอยู่และคุณมีสิทธิ์ในการอ่านและเขียนของผู้ใช้
หากต้องการเริ่มหรือเริ่มเจนกินส์ของคุณเพียงแค่พิมพ์:
$ localjenkinsrestart
ทุกสิ่งที่คุณทำในเจนกินส์ในพื้นที่ของคุณจะถูกเก็บไว้ในโฟลเดอร์ / opt / docker / jenkins / jenkins_home และเก็บไว้ระหว่างการรีสตาร์ท
สร้างรหัสการเข้าถึง ssh ใน jenkins นักเทียบท่าของคุณ
นี่เป็นส่วนที่สำคัญมากสำหรับการทำงาน ครั้งแรกที่เราเริ่มต้นนักเทียบท่าคอนเทนเนอร์และสร้างเปลือก bash:
$ localjenkinsrestart
$ docker exec -it jenkins /bin/bash
ตอนนี้คุณได้ป้อนลงใน container docker ซึ่งเป็นสิ่งที่คุณเห็นjenkins@e7b23bad10aa:/$
ในเทอร์มินัลของคุณ แฮชหลังจาก @ จะแตกต่างกันอย่างแน่นอน
สร้างรหัส
jenkins@e7b23bad10aa:/$ ssh-keygen
กด Enter กับคำถามทั้งหมดจนกว่าคุณจะได้รับพรอมต์
คัดลอกรหัสไปยังคอมพิวเตอร์ของคุณ จากภายในตู้คอนเทนเนอร์นักเทียบท่าคอมพิวเตอร์ของคุณควรมีขนาด 172.17.0.1
jenkins@e7b23bad10aa:/$ ssh-copy-id user@172.17.0.1
user = ชื่อผู้ใช้ของคุณและ 172.17.0.1 เป็นที่อยู่ IP ไปยังคอมพิวเตอร์ของคุณจากภายในคอนเทนเนอร์นักเทียบท่า
คุณจะต้องพิมพ์รหัสผ่านของคุณ ณ จุดนี้
ตอนนี้ให้ลองวนลูปโดย ssh-ing ไปยังคอมพิวเตอร์ของคุณจากภายในคอนเทนเนอร์นักเทียบท่า
jenkins@e7b23bad10aa:/$ ssh user@172.17.0.1
คราวนี้คุณไม่จำเป็นต้องใส่รหัสผ่าน ถ้าคุณทำสิ่งผิดพลาดและคุณต้องลองอีกครั้ง
ตอนนี้คุณจะอยู่ในโฟลเดอร์โฮมของคอมพิวเตอร์ ลองls
ดูสิ
อย่าหยุดที่นี่เพราะเรามีห่วงโซ่ sshs ที่เราต้องออกไป
$ exit
jenkins@e7b23bad10aa:/$ exit
ขวา! ตอนนี้เรากลับมาแล้วและพร้อมที่จะดำเนินการต่อไป
ติดตั้ง Jenkins ของคุณ
คุณจะพบกับเจนกินส์ในท้องถิ่นของคุณในเบราว์เซอร์ของคุณได้ที่http: // localhost: 8787
ครั้งแรกที่คุณชี้เบราว์เซอร์ของคุณไปที่เจนกินส์ในพื้นที่คุณจะได้รับความช่วยเหลือด้วยตัวช่วยติดตั้ง ค่าเริ่มต้นถูกต้องตรวจสอบให้แน่ใจว่าคุณติดตั้งปลั๊กอินไปป์ไลน์ระหว่างการตั้งค่า
ตั้งค่าเจนกินส์ของคุณ
เป็นสิ่งสำคัญอย่างยิ่งที่คุณต้องเปิดใช้งานการรักษาความปลอดภัยตามเมทริกซ์บนhttp: // localhost: 8787 / configureSecurityและให้สิทธิ์กับตัวเองด้วยการเพิ่มเมทริกซ์และทำเครื่องหมายที่ช่องทั้งหมด (มีไอคอนติ๊กทุกช่องทางด้านขวาสุด)
Jenkins’ own user database
เป็นขอบเขตความปลอดภัยMatrix-based security
ในส่วนการอนุญาตUser/group to add:
และคลิกที่[ Add ]
ปุ่มPrevent Cross Site Request Forgery exploits
เครื่องหมาย (เนื่องจากเจนกินส์นี้สามารถเข้าถึงได้จากคอมพิวเตอร์ของคุณเท่านั้นจึงไม่ใช่เรื่องใหญ่อะไร)[ Save ]
และออกจากระบบของเจนกินส์และอีกครั้งเพื่อให้แน่ใจว่ามันใช้งานได้
หากคุณไม่จำเป็นต้องเริ่มต้นใหม่ตั้งแต่ต้นและล้าง/opt/docker/jenkins/jenkins_home
โฟลเดอร์ก่อนที่จะรีสตาร์ทเพิ่มผู้ใช้คอมไพล์
เราต้องอนุญาตให้ git hook ของเราเข้าสู่ระบบ Jenkins ในพื้นที่ของเราด้วยสิทธิ์น้อยที่สุด เพียงเพื่อดูและสร้างงานก็เพียงพอแล้ว ดังนั้นเราจึงสร้างผู้ใช้ที่เรียกว่าด้วยรหัสผ่านgit
login
นำเบราว์เซอร์ของคุณไปที่http: // localhost: 8787 / securityRealm / addUserและเพิ่มgit
เป็นชื่อผู้ใช้และlogin
รหัสผ่าน [ Create User ]
คลิกที่
เพิ่มสิทธิ์ให้กับผู้ใช้คอมไพล์
ไปที่หน้าhttp: // localhost: 8787 / configureSecurityในเบราว์เซอร์ของคุณ เพิ่มผู้ใช้คอมไพล์ในเมทริกซ์:
git
ในฟิลด์User/group to add:
และคลิกที่[ Add ]
ตอนนี้ถึงเวลาที่ต้องทำเครื่องหมายในช่องเพื่อให้ได้สิทธิ์น้อยที่สุดสำหรับผู้ใช้ git จำเป็นต้องใช้สิ่งเหล่านี้เท่านั้น:
ตรวจสอบให้แน่ใจว่าไม่มีการPrevent Cross Site Request Forgery exploits
ทำเครื่องหมายในช่องและคลิกที่[ Save ]
เราคิดว่าเรามีชื่อผู้ใช้user
และโครงการเปิดใช้งานคอมไพล์ของเราโดยJenkinsfile
มีชื่อเรียกproject
อยู่และตั้งอยู่ที่/home/user/projects/project
ในhttp: // localhost: 8787 Jenkins เพิ่มโครงการท่อส่งใหม่ ฉันตั้งชื่อมันว่า hookpipeline สำหรับการอ้างอิง
New Item
ในเมนูเจนกินส์hookpipeline
[ OK ]
Poll SCM
ในส่วนสร้างทริกเกอร์ เว้นช่วงเวลาว่างไว้Pipeline script from SCM
Repository URL
ช่องใส่user@172.17.0.1:projects/project/.git
Script Path
ช่องใส่Jenkinsfile
ไปที่/home/user/projects/project/.git/hooks
โฟลเดอร์และสร้างไฟล์ชื่อpost-commit
ที่มี:
#!/bin/sh
BRANCHNAME=$(git rev-parse --abbrev-ref HEAD)
MASTERBRANCH='master'
curl -XPOST -u git:login http://localhost:8787/job/hookpipeline/build
echo "Build triggered successfully on branch: $BRANCHNAME"
ทำให้ไฟล์นี้ทำงานได้:
$ chmod +x /home/user/projects/project/.git/hooks/post-commit
ทดสอบตะขอหลังการผูกมัด:
$ /home/user/projects/project/.git/hooks/post-commit
ตรวจสอบใน Jenkins ว่าโครงการ hookpipeline ของคุณถูกเรียกใช้หรือไม่
ในที่สุดก็ทำการเปลี่ยนแปลงโดยพลโครงการของคุณเพิ่มการเปลี่ยนแปลงและกระทำ สิ่งนี้จะทริกเกอร์ไปป์ไลน์ในเจนกินส์ใกล้บ้านคุณ
วันแห่งความสุข!
docker build -t local_jenkins /opt/docker/jenkins/Dockerfile
ด้วยdocker build -t local_jenkins /opt/docker/jenkins
เพราะ Docker บ่นเกี่ยวกับ "ไม่สามารถเตรียมบริบท: บริบทต้องเป็นไดเรกทอรี"
$ docker inspect jenkins | grep Gateway
ssh user@docker.for.mac.localhost
ใช้ที่อยู่ IP แทน นอกจากนี้ตรวจสอบให้แน่ใจว่าคุณเปิดใช้งานคุณสมบัติการเข้าสู่ระบบระยะไกลจากการตั้งค่าระบบ macOs -> เมนูโฟลเดอร์ที่ใช้ร่วมกัน
TL; DR
การทดสอบท่อแบบยาวของเจนกิ้นส์รุ่นยาวกลายเป็นความเจ็บปวดที่เพิ่มมากขึ้นเรื่อย ๆ ซึ่งแตกต่างจากวิธีการกำหนดค่างานประกาศคลาสสิกที่ผู้ใช้ถูก จำกัด กับสิ่งที่ UI สัมผัส Jenkins ใหม่ไปป์ไลน์เป็นภาษาการเขียนโปรแกรมเต็มเปี่ยมสำหรับกระบวนการสร้างที่คุณผสมส่วนที่เปิดเผยกับรหัสของคุณเอง ในฐานะนักพัฒนาที่ดีเราต้องการทดสอบหน่วยสำหรับโค้ดประเภทนี้เช่นกัน
มีสามขั้นตอนที่คุณควรปฏิบัติเมื่อพัฒนาท่อส่งเจนกินส์ ขั้นตอนที่ 1ควรจะครอบคลุม 80% ของกรณีการใช้งาน
ตัวอย่าง
pipelineUnit GitHub repo มีตัวอย่างสป็อคเกี่ยวกับวิธีการใช้กรอบการทดสอบเจนกินส์ท่อส่งหน่วย
ในขณะที่เขียน(สิ้นเดือนกรกฎาคม 2017)ด้วยปลั๊กอินBlue Oceanคุณสามารถตรวจสอบไวยากรณ์ของไปป์ไลน์ที่ประกาศได้โดยตรงในเครื่องมือแก้ไขภาพ ตัวแก้ไขใช้งานได้จาก Blue Ocean UI เมื่อคุณคลิก "กำหนดค่า" สำหรับโครงการ GitHubเท่านั้น(นี่เป็นปัญหาที่ทราบแล้ว
แต่ดังที่อธิบายไว้ในคำถามนี้คุณสามารถเปิดเครื่องมือแก้ไขการเรียกดู:
[Jenkins URL]/blue/organizations/jenkins/pipeline-editor/
จากนั้นคลิกที่ตรงกลางของหน้าและกดCtrl+S
สิ่งนี้จะเปิด textarea ที่คุณสามารถวางสคริปต์ไปป์ไลน์ เมื่อคุณคลิกที่อัปเดตหากมีข้อผิดพลาดทางไวยากรณ์ตัวแก้ไขจะแจ้งให้คุณทราบว่าข้อผิดพลาดทางไวยากรณ์นั้นอยู่ที่ไหน กดไลค์ในสกรีนช็อตนี้:
หากไม่มีข้อผิดพลาดทางไวยากรณ์ข้อความจะปิดและหน้าจะเห็นภาพขั้นตอนของคุณ ไม่ต้องกังวลว่าจะไม่บันทึกอะไรเลย (ถ้าเป็นโครงการ GitHub ก็จะยอมรับการเปลี่ยนแปลง Jenkinsfile)
ฉันใหม่กับเจนกินส์และนี่ค่อนข้างมีประโยชน์โดยที่ฉันไม่ต้องทำเจนกินส์ไฟล์หลาย ๆ ครั้งจนกระทั่งมันใช้งานได้ (น่ารำคาญมาก!) หวังว่านี่จะช่วยได้ ไชโย
สายไปงานเลี้ยงนิดหน่อย แต่นั่นเป็นเหตุผลว่าทำไมฉันถึงเขียนjenny
งานเล็ก ๆ น้อย ๆ ของขั้นตอนหลักของ Jenkinsfile ( https://github.com/bmustiata/jenny )
เท่าที่ฉันรู้ว่าปลั๊กอินท่อนี้เป็น "กลไก" ของกลไก Jenkinsfile ใหม่ดังนั้นฉันค่อนข้างมั่นใจว่าคุณสามารถใช้สิ่งนี้เพื่อทดสอบสคริปต์ในเครื่องของคุณ
ฉันไม่แน่ใจว่ามีขั้นตอนเพิ่มเติมที่จำเป็นเมื่อคุณคัดลอกลงใน Jenkinsfile หรือไม่อย่างไรก็ตามไวยากรณ์และอื่น ๆ ควรจะเหมือนกันทุกประการ
แก้ไข:พบการอ้างอิงใน "เครื่องยนต์" ตรวจสอบรายละเอียดคุณสมบัตินี้ย่อหน้าสุดท้ายรายการแรก
ในการตั้งค่าการพัฒนาของฉัน - หายไปบรรณาธิการ Groovy ที่เหมาะสม - การจัดการที่ดีของ Jenkinsfile ปัญหามาจากง่ายข้อผิดพลาดทางไวยากรณ์ เพื่อแก้ไขปัญหานี้คุณสามารถตรวจสอบ Jenkinsfile กับตัวอย่าง Jenkins ของคุณ (ทำงานที่$JENKINS_HTTP_URL
):
curl -X POST -H $(curl '$JENKINS_HTTP_URL/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)') -F "jenkinsfile=<Jenkinsfile" $JENKINS_HTTP_URL/pipeline-model-converter/validate
คำสั่งดังกล่าวเป็นรุ่นที่ได้รับการแก้ไขเล็กน้อยจาก https://github.com/jenkinsci/pipeline-model-definition-plugin/wiki/Validating-(or-linting)-a-Declarative-Jenkinsfile-from-the-command-line
นอกเหนือจากคุณสมบัติเล่นซ้ำที่คนอื่นพูดถึงแล้ว (เช่นเดียวกันกับประโยชน์ของมัน!) ฉันพบว่าสิ่งต่อไปนี้มีประโยชน์เช่นกัน:
ใส่รหัส SSH ของคุณลงในโปรไฟล์ Jenkins ของคุณจากนั้นใช้linter ที่ประกาศดังนี้:
ssh jenkins.hostname.here declarative-linter < Jenkinsfile
นี่จะทำการวิเคราะห์แบบคงที่ใน Jenkinsfile ของคุณ ในเครื่องมือแก้ไขที่คุณเลือกกำหนดแป้นพิมพ์ลัดที่เรียกใช้คำสั่งนั้นโดยอัตโนมัติ ใน Visual Studio Code ซึ่งเป็นสิ่งที่ฉันใช้ให้ไปที่ Tasks> Configure Tasks จากนั้นใช้ JSON ต่อไปนี้เพื่อสร้างคำสั่งValidate Jenkinsfile :
{
"version": "2.0.0",
"tasks": [
{
"label": "Validate Jenkinsfile",
"type": "shell",
"command": "ssh jenkins.hostname declarative-linter < ${file}"
}
]
}
ฉันใช้ replay ในอนาคตเพื่อทำการอัปเดตและเรียกใช้อย่างรวดเร็ว
ด้วยข้อ จำกัด บางประการและสำหรับท่อสคริปต์ฉันใช้วิธีนี้:
node('master') {
stage('Run!') {
def script = load('...you job file...')
}
}
def execute() {
... main job code here ...
}
execute()