jangan gagal jenkins build jika eksekusi shell gagal

132

Sebagai bagian dari proses build saya, saya menjalankan git commit sebagai langkah eksekusi shell. Namun, jika tidak ada perubahan di ruang kerja, Jenkins gagal membangun. Ini karena git mengembalikan kode kesalahan ketika tidak ada perubahan untuk dikomit. Saya ingin membatalkan pembangunan, atau hanya menandainya tidak stabil jika ini masalahnya. Ada ide?

Ben
sumber
Periksa apakah ada sesuatu untuk dikomit, dan hanya berkomitmen dalam kasus itu? stackoverflow.com/questions/5139290/…
Anders Lindahl

Jawaban:

210

Untuk menghentikan eksekusi lebih lanjut ketika perintah gagal:

command || exit 0

Untuk melanjutkan eksekusi ketika perintah gagal:

command || true

Pertanyaan Quolonel
sumber
12
Anda tidak perlu || exit 0dalam kasus pertama, jika commandpengembalian palsu eksekusi akan berhenti. Yang mengatakan, opsi kedua sangat membantu!
Nir Alfasi
20
@alfasin Anda tidak mengerti masalahnya. OP tidak ingin bangunan Jenkins gagal; kita harus exit 0karena kode keluar yang tidak nol akan gagal membangun.
Pertanyaan Quolonel
1
Saya melihat, dalam hal ini saya akan mengubah kata-kata dari: "Untuk menghentikan eksekusi lebih lanjut ketika perintah gagal:" menjadi: "Untuk menghentikan eksekusi lebih lanjut ketika perintah gagal dan menandai pekerjaan Jenkins sebagai berhasil:".
Nir Alfasi
1
@alfasin Sementara aku setuju bahwa Quolonel Questions, pernyataan tajam itu tidak profesional, dia benar dalam apa yang dia katakan. "exit 0" TIDAK akan menandai pekerjaan berhasil. Itu hanya akan menandai langkah build saat ini berhasil. Pekerjaan masih bisa gagal pada salah satu langkah membangun selanjutnya.
noamik
1
Terima kasih, ini berhasil! Ini sangat berguna untuk fitur "Execute shell on remote host using ssh" karena Anda tidak dapat menggunakan / bin / bash + e untuk tidak gagal pada kesalahan. Saya juga suka ide saya bisa memilih perintah mana yang tidak gagal membangun.
leeman24
80

Jenkins menjalankan langkah-langkah membangun shell menggunakan /bin/sh -xesecara default. -xartinya mencetak setiap perintah yang dieksekusi. -eberarti keluar dengan gagal jika ada perintah dalam skrip yang gagal.

Jadi saya pikir apa yang terjadi dalam kasus Anda adalah perintah git Anda keluar dengan 1, dan karena -eparam default , shell mengambil kode keluar non-0, mengabaikan sisa skrip dan menandai langkah sebagai kegagalan. Kami dapat mengkonfirmasi ini jika Anda dapat memposting skrip langkah pembuatan Anda di sini.

Jika itu masalahnya, Anda dapat mencoba untuk meletakkan #!/bin/shsehingga skrip akan dieksekusi tanpa opsi; atau melakukan set +ehal serupa di atas langkah build untuk mengesampingkan perilaku ini.


Diedit: Hal lain yang perlu diperhatikan adalah bahwa, jika perintah terakhir dalam skrip shell Anda mengembalikan kode non-0 , seluruh langkah build akan tetap ditandai sebagai gagal walaupun dengan pengaturan ini. Dalam hal ini, Anda bisa meletakkan echoperintah di bagian akhir untuk menghindari itu.

Pertanyaan terkait lainnya

Xiawei Zhang
sumber
41

Jika tidak ada yang mendorong git mengembalikan status keluar 1. Eksekusi langkah build shell ditandai sebagai gagal masing-masing. Anda dapat menggunakan ATAU pernyataan || (pipa ganda).

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

Itu berarti, jalankan argumen kedua jika pertama gagal (status keluar kembali> 0). Perintah kedua selalu kembali 0. Ketika tidak ada yang mendorong (status keluar 1 -> jalankan perintah kedua) gema akan kembali 0 dan membangun langkah berlanjut.

Untuk menandai build sebagai tidak stabil, Anda dapat menggunakan langkah post-build Jenkins Text Finder. Itu bisa melalui keluaran konsol, pola kecocokan (gema Anda) dan tandai bangunan tidak stabil.

Ecervena
sumber
27

Ada cara lain yang mulus untuk memberi tahu Jenkins agar tidak gagal. Anda dapat mengisolasi komit Anda dalam langkah build dan mengatur shell agar tidak gagal:

set +e
git commit -m "Bla."
set -e
joecks
sumber
2
Pastikan untuk menambahkan set -esetelah perintah yang ingin Anda jalankan terlepas dari kode keluar. Jika tidak, Anda bisa menjalankan perintah yang tidak Anda inginkan. Saya ingin menangani kesalahan sendiri, jadi saya melakukan sesuatu seperti: `set + e commit -m" bla "EXIT_CODE =" $ {?} "Set -e # handle logika kode
keluar`
8

Jenkins menentukan keberhasilan / kegagalan langkah demi langkah mengembalikan nilai langkah tersebut. Untuk kasus shell, itu harus menjadi pengembalian nilai terakhir. Untuk shell Bash Windows CMD dan (POSIX), Anda harus dapat mengatur nilai kembali secara manual dengan menggunakan exit 0sebagai perintah terakhir.

