Execute Shell, Jenkins'te bir derlemeyi nasıl / ne zaman başarısız olarak işaretler?


112

Bunun cevabını ararken bulduğum korku hikayeleri ...

Tamam, Jenkins'in yapması gereken her şeyi yapan bir .sh betiğim var:

  • SVN'deki kaynakları kontrol eder
  • projeyi inşa et
  • projeyi dağıtır
  • arkasını temizler

Yani Jenkins'te projeyi yalnızca komut dosyasını bir Kabuk Yürüt komutunda çalıştırarak 'inşa etmem' gerekiyor. Komut dosyası çalıştırılır (kaynaklar indirilir, proje inşa edilir / dağıtılır) ancak daha sonra yapıyı bir başarısızlık olarak işaretler: Oluşturma adımı 'Kabuğu çalıştır' derlemeyi başarısız olarak işaretledi Komut dosyası başarıyla çalıştırılmış olsa bile! Komut dosyasını şu şekilde kapatmayı denedim:

  • 0'dan çıkış (yine de hata olarak işaretler)
  • çıkış 1 (beklendiği gibi başarısızlık olarak işaretler)
  • hiç çıkış komutu yok (başarısızlık olarak işaretler)

Execute Shell, yapımı ne zaman, nasıl ve neden başarısız olarak işaretler?

Yanıtlar:


131

İlk önce fareyi aşağıdaki gri alanın üzerine getirin. Cevabın bir parçası değil, ama kesinlikle söylenmesi gerekiyor:

Tek başına "kullanıma alma, oluşturma, dağıtma" yapan bir kabuk betiğiniz varsa, neden Jenkins kullanıyorsunuz? Onu olduğu gibi yapan Jenkins'in tüm özelliklerinden bahsediyorsunuz. Bir cron veya SVN post-commit kancasına sahip olabilirsiniz, betiği doğrudan çağırın. SVN kontrolünü kendisi yapan Jenkins çok önemlidir. Derlemelerin yalnızca değişiklik olduğunda (veya isterseniz zamanlayıcıda veya manuel olarak) tetiklenmesini sağlar. Yapılar arasındaki değişiklikleri takip eder. Bu değişiklikleri gösterir, böylece hangi yapının hangi değişiklik kümesi için olduğunu görebilirsiniz. Yapım işlemlerinin başarılı veya başarısız olmasına neden olduğunda işleyicileri e-posta ile gönderir (yine tercih ettiğiniz şekilde yapılandırılır). Düzeltmeleri başarısız olan yapıyı düzelttiğinde işleyenlere e-posta gönderecektir. Ve daha fazlası. Yapıtları arşivleyen Jenkins, bunları derleme başına doğrudan Jenkins'ten erişilebilir kılar. SVN kontrolü kadar önemli olmasa da, bu bir kez daha onu Jenkins yapan şeyin ayrılmaz bir parçası. Konuşlandırmayla aynı. Tek bir ortamınız olmadığı sürece, dağıtım genellikle birden çok ortamda gerçekleşir. Jenkins, Promosyonları kullanarak belirli bir yapının (belirli SVN değişiklikleri ile) hangi ortamda dağıtıldığını takip edebilir. Tüm bunlardan vazgeçiyorsunuz. Görünüşe göre "Jenkins kullanmak zorundasın" söylendi ama gerçekten istemiyorsun ve bunu sadece patronlarını arkandan çekmek için yapıyorsun, sadece "evet, Jenkins'i kullandım" işareti koymak için

Kısa cevap şudur: Jenkin'in Execute Shell oluşturma adımının son komutunun çıkış kodu , Oluşturma Adımının başarısını / başarısızlığını belirleyen şeydir . - başarı, - başarısızlık. Unutmayın, bu, çalıştırılan tüm işin değil, oluşturma adımının başarısını / başarısızlığını belirler . Tüm iş çalışmasının başarısı / başarısızlığı, birden çok derleme adımından ve derleme sonrası eylemlerden ve eklentilerden de etkilenebilir.0anything else

Bahsetmiştiniz Build step 'Execute shell' marked build as failure, bu yüzden sadece tek bir inşa adımına odaklanacağız. Senin Eğer Yürütme kabuk yapı adım yalnızca shell script çağıran tek bir satır vardır, sonra kabuk komut çıkış kodu inşa adımının başarı / başarısızlık belirleyecektir. Eğer daha fazla hattınız varsa, sonra onlar başarısızlık neden olabilecek olanlar gibi kabuk komut yürütme, sonra dikkatlice, bunları gözden.

Son olarak, Google Test çalıştırıldıktan sonra Jenkins Build Script'in çıktığını buradan okuyun . Bu doğrudan sorunuzla ilgili değildir, ancak Jenkins'in Execute Shell oluşturma adımını başlatan kısmına , bir kabuk betiği olarak/bin/sh -xe

-eKabuk komut dosyası olacağı anlamına gelir çıkmak , sadece 1 komut başarısız olsa bile, yetmezliği olan bile o komutu için hata denetimi yapmak eğer (script çıkar çünkü sizin hata kontrolü ulaşmadan durdurur). Bu, genellikle başarısız olan komut için hata mesajını yazdıran (veya onu boşa yönlendirip başka yollarla işleyen) ve devam eden kabuk komut dosyalarının normal yürütülmesine aykırıdır.

Bunu aşmak set +eiçin, kabuk betiğinizin üstüne ekleyin .

Senaryonuzun yapması gereken her şeyi yaptığını söylediğiniz için, başarısız olan komut betiğin sonunda bir yerdedir. Belki son bir yankı? Veya bir yerlerde eserlerin kopyası? Tam konsol çıktısını görmeden sadece tahmin ediyoruz.

