Execute Shell ทำเครื่องหมาย build เป็นความล้มเหลวใน Jenkins อย่างไร / เมื่อใด


112

เรื่องราวสยองขวัญที่ฉันพบขณะค้นหาคำตอบสำหรับเรื่องนี้ ...

ตกลงฉันมีสคริปต์. sh ซึ่งทำทุกอย่างที่เจนกินส์ควรทำ:

  • ตรวจสอบแหล่งที่มาจาก SVN
  • สร้างโครงการ
  • ปรับใช้โครงการ
  • ทำความสะอาดตัวเอง

ดังนั้นใน Jenkins ฉันต้อง 'สร้าง' โครงการโดยการเรียกใช้สคริปต์ในคำสั่ง Execute Shell สคริปต์ถูกรัน (มีการดาวน์โหลดแหล่งที่มาโปรเจ็กต์กำลังสร้าง / ปรับใช้) แต่จากนั้นจะทำเครื่องหมายบิลด์ว่าล้มเหลว: ขั้นตอนการสร้าง 'ดำเนินการเชลล์' ทำเครื่องหมายว่าบิลด์ล้มเหลวแม้ว่าสคริปต์จะรันสำเร็จก็ตาม! ฉันพยายามปิดสคริปต์ด้วย:

  • ออกจาก 0 (ยังคงทำเครื่องหมายว่าล้มเหลว)
  • ทางออก 1 (ทำเครื่องหมายว่าล้มเหลวตามที่คาดไว้)
  • ไม่มีคำสั่ง exit เลย (ทำเครื่องหมายว่าล้มเหลว)

เมื่อไหร่อย่างไรและทำไม Execute Shell จึงทำเครื่องหมายว่าบิลด์ของฉันล้มเหลว

คำตอบ:


131

อันดับแรกวางเมาส์เหนือพื้นที่สีเทาด้านล่าง ไม่ใช่ส่วนหนึ่งของคำตอบ แต่ต้องพูดอย่างแน่นอน:

หากคุณมีเชลล์สคริปต์ที่ "ชำระเงินสร้างปรับใช้" ทั้งหมดด้วยตัวเองทำไมคุณถึงใช้เจนกินส์ คุณกำลังกล่าวถึงคุณสมบัติทั้งหมดของ Jenkins ที่ทำให้มันเป็นอย่างนั้น คุณอาจมี cron หรือ SVN post -mit hook เรียกสคริปต์โดยตรง. Jenkins ดำเนินการชำระเงิน SVN ด้วยตัวเองเป็นสิ่งสำคัญ ช่วยให้การสร้างจะถูกทริกเกอร์เฉพาะเมื่อมีการเปลี่ยนแปลง (หรือบนตัวจับเวลาหรือด้วยตนเองหากคุณต้องการ) ติดตามการเปลี่ยนแปลงระหว่างการสร้าง จะแสดงการเปลี่ยนแปลงเหล่านั้นเพื่อให้คุณสามารถดูได้ว่าบิวด์ใดเป็นชุดของการเปลี่ยนแปลงใด อีเมลจะคอมมิตเมื่อการเปลี่ยนแปลงทำให้การสร้างสำเร็จหรือล้มเหลว (อีกครั้งตามที่กำหนดค่าตามที่คุณต้องการ) จะส่งอีเมลคอมมิตเมื่อการแก้ไขของพวกเขาแก้ไขบิลด์ที่ล้มเหลว และมากขึ้นเรื่อย ๆ Jenkins การเก็บถาวรสิ่งประดิษฐ์ยังทำให้พร้อมใช้งานต่อสร้างตรงจาก Jenkins แม้ว่าจะไม่สำคัญเท่ากับการชำระเงิน SVN แต่นี่เป็นอีกครั้งที่เป็นส่วนสำคัญของสิ่งที่ทำให้เจนกินส์ เช่นเดียวกันกับการปรับใช้ การปรับใช้มักจะเกิดขึ้นกับหลายสภาพแวดล้อมเว้นแต่คุณจะมีสภาพแวดล้อมเดียว Jenkins สามารถติดตามสภาพแวดล้อมที่มีการใช้งานบิลด์เฉพาะ (พร้อมชุดการเปลี่ยนแปลง SVN เฉพาะ) ผ่านการใช้โปรโมชั่น คุณอยู่ข้างหน้าทั้งหมดนี้ ดูเหมือนว่าคุณจะถูกบอกว่า "คุณต้องใช้เจนกินส์" แต่คุณไม่ต้องการจริงๆและคุณกำลังทำเพียงเพื่อให้ผู้บังคับบัญชาของคุณหายไปเพียงแค่ใส่เครื่องหมายถูก "ใช่ฉันใช้เจนกินส์"

