- GitHub Actions'taki
shell, run: bloğunun nasıl çalıştırılacağını belirleyen bir ayardır; ancak gerçekte önceden tanımlı bir kabuk listesiyle sınırlı değildir ve $PATH içindeki yürütülebilir dosyaları da hedef alabilir
- Workflow içinde isteğe bağlıdır, action tanımında ise zorunludur; varsayılan değer runner'a göre değişir ve Linux/macOS'ta
bash, Windows'ta pwsh olur
shell: bash gibi açıkça belirtildiğinde GitHub, bash --noprofile --norc -eo pipefail gibi ek bayraklar ekler; ancak çalıştırılan hedefin kendisi yine herhangi bir program olabilir
- Yürütülebilir dosya tek bir dosya girdisini kabul etmiyorsa
shell değerine {0} argümanı eklenmelidir; GitHub bunu run bloğunu içeren geçici dosyanın yoluyla değiştirir
bash gibi tanıdık adlar da $PATH üzerinden çözümlendiği için, $GITHUB_PATH değişiklikleri veya sahte yürütülebilir dosyalar sonraki adımların çalışma biçimini etkileyebilir
shell anahtar sözcüğünün varsayılan davranışı
- GitHub Actions'taki
shell anahtar sözcüğü, belirli bir run: bloğunun hangi kabuk ile çalıştırılacağını belirtir
- Workflow içinde isteğe bağlıdır, ancak action tanımında zorunludur
- Varsayılan kabuk runner ortamına göre belirlenir
- Linux ve macOS'ta genellikle
bash
- Windows'ta genellikle
pwsh
Kabuk açıkça belirtildiğinde ek bayraklar
- GitHub,
defaults.run.shell belgesinde kabuk açıkça belirtilirse GitHub'ın seçtiği bayrakların da uygulanacağını belirtir
- Örneğin
shell: bash açıkça belirtilirse yürütme biçimi şu olur
bash --noprofile --norc -eo pipefail
- Yalnızca bu davranışa bakıldığında, GitHub'ın sınırlı bir geçerli kabuk değerleri listesi yönettiğini ve özel bayrakları yalnızca bu değerlere eklediğini düşünmek kolaydır
$PATH içindeki herhangi bir yürütülebilir dosya da kabuk olabilir
- Gerçekte
shell için $PATH içinde bulunan herhangi bir yürütülebilir dosya belirtilebilir
- GitHub,
run bloğunu belirtilen yürütülebilir dosyayla çalıştırır
- İlgili komut tek bir dosya girdisini doğrudan kabul etmiyorsa
shell değerine {0} eklenmelidir
- GitHub,
{0} ifadesini geçici dosya yoluyla değiştirir
- Bu geçici dosya, şablon genişletmesi uygulanmış
run bloğu içeriğini barındırır
C'yi adım çalıştırıcısı olarak kullanma örneği
- C derleyicisi/yorumlayıcısı gibi davranan araçlar da GitHub Actions adımlarını çalıştırmak için kullanılabilir
tcc -run {0} değerinin shell olarak verildiği örnek sorunsuz çalışır
- run: sudo apt install -y tcc
- shell: tcc -run {0}
run: |
#include <stdio.h>
int main() {
printf("Hello, world!\n");
return 0;
}
$GITHUB_PATH ile kabuk çözümlemesini değiştirme örneği
$GITHUB_PATH üzerinden $PATH dinamik olarak değiştirilirse, sonraki shell: bash beklenenden farklı bir yürütülebilir dosyayı gösterebilir
- Örnekte geçerli dizinde
bash adlı bir yürütülebilir dosya oluşturuluyor ve geçerli dizin $GITHUB_PATH içine ekleniyor
- Ardından
shell: bash kullanıldığında GitHub, $PATH içinde bulduğu sahte bash dosyasını çalıştırabilir
- run: |
touch ./bash
chmod +x ./bash
echo '#!/bin/sh' > ./bash
echo 'echo hello from fake bash' >> ./bash
echo "${PWD}" >> "${GITHUB_PATH}"
- run: |
echo "this doesn't do what you expect"
shell: bash
Güvenlik açısından beklenmedik nokta
- Bu davranışın güvenlik açısından ne kadar önemli olduğunu kesin olarak söylemek zor
- GitHub Actions içinde dosya yazmanın yürütmeye dönüştüğü zaten birçok yol var ve
GITHUB_ENV de bu örnekler arasında yer alıyor
- Yine de GitHub'ın
bash gibi iyi bilinen kabuk değerleri için bile $PATH araması yapması beklenmedik olabilir
- Özellikle iyi bilinen kabuk değerlerine göre komut satırı bayrakları enjekte ediliyorsa,
bashin /bin/bash gibi belirli bir yola sabitleneceği düşünülebilir
- Daha genel olarak, GitHub'ın yalnızca araç önbelleğine önceden kaydedilmiş araçlara izin verdiği sanılabilir; ancak gözlemlenen davranış
$PATH içindeki yürütülebilir dosyaları kullanma yönündedir
2 yorum
github/runner-image deposuna baksanız bile, doğrudan kullanılabilecek epey fazla paket kurulu oluyor....
İmajı oluşturunca 1GB zaten hemen doluyor....
Hacker News yorumları
-xbayrağını kullanmıştım; hata ayıklamada epey işe yarıyorhttps://github.com/jstrieb/just.sh/blob/2da1e2a3bfb51d583be0...
pipefail daha karmaşık hata durumlarını da engellemez. Örneğin yapılandırmadaki
curl ... | sudo tar ...adımındatarçıkarma hatası,sudohatası, kabuk hatası gibi durumlar görünür; ancakcurlbir ağ hatasıyla ortada başarısız olursatar,justikilisini yarım çıkarıp bırakabilir ve kabuk hemen sonlanabilir. Bu durumda hata mesajı olmaz; bozuk çalıştırılabilir dosya diskte kalır ve başarısızlığı atlama açıksa çalıştırılmaya bile çalışılabilirrepository_dispatcholay adında joker karakter kullanarak eşleştirme yapılabilmesiydion: repository_dispatch: - security_scan - security_scan::*gibi kullanılabiliyor. Yayın hattını merkezîleştirirseniz her deponun tanımlı yeniden kullanılabilir iş akışından geçmesini zorunlu kılabilirsiniz;security_scan::$product_name::$versiongibi bir olay gönderdiğinizde de merkezî yayın deposunun Actions sekmesinde hangi ürün ve sürümün iş akışının çalıştığını anlamak çok daha kolay olurBenzer bir şey yapmaya çalışan bir kuruluşa yeni katıldım; pratikte neredeyse işe yaramaz görünüyor. Şablonlar sık sık bozuluyor ve çoğu zaman kodun nasıl derlenmesi gerektiğine dair dokümantasyon olmadan belirli bir derleme yöntemini varsayarak yazılmış oluyor
Genelde mantığı Make gibi bir derleme sistemine koyup GitHub Actions’tan sadece çağırmayı ya da küçük bir komut satırı programı yazıp onu çağırmayı tercih ederim. Bunları yerelde hata ayıklamak CI’a göre çok daha kolay. İlginç bir numara ama nerede faydalı olur pek emin değilim
make buildvemake testcivarındaSatın alındıktan sonra bizi alan şirketin iş akışı dosyasına baktım; yüzlerce satırdı ve çok sayıda tekrar eden bölüm vardı. Eski kafalı diyebilirsiniz ama YAML kasabasından mümkün olduğunca çabuk çıkmak istiyorum
Fiilen kullanmayı planlamadığınız bir özellik olsa bile sistemde nelerin mümkün olduğunu bilmek güvenlik ve hata ayıklama açısından faydalıdır
Özellikle de kendi barındırdığınız runner’ları “keşfederken”
Sonraki kuşak, GitHub Actions ile yapılmış dağıtımlara disiplin getirmeleri istendiğinde titreyecek
Açıklayabilirseniz bizim kuruluşta muhtemelen hayata geçirebiliriz
bash’i kandırıp rastgele bir program çalıştırmasını da sağlayabilirsinizElle yazılmış birkaç komutu neredeyse aynen taşıyarak başlayan kabuk betiklerinin yüz satırı aşan canavarlara dönüştüğü çok oldu; her seferinde gerçek diziler ve tipler ile Python standart kütüphanesinin piller dahil özellikleri olsaydı diye düşündüm. Yine de şirketin derleme Action’ını elisp ile uygulamayacağım
ScriptHandlerHelpers.GetScriptArgumentsFormatmetodu üzerinden sunuluyor.ScriptHandler.csiçinde süreç ortamı ve argüman hazırlama kodu var; gerçek süreç başlatma kodu ise burada: https://github.com/actions/runner/blob/main/src/Runner.Worke...Genel olarak bu kodun basitliği beni iyi anlamda şaşırttı. Çok prosedürel ve çok sayıda uç durumu ele alıyor ama anlaşılması ve hata ayıklaması kolay görünüyor
Assembly de mümkün gibi
Ancak goeval henüz dosya girdisini doğrudan desteklemiyor, sadece standart girdiyi destekliyor; bu yüzden kabuk numarası gerekiyor. Şimdilik
go run github.com/dolmen-go/goeval@v1 - <<'EOF' ... EOFgibi bir yöntem kullanılıyor ve biraz boilerplate gerekiyor. Not: goeval’in yazarıyım[1] https://github.com/dolmen-go/goeval
go run github.com/dolmen-go/goeval@v1 - < file.goolmuyor mu?Bu bağlamda oyuncak bir projeyi tanıtacaksanız “hello yazdır” yerine daha ilgili bir örnek gösterseydiniz tıklamama gerek kalmazdı
run: pipeline.shgibi bir bash betiğine göre daha iyi yanı ne?Birden fazla işletim sistemi ve CPU mimarisinde işleri aynı anda çalıştırabilirsiniz; işi tetikleyen olay ve depo durumu hakkında bağlam bilgisi de alabilirsiniz. PR başına işler veya yayın otomasyonu için kullanışlıdır; linter’ın PR’daki her satırda sorunları göstermesi ya da test hatalarının bir web sayfasında render edilmesi gibi GitHub web UI ile de entegre olabilir. Değişmeyen dosyaları yeniden indirmemek veya yeniden derlememek için küçük bir cache de kullanılabilir. İdeal olarak mümkün olduğunca çok şeyi yerelde çalışan normal araçlara koymak, GitHub CI yapılandırmasının ise yalnızca tetikleyiciler, cache ve GitHub entegrasyonu için gereken yapıştırıcı kodu üstlenmesini sağlamak daha iyi
Başkalarının yaptığı GitHub Actions’ları pipeline’da kolayca kullanabilir, iş akışını modülerleştirebilir, bağımlılıkları ve paralel çalıştırmayı kontrol edebilirsiniz. Daha fazlası da vardır ama temel avantaj, bunları kendiniz uygulamak zorunda kalmamanız