Lütfen job run'un konsol çıktısını ve tercihen kabuk betiğinin kendisini de gönderin, sonra size tam olarak hangi satırın başarısız olduğunu söyleyebiliriz.


6
Hala Jenkins'i kullanmamın sebebi benim için net değil ... Görünüşe göre tepedeki birisi bu betiğe zaten sahip olduğumuzu tam olarak anlamadı ve Jenkins'i kullanmamızda ısrar etti. Dilbert striptizinde olduğumu hissediyorum. -E bahşiş için teşekkürler. Sorunu çözdü
test cihazı

45
Jenkins'i kullanmak için hala iyi nedenler var: denetim izi, derleme durumu görünürlüğü vb. Halihazırda bir yapı betiğiniz varsa, Jenkins özelliklerinden yararlanmak için yeniden düzenlemeden önce onu Jenkins'e taşımak iyi bir ilk adımdır.
aehlke

3
Bu yanıtı çapraz bağlayarak serverfault.com/a/143576/186454 set + e ve set -e komut dosyanızın herhangi bir yerinde belirtilebilir. Dönen değer 0 değilse, aradaki herhangi bir kod
derlemede

2
kabuk betiğine karşı jenkins setinde çok iyi söylendi
pushya

yetkilendirilmiş erişim ve iş için bir kullanıcı arayüzü sağlamak için jenkins kullanıyoruz. Bir cron onu kesmez. Jenkins sadece sakat bırakmaz.
ffghfgh

90

Sorunuzun basit ve kısa cevabı

Lütfen "Kabuğu çalıştır" oluşturma adımınıza aşağıdaki satırı ekleyin.

#!/bin/sh

Şimdi size "Execute Shell" derleme işi için bu satırı neden gerekli kıldığımızı açıklayayım.

Varsayılan olarak Jenkins alır /bin/sh -xeve bu, -xher bir komutu yazdırır ve diğer seçenek -e, kabuğun herhangi bir komut sıfırdan farklı bir çıkış kodu ile çıktığında (herhangi bir komut başarısız olduğunda) hemen bir komut dosyası çalıştırmayı durdurmasına neden olur.

Yani ekleyerek #!/bin/shhiçbir seçenek olmadan çalıştırmanıza izin verecektir.


4
Upvoted. -Xe varsayılanını bilmiyordum.
Grep komutanım

Harika çalıştı! Bunu benim çok önemli olmayan adımlar, sadece benzer bir şey yapan find . -name 'bower_components' -exec rm {} \;ve bazı durumlarda başarısız olan bir temizleme adımı üzerinde kullanmak . Teşekkürler!
yorch

bu her şeyi temizledi - 'Ve diğer seçenek -e, kabuğun herhangi bir komut sıfırdan farklı çıktığında (herhangi bir komut başarısız olduğunda) çıkış kodu ile çıktığında hemen bir komut dosyası çalıştırmayı durdurmasına neden olur.'
Paramvir Singh Karwal

3

Benim fikrime göre, -ekabuğunuza olan seçeneği kapatmak gerçekten kötü bir fikir. Sonunda betiğinizdeki komutlardan biri, disk alanı yetersizliği veya ağ hataları gibi geçici koşullar nedeniyle başarısız olacaktır. -eJenkins olmadan fark etmez ve mutlu bir şekilde devam eder. Dağıtım yapmak için Jenkins'i kurduysanız, bu kötü kodun itilmesine ve sitenizin çökmesine neden olabilir.

Komut dosyanızda grep veya bul gibi hatanın beklendiği bir satır varsa || true, o satırın sonuna ekleyin . Bu, hattın her zaman başarılı olmasını sağlar.

Bu çıkış kodunu kullanmanız gerekiyorsa, komutu if ifadenize kaldırabilirsiniz:

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

Ya da geri dönüş kodunu cümlenizde yakalayabilirsiniz ||:

grep foo bar || ret=$?

1
Teşekkürler Bryan. Günümü kurtardın. Ayrıca, hem -x hem de -e'yi açmanın iyi bir fikir olduğunu düşünüyorum. Böylece jenkins günlüğünüzde görebilirsiniz.
Bikal Basnet

2

Sade ve basit:

Jenkins, inşa adımının (ki bu da bir betiktir) sıfırdan farklı bir kodla çıktığını görürse, yapı kırmızı bir topla işaretlenir (= başarısız).

Tam olarak bunun neden olduğu, derleme betiğinize bağlıdır.

Başka bir bakış açısından benzer bir şey yazdım ama yine de okumamıza yardımcı olabilir: Jenkins neden yapımın başarılı olduğunu düşünüyor?


0

Yani ekleyerek #!/bin/shhiçbir seçenek olmadan çalıştırmanıza izin verecektir.

Ayrıca Linux kölemde Jenkins master'dan bash betiğini çalıştırdığım bir sorunu çözmeme yardımcı oldu. #!/bin/bash"Execute Shell" bloğundaki gerçek betiğimin üzerine ekleyerek sorunumu çözdü, aksi takdirde hata veren bash kabuğunun Windows git tarafından sağlanan sürümünü çalıştırıyordu.


0

Jenkins ver. 1.635, böyle bir yerel ortam değişkenini göstermek imkansızdır:

$BUILD_NUMBER or ${BUILD_NUMBER}

Bu durumda, onu başka bir değişkene ayarlamanız gerekir.

set BUILDNO = $BUILD_NUMBER
$BUILDNO
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.