คำตอบสั้น ๆ คือ: รหัสออกของคำสั่งสุดท้ายของขั้นตอนการสร้างExecute Shellของ Jenkin คือสิ่งที่กำหนดความสำเร็จ / ล้มเหลวของขั้นตอนการสร้างสร้างขั้นตอน0- ความสำเร็จanything else- ความล้มเหลว หมายเหตุนี้จะกำหนดความสำเร็จ / ล้มเหลวของการสร้างขั้นตอนที่ไม่ได้ทั้งวิ่งงาน ความสำเร็จ / ล้มเหลวของการรันงานทั้งหมดอาจได้รับผลกระทบจากขั้นตอนการสร้างหลายขั้นตอนและการดำเนินการหลังการสร้างและปลั๊กอิน

คุณได้กล่าวไว้Build step 'Execute shell' marked build as failureดังนั้นเราจะมุ่งเน้นไปที่ขั้นตอนการสร้างเพียงขั้นตอนเดียว หากขั้นตอนการสร้างเชลล์ Executeของคุณมีเพียงบรรทัดเดียวที่เรียกเชลล์สคริปต์ของคุณโค้ดออกของเชลล์สคริปต์ของคุณจะกำหนดความสำเร็จ / ล้มเหลวของขั้นตอนการสร้าง หากคุณมีบรรทัดมากกว่านี้หลังจากการเรียกใช้เชลล์สคริปต์ของคุณให้ตรวจสอบอย่างรอบคอบเนื่องจากเป็นบรรทัดที่อาจทำให้เกิดความล้มเหลว

สุดท้ายอ่านที่นี่Jenkins Build Script ออกหลังจากการดำเนินการทดสอบของ Googleเจนกินส์รูปร่างออกสคริปต์หลังจากที่การกระทำของไม่เกี่ยวข้องโดยตรงกับคำถามของคุณ แต่โปรดทราบว่าส่วนที่เกี่ยวกับเจนกินส์เปิดตัวขั้นตอนการสร้างExecute Shellเป็นเชลล์สคริปต์ที่มี/bin/sh -xe

-eหมายความว่าเชลล์สคริปต์จะออกกับความล้มเหลวแม้เพียง 1 คำสั่งล้มเหลวแม้ถ้าคุณทำการตรวจสอบข้อผิดพลาดสำหรับคำสั่งที่ (เพราะออกจากสคริปต์ก่อนที่มันจะได้รับการตรวจสอบข้อผิดพลาดของคุณ) สิ่งนี้ตรงกันข้ามกับการดำเนินการตามปกติของเชลล์สคริปต์ซึ่งโดยปกติจะพิมพ์ข้อความแสดงข้อผิดพลาดสำหรับคำสั่งที่ล้มเหลว (หรือเปลี่ยนเส้นทางไปเป็นโมฆะและจัดการโดยวิธีอื่น) และดำเนินการต่อ

หากต้องการหลีกเลี่ยงสิ่งนี้ให้เพิ่มset +eที่ด้านบนของเชลล์สคริปต์ของคุณ

เนื่องจากคุณบอกว่าสคริปต์ของคุณทำทุกอย่างที่ควรทำโอกาสที่คำสั่งจะล้มเหลวจะอยู่ที่ส่วนท้ายของสคริปต์ อาจจะเป็นเสียงสะท้อนสุดท้าย? หรือสำเนาสิ่งประดิษฐ์ที่ไหนสักแห่ง? หากไม่เห็นเอาต์พุตคอนโซลแบบเต็มเราก็แค่คาดเดา

โปรดโพสต์เอาต์พุตคอนโซลของการรันงานและโดยเฉพาะอย่างยิ่งเชลล์สคริปต์เองด้วยจากนั้นเราจะบอกคุณได้ว่าบรรทัดใดล้มเหลว


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

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

3
การเชื่อมโยงข้ามคำตอบนี้serverfault.com/a/143576/186454 set + e และ set -e สามารถระบุได้ทุกที่ในสคริปต์ของคุณ รหัสใด ๆ ที่อยู่ระหว่างนั้นจะไม่สร้างความล้มเหลวหากค่าที่ส่งคืนไม่ใช่ 0
Alex Skrypnyk

2
พูดได้ดีมากในเชลล์สคริปต์กับชุดเจนกินส์
pushya

