อย่าล้มเหลวในการสร้างเจนกินส์หากการรันเชลล์ล้มเหลว


133

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


ตรวจสอบว่ามีอะไรที่ต้องกระทำและกระทำเฉพาะในกรณีเหล่านั้นหรือไม่? stackoverflow.com/questions/5139290/…
Anders Lindahl

คำตอบ:


213

หากต้องการหยุดการดำเนินการเพิ่มเติมเมื่อคำสั่งล้มเหลว:

command || exit 0

เพื่อดำเนินการต่อเมื่อคำสั่งล้มเหลว:

command || true


12
คุณไม่จำเป็นต้องใช้|| exit 0ในกรณีแรกหากcommandส่งกลับเท็จการดำเนินการจะหยุดลง ที่กล่าวว่าตัวเลือกที่สองมีประโยชน์มาก!
Nir Alfasi

20
@alfasin คุณไม่เข้าใจปัญหา OP ไม่ต้องการให้การสร้าง Jenkins ล้มเหลว เราต้องทำexit 0เพราะรหัสทางออกที่ไม่ใช่ศูนย์จะทำให้การสร้างล้มเหลว
คำถาม Quolonel

1
ฉันเห็นว่าในกรณีนี้ฉันจะเปลี่ยนถ้อยคำจาก: "เพื่อหยุดการดำเนินการเพิ่มเติมเมื่อคำสั่งล้มเหลว:" เป็น: "เพื่อหยุดการดำเนินการเพิ่มเติมเมื่อคำสั่งล้มเหลวและทำเครื่องหมายงานเจนกินส์ว่าสำเร็จ:"
Nir Alfasi

1
@alfasin ในขณะที่ฉันยอมรับว่า Quolonel Questions คำพูดที่รวดเร็วนั้นไม่เป็นมืออาชีพ แต่เขาก็พูดถูกในสิ่งที่เขาพูด "exit 0" จะไม่ทำเครื่องหมายว่างานสำเร็จ เพียงแค่ทำเครื่องหมายว่าขั้นตอนการสร้างปัจจุบันประสบความสำเร็จ งานยังคงล้มเหลวในขั้นตอนการสร้างถัดไปอย่างใดอย่างหนึ่ง
noamik

1
ขอบคุณที่ใช้งานได้! สิ่งนี้มีประโยชน์อย่างยิ่งสำหรับคุณลักษณะปลั๊กอิน "Execute shell บนโฮสต์ระยะไกลโดยใช้ ssh" เนื่องจากคุณไม่สามารถใช้ / bin / bash + e เพื่อไม่ให้เกิดข้อผิดพลาดได้ ฉันชอบความคิดที่ฉันจะเลือกคำสั่งที่ไม่สร้างความล้มเหลว
leeman24

81

Jenkins กำลังดำเนินการตามขั้นตอนการสร้างเชลล์โดยใช้/bin/sh -xeค่าเริ่มต้น -xหมายถึงการพิมพ์ทุกคำสั่งที่ดำเนินการ -eหมายถึงการออกด้วยความล้มเหลวหากคำสั่งใด ๆ ในสคริปต์ล้มเหลว

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

หากเป็นกรณีนี้คุณสามารถลองวาง#!/bin/shเพื่อให้สคริปต์ทำงานโดยไม่มีตัวเลือก หรือทำset +eสิ่งใดสิ่งหนึ่งที่คล้ายกันที่ด้านบนของขั้นตอนการสร้างเพื่อลบล้างพฤติกรรมนี้


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

อีกคำถามที่เกี่ยวข้อง


42

หากไม่มีสิ่งใดให้พุช git ส่งคืนสถานะ exit 1. ขั้นตอนการสร้างเชลล์ดำเนินการจะถูกทำเครื่องหมายว่าล้มเหลวตามลำดับ คุณสามารถใช้คำสั่ง OR || (ท่อคู่).

git commit -m 'some messasge' || echo 'Commit failed. There is probably nothing to commit.'

นั่นหมายความว่ารันอาร์กิวเมนต์ที่สองหากครั้งแรกล้มเหลว (ส่งคืนสถานะการออก> 0) คำสั่งที่สองจะคืนค่า 0 เสมอเมื่อไม่มีสิ่งใดให้พุช (ออกจากสถานะ 1 -> ดำเนินการคำสั่งที่สอง) echo จะส่งคืน 0 และสร้างขั้นตอนต่อไป

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


27

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

set +e
git commit -m "Bla."
set -e