jerny
sumber
ini tampaknya tidak berfungsi untuk 'mengeksekusi kelelawar windows' yang memiliki 2 baris: git commit -m "message" exit 0
Ben
@Ben saya gunakan exit 0dengan "jalankan perintah batch windows" dalam beberapa build di instal Windows Jenkins saya, dan berfungsi seperti yang diharapkan. Sesuatu yang lain pasti sedang terjadi. Bisakah Anda memposting bagian yang relevan dari log konsol?
jwernerny
apakah Anda menggunakannya dengan git commit -m "bla" pada langkah pertama Anda? Saya mencoba membuat skrip kelelawar pada mesin secara manual, dan meletakkan gema dan keluar 0 setelah perintah git. Tak satu pun dari perintah lain dijalankan ketika tidak ada yang berkomitmen ...
Ben
Lihat jawaban dari @xiawei. Perilaku default Jenkins untuk mengeksekusi shell #!/bin/sh -xvyang mengakibatkan menghentikan skrip jika ada kesalahan ditemukan.
Steven the Easily Amused
8

Saya dapat mengaktifkannya menggunakan jawaban yang ditemukan di sini:

Bagaimana cara git tidak melakukan apa-apa tanpa kesalahan?

git diff --quiet --exit-code --cached || git commit -m 'bla'
Ben
sumber
1
Apa yang dilakukan di atas adalah: "Lakukan git diffperintah, dan jika itu gagal, lakukan git commitperintah. Pada dasarnya, hanya melakukan komit, jika git diffmenemukan sesuatu untuk dikomit. Namun, jawaban @jwernerny benar bahwa Anda harus dapat menambahkan exit 0pernyataan terakhir ke skrip apa pun untuk membuat Jenkins memperlakukannya sebagai sukses. Saya bisa memikirkan satu skenario di mana ini akan gagal jika Anda melakukan langkah shell Linux, tetapi dalam Batch ini harus selalu bekerja.
Slav
@ Ben Jenkins menjalankan langkah-langkah membangun shell menggunakan /bin/sh -xesecara default seperti yang disebutkan di sini (di tengah). Jadi Anda dapat mencoba meletakkan #!/bin/bashatau melakukan langkah set +edi atas langkah build untuk menimpa perilaku ini, yang akan melanjutkan sisa langkah bahkan satu perintah di dalam keluar dengan kode non-0
Xiawei Zhang
8

Pada pertanyaan (lebih umum) dalam judul - untuk mencegah Jenkins gagal, Anda dapat mencegahnya melihat kode keluar 1. Contoh untuk ping:

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

Dan sekarang Anda bisa mis. Mendapatkan hasil ping:

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

Tentu saja alih-alih ping ...Anda dapat menggunakan perintah apa pun - termasuk git commit.

Nux
sumber
6

Anda dapat menggunakan Plugin Text-finder . Ini akan memungkinkan Anda untuk memeriksa konsol keluaran untuk ekspresi pilihan Anda lalu tandai build as Unstable.

jphuynh
sumber
ini tampak menjanjikan, tetapi untuk beberapa alasan itu terus gagal membangun.
Ben
4

Untuk beberapa perintah shell, saya mengabaikan kegagalan dengan menambahkan:

set +e commands true

masukkan deskripsi gambar di sini

Megha
sumber
Saya mencegah unsetting -e secara umum. Jika Anda ingin mengabaikan nilai pengembalian perintah tertentu, Anda dapat menambahkan "|| true" atau sesuatu yang lebih bermakna dengan mengembalikan nilai true, seperti: stop-service.sh || Layanan echo sudah turun
Raúl Salinas-Monteagudo
3

Jika Anda menempatkan perintah ini ke dalam blok shell:

false
true

build Anda akan ditandai sebagai gagal (setidaknya 1 kode keluar bukan nol), sehingga Anda dapat menambahkan (set + e) ​​untuk mengabaikannya:

set +e
false
true

tidak akan gagal. Namun, ini akan gagal bahkan dengan (set + e) ​​di tempat:

set +e
false

karena perintah shell terakhir harus keluar dengan 0.

chenchuk
sumber
2

Berikut ini berfungsi untuk lincah dengan hanya melakukan jika ada perubahan. Jadi build hanya gagal jika komit gagal.

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

Satu lagi jawaban dengan beberapa tips, dapat bermanfaat bagi seseorang:

ingatlah untuk memisahkan perintah Anda dengan aturan berikut :

command1 && command2 - artinya, perintah2 itu akan dieksekusi, hanya jika command1 berhasil

command1 ;command2 - artinya, perintah 2 itu akan dieksekusi meskipun berdasarkan perintah1

sebagai contoh:

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

akan dieksekusi dengan set -edan echo 0perintah berhasil jika gmake testgagal (tes Anda gagal), sementara kode berikut dipotong:

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

sedikit salah dan perintah set -edan echo 0di && gmake test && set -e && echo 0akan dilewati, dengan println run_testspernyataan, karena gagal gmake testakan membatalkan jenkins membangun. Sebagai solusi Anda dapat beralih ke returnStatus:true, tetapi kemudian Anda akan kehilangan output dari perintah Anda.

Sysanin
sumber
0

Jawaban ini benar, tetapi tidak menentukan || exit 0atau || truemasuk ke dalam perintah shell . Berikut ini contoh yang lebih lengkap:

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

Di atas akan berfungsi, tetapi yang berikut akan gagal:

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

Mungkin sudah jelas bagi orang lain, tetapi saya membuang banyak waktu sebelum saya menyadari hal ini.

McLarge Besar
sumber