เราใช้เจนกินส์เพื่อให้การเข้าถึงที่พิสูจน์ตัวตนและ UI สำหรับงาน cron จะไม่ตัดมัน Jenkins ไม่เพียง แต่เรียกใช้ cripts
ffghfgh

90

คำตอบที่ง่ายและสั้นสำหรับคำถามของคุณคือ

โปรดเพิ่มบรรทัดต่อไปนี้ในขั้นตอนการสร้าง "Execute shell" ของคุณ

#!/bin/sh

ตอนนี้ให้ฉันอธิบายเหตุผลที่เราต้องการบรรทัดนี้สำหรับงานบิลด์ "Execute Shell"

โดยค่าเริ่มต้น Jenkins ใช้/bin/sh -xeและนี่หมายความว่า-xจะพิมพ์คำสั่งแต่ละคำสั่งและตัวเลือกอื่น ๆ-eซึ่งทำให้เชลล์หยุดรันสคริปต์ทันทีเมื่อคำสั่งใด ๆ ออกโดยไม่เป็นศูนย์ (เมื่อคำสั่งใด ๆ ล้มเหลว) ออกจากรหัส

ดังนั้นการเพิ่ม#!/bin/shจะช่วยให้คุณดำเนินการโดยไม่มีตัวเลือก


4
โหวตแล้ว ไม่ทราบเกี่ยวกับค่าเริ่มต้น -xe เมื่อคอมแมน grep ของฉันไม่พบสตริงสคริปต์ทั้งหมดของฉันล้มเหลวเนื่องจาก grep ส่งคืนค่าที่ไม่ใช่ 0 กลับ :)
Somaiah Kumbera

ทำงานได้ดีมาก! ใช้มันกับขั้นตอนที่ไม่สำคัญของฉันซึ่งเป็นขั้นตอนการล้างข้อมูลที่เพิ่งทำสิ่งที่ชอบfind . -name 'bower_components' -exec rm {} \;และในบางกรณีก็ล้มเหลว ขอบคุณ!
ยอ

สิ่งนี้จะล้างทุกอย่าง - 'และตัวเลือกอื่น ๆ -e ซึ่งทำให้เชลล์หยุดการรันสคริปต์ทันทีเมื่อคำสั่งใด ๆ ออกโดยที่ไม่ใช่ศูนย์ (เมื่อคำสั่งใด ๆ ล้มเหลว) ออกจากโค้ด'
Paramvir Singh Karwal

3

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

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

หากคุณต้องการใช้รหัสทางออกนั้นคุณสามารถยกคำสั่งลงในคำสั่ง if ของคุณ:

grep foo bar; if [ $? == 0 ]; then ...    -->   if grep foo bar; then ...

หรือคุณสามารถจับรหัสส่งคืนใน||ประโยคของคุณ:

grep foo bar || ret=$?

1
ขอบคุณไบรอัน คุณช่วยวันของฉัน นอกจากนี้ฉันคิดว่าควรเปิดทั้ง -x และ -e เพื่อให้คุณเห็นในบันทึกของเจนกินส์
Bikal Basnet

2

เรียบง่าย:

ถ้าเจนกินส์เห็นขั้นตอนการสร้าง (ซึ่งเป็นสคริปต์ด้วย) ออกโดยมีรหัสที่ไม่ใช่ศูนย์บิลด์จะมีลูกสีแดงกำกับไว้ (= ล้มเหลว)

เหตุใดสิ่งนี้จึงขึ้นอยู่กับสคริปต์การสร้างของคุณ

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


0

ดังนั้นการเพิ่ม#!/bin/shจะช่วยให้คุณดำเนินการโดยไม่มีตัวเลือก

นอกจากนี้ยังช่วยฉันในการแก้ไขปัญหาที่ฉันเรียกใช้ bash script จาก Jenkins master บน Linux slave ของฉัน เพียงเพิ่ม#!/bin/bashด้านบนสคริปต์จริงของฉันในบล็อก "Execute Shell" มันช่วยแก้ปัญหาของฉันได้ไม่เช่นนั้นก็กำลังเรียกใช้งาน windows git เวอร์ชัน bash shell ที่ให้ข้อผิดพลาด


0

ใน Jenkins ver. 1.635 เป็นไปไม่ได้ที่จะแสดงตัวแปรสภาพแวดล้อมดั้งเดิมเช่นนี้:

$BUILD_NUMBER or ${BUILD_NUMBER}

ในกรณีนี้คุณต้องตั้งค่าในตัวแปรอื่น

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