Husky ile Git Hook’larını Yakalamak ve Yönetmek

Tuğsan Ünlü
4 min readDec 27, 2020

--

Git hooks

Girizgah

Geliştirdiğimiz uygulamalarda kod kalitesini arttırmak için kimi denetlemeler yapmak, testlerimizi koşturmak, kullandığımız üçüncü parti bağımlılıklarda zafiyet taraması yapmak ve sair sebeplerden ötürü önceden tanımladığımız betikler (script) çalıştırmaya ihtiyaç duyuyoruz.

Tanımlanan bu betikleri her defasında elle çalıştırmak, özellikle yoğun tempoda çalışılan dönemlerde unutulmaya teşne olabiliyor. Kimi zaman da kasıtlı olarak ya da ihmal sonucu göz ardı ediliyor. Bunun önüne geçmek için süreci otomatikleştirmek ilk akla gelen çözüm. Asıl husus bu otomatikleştirmenin nerede yapılacağı.

Continuous integration yaşam döngüsü

İlgili kontrolleri yazdığımız kodun test ortamına veya canlı ortama çıkmadan hemen öncesine yani Continuous integration adımlarına konumlandırabiliriz. Bu tercihin şöyle olumsuz yönleri var.

  • Bir testimiz geçmediğinde veya kullandığımız bağımlılıklarda bir zafiyet tespit edildiğinde tamamen koptuğumuz sürece yeniden dahil olmak durumundayız. İlgili değişiklikleri yapmamızın üstünden belli bir zaman geçmiş ve yaptıklarımızı unutmuş olabiliriz. Tüm süreci her defasında yeniden hatırlamak ve yaşamak zorundayız.
  • Bulut hizmet sağlayıcıları CI/CD pipeline ücretlendirmelerini ekseriyetle çalışılan süre üzerinden yapıyor. Test çalıştırmak, kod denetlemek gibi işlemlerin sorumluluğunu her defasında CI araçlarına bırakırsak yekûn olarak baktığımızda günün sonunda ciddi bir maliyet oluşuyor.

İki durumda da zaman ve maliyet olarak gereksiz bir kayıp var.

Bunun alternatifi ilgili kontrolleri geliştirme ortamımızda yapmak. Fakat onun da şöyle dezavantajları var.

  • Geliştirme ortamımızda tüm kontrollerimizi yapıp ilgili değişiklikleri uzak sunucuya gönderdik diyelim. Fakat yazdığımız kod bir sebepten (kod review vs.) test ortamında veya canlı ortama derhâl gitmedi. Bu arada geçen meçhul zamanda dış ortama bağlı şartlarda değişiklikler olabilir. Kodumuz değişmeyeceği için testlerimiz yine geçer fakat bir güvenlik zafiyetinden haberdar olmamız mümkün olmaz.
  • Kodumuz değişmez dedik ama bir başka arkadaşımız kodumuzda değişiklik yapmış ve kendi geliştirme ortamında çalıştırması gereken testleri ihmal etmiş olabilir. Bundan da maalesef haberimizin olması ve hatalı kodun canlı ortama çıkmasına engel olmamız mümkün değil.

O yüzden en sonda söyleyeceğimi başta söylemiş olayım. Aynı kontrolleri hem geliştirme ortamımızda hem de CI araçlarında yapmak zaman, maliyet ve tutarlılık bakımından pratik bir yöntem olacaktır. Önem derecesine göre kimi kontrolleri CI sürecine hiç dahil etmemek de tartışılabilir fakat onu başka bir yazının konusu yapayım.

Husky 🐶

Tekrar geliştirme ortamımıza dönelim. İlgili kontrolleri elle çalıştırmanın unutulmaya teşne olduğundan bahsediyorduk. Tam burada imdadımıza Husky yetişiyor. Husky, JavaScript ekosistemi içerisinde geliştirilen uygulamalardapre-commit, post-commit, pre-push, commit-msg gibi tüm Git hook’larını yakalamamızı ve yönetmemizi sağlayan bir araç. Bu sayede bir anda envaitürlü senaryoyu uygulayabilir hâle geliyoruz. Kullanımı da oldukça basit, hemen başlayalım ve Husky’i projemize dahil edelim.

npm install husky 

Akabinde kod formatımızın uygunluğunu kontrol etmesi için Prettier’ı da projeye dahil edelim.

npm install prettier

Konumuz Husky olduğu için Prettier’a herhangi bir özel kural tanımlamayıp varsayılan yapılandırmasıyla bırakacağız. Prettier’ın CLI aracı check isimli bir parametre alıyor. Bu parametrede hangi dizindeki hangi dosyalar için format kontrolü yapılacağını belirtiyoruz. Bu kontrolü tetikleyecek bir betik oluşturup package.json dosyasındaki scripts objesine ekliyoruz.

package.json’da script tanımlaması

Artık npm run prettier komutunu çalıştırdığımızda Prettier, JavaScript dosyalarımızın formatını kontrol edecek. Hemen içerisinde girintileme stil hatası olan bir dosya oluşturup ardından Prettier’ı çalıştıralım.

Hatalı stilde girintilemeye sahip dosya (index.js)
Prettier hatalı format uyarısı

Görüleceği üzere Prettier dosyamızdaki hatayı buldu ve bizi uyardı. Şimdi bu süreci commit öncesini yakalamamızı sağlayan pre commit hook’u içerisinde otomatikleştirelim.

Bunun için projemizin ana dizinine husky.config.js isminde bir dosya oluşturup hangi hook’da hangi komutun çalıştırılması gerektiğini CommonJS formatında yazarak belirtelim.

husky.config.js

Ardından yaptığımız değişiklikleri commit etmeye çalışalım.

pre-commit hook’unda hata alan kontrol

Husky, Git’in pre commit hook’unu yakaladı ve commit öncesinde belirttiğimiz gibi npm run prettier komutunu çalıştırdı. Prettier’ın format doğrulaması başarılı olamadığı için işlem yarıda kesildi ve herhangi bir commit atılmadı.

pre-commit hook’undan geçen kontrol

İlgili dosyadaki girintilemeyi düzeltip yeniden commit etmeye çalıştığımızda herhangi bir hata almadan işlemi tamamlayabildik.

Aslında Husky’nin yaptığı kabaca bundan ibaret. Husky’nin bu kabiliyeti, Git hook’larının marifetleriyle birleştirildiğinde yukarıda da söylediğim gibi envaitürlü senaryo canlanıyor insanın zihninde. Neler yapılabilir mesela? commit-msg hook’unda bir önceki yazımda bahsettiğim şekilde konvansiyona uygun commit mesajları yazılması sağlanabilir. Yine pre-commit hook’unda birim testler koşturulabilir veya NPM Audit çalıştırılabilir. pre-push ile değişiklikler uzak sunucuya gönderilmeden önce atlanmaması gereken son kontroller yapılırkenpre-rebase ile rebase öncesi ortam hazırlanabilir. Bu noktada yapılabilecekler tamamen ihtiyaçlara ve geliştiricilerin hayal gücüne kalmış durumda.

Tahmin ediyorum 2020'nin son yazısı bu oldu. Fena bir kapanış olmadığı kanaatindeyim. Yeni senede daha sık görüşmek üzere!

Kaynaklar

https://typicode.github.io/husky
https://github.com/typicode/husky

--

--

Tuğsan Ünlü
Tuğsan Ünlü

Written by Tuğsan Ünlü

Senior Application Architect, Technical Product Owner @Akbank — tugsanunlu.com

No responses yet