2
ตรวจสอบให้แน่ใจว่าได้เพิ่มset -eหลังคำสั่งที่คุณต้องการเรียกใช้โดยไม่คำนึงถึงรหัสออก มิฉะนั้นคุณอาจจบลงด้วยการรันคำสั่งที่คุณไม่ได้ตั้งใจ ฉันต้องการจัดการข้อผิดพลาดด้วยตัวเองดังนั้นฉันจึงทำบางอย่างเช่น: `set + e คอมมิต -m" bla "EXIT_CODE =" $ {?} "set -e # จัดการตรรกะรหัสทางออก`
jcasner

8

เจนกินส์กำหนดความสำเร็จ / ความล้มเหลวของขั้นตอนด้วยค่าตอบแทนของขั้นตอน สำหรับกรณีของเชลล์ควรเป็นการส่งคืนค่าสุดท้าย สำหรับทั้ง Windows CMD และ (POSIX) Bash เชลล์คุณควรจะสามารถตั้งค่าการส่งคืนได้ด้วยตนเองโดยใช้exit 0เป็นคำสั่งสุดท้าย


ดูเหมือนจะใช้ไม่ได้กับ 'execute windows bat' ที่มี 2 บรรทัด: git comm -m "message" exit 0
Ben

@ Ben ฉันใช้exit 0กับ "execute windows batch command" ในหลาย ๆบิลด์ในการติดตั้ง Windows Jenkins ของฉันและทำงานได้ตามที่คาดไว้ อย่างอื่นจะต้องเกิดขึ้น คุณช่วยโพสต์ส่วนที่เกี่ยวข้องของบันทึกคอนโซลได้ไหม
jwernerny

คุณใช้มันร่วมกับคอมมิต -m "blah" ในขั้นตอนแรกหรือไม่? ฉันลองสร้างสคริปต์ bat บนเครื่องด้วยตนเองแล้วใส่ echo และ exit 0 หลังคำสั่ง git คำสั่งอื่น ๆ จะไม่ทำงานเมื่อไม่มีอะไรให้กระทำ ...
Ben

ดูคำตอบจาก @xiawei ลักษณะการทำงานเริ่มต้นของ Jenkins ในการรันเชลล์#!/bin/sh -xvซึ่งส่งผลให้หยุดสคริปต์หากพบข้อผิดพลาดใด ๆ
Steven the Easily Amused

8

ฉันสามารถทำงานนี้ได้โดยใช้คำตอบที่พบที่นี่:

จะคอมไพล์อะไรโดยไม่มีข้อผิดพลาดได้อย่างไร?

git diff --quiet --exit-code --cached || git commit -m 'bla'

1
สิ่งที่กล่าวมาข้างต้นคือ: " git diffคำสั่งDo และหากล้มเหลวให้ทำgit commitคำสั่งโดยทั่วไปจะกระทำเฉพาะในกรณีที่git diffพบสิ่งที่ต้องกระทำอย่างไรก็ตามคำตอบของ @jwernerny นั้นถูกต้องซึ่งคุณควรจะเพิ่มexit 0เป็นคำสั่งสุดท้ายได้ ไปยังสคริปต์ใด ๆ เพื่อให้ Jenkins ถือว่ามันประสบความสำเร็จฉันสามารถนึกถึงสถานการณ์หนึ่งที่สิ่งนี้จะล้มเหลวหากคุณทำขั้นตอนเชลล์ของ Linux แต่ใน Batch สิ่งนี้ควรใช้งานได้เสมอ
Slav

@ Ben Jenkins กำลังดำเนินการขั้นตอนการสร้างเชลล์โดยใช้/bin/sh -xeค่าเริ่มต้นตามที่กล่าวไว้ที่นี่ (ตรงกลาง) ดังนั้นคุณสามารถลองวาง#!/bin/bashหรือทำset +eด้านบนของขั้นตอนการสร้างเพื่อลบล้างพฤติกรรมนี้ซึ่งจะดำเนินการต่อในขั้นตอนที่เหลือแม้แต่คำสั่งเดียวใน exit ด้วยรหัสที่ไม่ใช่ 0
Xiawei Zhang

8

ในคำถาม (ทั่วไปมากขึ้น) ในชื่อ - เพื่อป้องกันไม่ให้ Jenkins ล้มเหลวคุณสามารถป้องกันไม่ให้เห็นรหัสทางออก 1 ตัวอย่างสำหรับ ping:

bash -c "ping 1.2.3.9999 -c 1; exit 0"

และตอนนี้คุณสามารถรับผลลัพธ์ของ ping:

output=`bash -c "ping 1.2.3.9999 -c 1; exit 0"`

แน่นอนแทนping ...คุณสามารถใช้คำสั่งใด ๆ (s) - git commitรวมทั้ง



6

คุณสามารถใช้ข้อความค้นหาปลั๊กอิน Unstableมันจะช่วยให้คุณสามารถตรวจสอบคอนโซลการส่งออกสำหรับการแสดงออกของคุณเลือกแล้วทำเครื่องหมายการสร้างเป็น


สิ่งนี้ดูมีแนวโน้ม แต่ด้วยเหตุผลบางประการทำให้การสร้างล้มเหลว
เบ็

4

สำหรับคำสั่งเชลล์หลายคำสั่งฉันละเว้นความล้มเหลวโดยการเพิ่ม:

set +e commands true

ใส่คำอธิบายภาพที่นี่


ฉันไม่สนับสนุนการไม่ตั้งค่า - โดยทั่วไป หากคุณต้องการละเว้นค่าส่งคืนของคำสั่งบางคำสั่งคุณสามารถเพิ่ม "|| true" หรือสิ่งที่มีความหมายมากกว่าที่ส่งคืนจริงเช่น: stop-service.sh || บริการก้องหยุดทำงานแล้ว
Raúl Salinas-Monteagudo

3

หากคุณใส่คำสั่งนี้ในบล็อกเชลล์:

false
true

บิลด์ของคุณจะถูกทำเครื่องหมายว่าล้มเหลว (อย่างน้อย 1 รหัสทางออกที่ไม่ใช่ศูนย์) ดังนั้นคุณสามารถเพิ่ม (set + e) ​​เพื่อเพิกเฉยได้:

set +e
false
true

จะไม่ล้มเหลว อย่างไรก็ตามสิ่งนี้จะล้มเหลวแม้ว่าจะมี (set + e) ​​อยู่:

set +e
false

เนื่องจากคำสั่งเชลล์สุดท้ายต้องออกด้วย 0


2

ต่อไปนี้ใช้ได้ผลกับเมอร์คิวเรียลโดยกระทำเมื่อมีการเปลี่ยนแปลงเท่านั้น ดังนั้นการสร้างจะล้มเหลวหากการคอมมิตล้มเหลวเท่านั้น

hg id | grep "+" || exit 0
hg commit -m "scheduled commit"

0

อีกหนึ่งคำตอบพร้อมเคล็ดลับอาจเป็นประโยชน์สำหรับใครบางคน:

อย่าลืมแยกคำสั่งของคุณด้วยกฎต่อไปนี้ :

command1 && command2 - หมายถึง command2 นั้นจะถูกเรียกใช้งานก็ต่อเมื่อ command1 สำเร็จ

command1 ; command2 - หมายถึงคำสั่ง 2 นั้นจะถูกเรียกใช้งานแม้จะเป็นผลลัพธ์ของ command1 ก็ตาม

ตัวอย่างเช่น:

String run_tests = sh(script: "set +e && cd ~/development/tests/ && gmake test ;set -e;echo 0 ", returnStdout: true).trim()
println run_tests 

จะดำเนินการสำเร็จด้วยset -eและecho 0คำสั่งหากgmake testล้มเหลว (การทดสอบของคุณล้มเหลว) ในขณะที่โค้ดต่อไปนี้ถูกตัดออก:

String run_tests = sh(script: "set +e && cd ~/development/tests/ && gmake test && set -e && echo 0 ", returnStdout: true).trim()
println run_tests 

ผิดเล็กน้อยและคำสั่งset -eและecho 0ใน&& gmake test && set -e && echo 0จะถูกข้ามไปพร้อมกับprintln run_testsคำสั่งเนื่องจากความล้มเหลวgmake testจะยกเลิกการสร้างเจนกินส์ เป็นวิธีแก้ปัญหาชั่วคราวคุณสามารถเปลี่ยนไปใช้returnStatus:trueแต่คุณจะพลาดผลลัพธ์จากคำสั่งของคุณ


0

คำตอบนี้ถูกต้อง แต่ก็ไม่ได้ระบุ|| exit 0หรือ|| trueไปภายในคำสั่งของเชลล์ นี่คือตัวอย่างที่สมบูรณ์ยิ่งขึ้น:

sh "adb uninstall com.example.app || true"

ข้างต้นจะใช้งานได้ แต่สิ่งต่อไปนี้จะล้มเหลว:

sh "adb uninstall com.example.app" || true

บางทีอาจจะเห็นได้ชัดสำหรับคนอื่น แต่ฉันเสียเวลาไปมากก่อนที่จะรู้เรื่องนี้

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