Devops’a nasıl devam ettik? — Build & Automation

Orhun Begendi
hesapkurdu-development
6 min readJul 11, 2018

Merhabalar herkese,

Önceki yazılarımızla başlattığımız dizimiz yeni yazımızla devam ediyor! Sonraki adım olarak; kurduğumuz build server’ından ayrıca Hesapkurdu.com Arge ekibi olarak seçiminin nasıl olduğunu nedenleriyle yazdığımızdan bahsedeceğim.

Konu bütünlüğü açısından Devops yaptık da n’oldu? ve Devops‘a nasıl başladık? — Analiz yazılarımızı okursanız iyi olur ama okumasanız da sadece bu aşamadaki yaşadığımız olayları anlayacaksınız.

Biz bu işe sıfırdan başladığımızı tekrardan vurgulamakta fayda var. Sıfırdan başlamıştık, analiz ettiki teşhisi koyduk ve işlerimizi hızlandırmamız gerekiyordu. Analiz’i manual yapmak, publish’leri manual, testler derken tonla manual iş yapılıyordu ve ciddi oranda iş gücü kaybı yaşıyorduk. Bizim bir startup olarak çok daha ileriye gitmemiz gerekiyor ama sürekli ayağımıza dolanan bu işlerden yeteri kadar hızlı gidemiyorduk. Aklımızda deli işler yapmak vardı ama bunlarla uğraşmaktan resmen tırım tırım gidiyorduk. Bu noktada bizim CI’lara, build server’a(lara) ihtiyacımız çok barizdi. Bunu yöneticilerimizle paylaştık ve her zamanki gibi durumun zaten farkındaydılar. Bütçe ayrıldı ve sonunda ellerimizi kirletmeye hazırdık…

Şu kızgın abiyi görmeden yaptıysanız birşeyler çok ama çok ters gidiyor olabilir!

Karar aşaması

Karar vermemiz gereken onlarca sorun vardı. Bizde en çok sıkıntı olan şeyleri çözecek olan CI Server’ını seçmek için incelemelere başladık. Bu aşamada bizim ortamımız için birkaç seçenek başı çekiyordu. Amazon’un Code Deploy’u, TeamCity, Circle CI ve Jenkins.

Değerlendirmeye bunlarla başladık. Eleme ve seçim aşamalarımızda yaşadığımız tecrübeler, ortamlarımıza uygunluğu, entegrasyon becerileri ve bütçemiz.

Şirketteki tecrübeli yazılımcılar Teamcity’i neredeyse en başta elemişti. Bize yetecek seviyede ücretsizdi, ancak artan ihtiyaçlar ve publish vb. olaylarda daha önce çok can sıkılan tanıdıklarımız vardı. Bizim daha fazla hakimiyete ihtiyacımız vardı.

AWS’de pay as you go şeklinde bir service sunan Code Deploy’u baya bir inceledik. Hem bizim kullandığımız git provider’ına entegre olmaması(daha sonra geldi ama hala tam değil) hem de her türlü entegrasyonu cloud üzerinden götürme çabası ve ücretlemesinden dolayı hesaplayınca ücret olarak ortalama bir fiyat ama bu paraya değmez dedik.

Circle CI benim kişisel olarak çok istediğim birşeydi, hem built-in olarak .Net ve türevlerini desteklemesi, cloud’da olması çok güzel bir özellikti. Her şeye entegreydi, golden boy diyebileceğimiz bir üründü ancak bunun fiyatı aradaki en pahalı seçenekti.

Jenkins ise tam ihtiyacımız olan şeydi. Open source ve esnek. Her türlü extension’ı ekleyebilir olmayanları yazabilirdik (ki yazdık). Hem de local olarak kullandığımız sunucular mevcuttu. Tek gereken bütçe kurulum için harcanacak insan eforuydu.

And the winner is …

Sonuç olarak fiyat ve özellikler konusunda bir değerlendirme yaptık. Dolayısıyla Jenkins’i seçtik. Güzel de oldu hani.

Entegrasyon ihtiyaçlarımız ve dertlerimiz

E tabii Jenkins’i seçtik seçmesine de bu kadar entegrasyon ihtiyacınız neydi diyebilirsiniz. Biraz bu konudan bahsetmek istedim. Daha önceden de bahsettiğim gibi biz .Net teknolojilerini ağırlıklı olarak kullanıyoruz. Burada Windows’da çalışması ve commandline desteği hatta powershell desteği tek başına her şeyi yaptırtabilirdi.

En öncelikli ihtiyacımız .Net’in kendi compiler’larını çalıştırmak en önemli özellik bunu tek başına command line (CLI)’la da yapabilirdik ama önemli bir nokta var. O kadar güzel extensionlar var ki olası herhangi bir hatayı mesela Culture’dan dolayı oluşabilecek özel karakterleri düşünmeden doğru düzgün kullanabiliyoruz ki bana göre çok önemli. Çünkü takımda herkes Türkçe yapılar kullanmıyor. Bir nokta, virgül, kesme işaretinin kabus olmasının önüne geçiyor. Meraklısı bakabilir (https://plugins.jenkins.io/msbuild)

Doğal olarak bir durum daha var ki o da dotnet core geçişi yaptığımız için dotnet cli desteği kaldı ki bunu da burada çözebiliyoruz.

İkinci en önemli bağlantı noktamız Sonarqube. Buna bağlanmak baştan çok basit olsa da configuration olmadan tam bir çöp ve kısa bir sürede işe yaramaz bir yapıya dönüşebiliyor. Burada ciddi sıkıntılar yaşadık, sürekli değişen MSbuild ve Sonarqube Server versiyonu hatta en çok Sonarqube’e data push’layan analyzer. Aman tanrım bu nasıl bir işkenceydi! İddia ediyorum tahmin edemezsiniz. Burada en önemli nokta şu; tek başına extension iş çözmüyor, tek başına Sonarqube dökümanları da iş çözmüyor, tecrübeyle sabittir. Sonarqube’ün bir analizi yapması dakikaları geçmesi, önceki versiyonla karşılaştırma sorunu ve yeni analiz sonuçları raporlamaları çok ciddi sıkıntılar. Bunu aşmanın çok basit taktikleri olsa da bu işleri her zaman Bamboo’yla yapmış biri olarak bu noktaların ne kadar kritik olduğunu bilmiyordum.

Çözüm de yine bizden geçti, çünkü konuyla alakalı bir satır yazı bulunabilecek bir konu değil. Versiyon sorununu auto versiyon deployer diye bir plugin’le çözdük. Bunun linkini vermiyorum çünkü deprecated oldu, hatta şimdi de Jenkins’de built-in feature olarak var ama o zaman yoktu 😕

Bu özellik şöyle bir şey güncellenen Msbuild vb. yapılara uygun bir versiyon her zaman çıkıyor, tabii buna uygun şekilde bir projeyle devam etmeniz gerekiyor. Her zaman use latest feature özelliği seçili olarak iş yapmak ne kadar cezalandırıcı bunu da gördük. Bu auto versiyon yapısıyla ihtiyacı olan Sonarqube ve msbuild gibi araçların versiyonunu otomatik kurup CI’ların bunları kullanmasını sağlıyor. Bu şekilde automation yapısı tekrar olması gerektiği gibi otomatik çalışabiliyor. Bu bize oh çektirdi ama bitmedi, Sonarqube’de versiyonlama yapmamız lazımdı. Bir önceki build farklarını görmeden analizin ne önemi var ki? Burada %Build_Number% variable’ını kullanarak Sonarqube analiz versiyonlaması yaptık.

Bu default olarak okunan project xml’i içinden geliyor ama bunu silip bunu commandline üzerinden geçerseniz o zaman size proje versiyonlaması yapabiliyor. Dışarıya bir ürün çıkarıp satan firmalar burada git versiyonlama ya da Jira üzerinden package number yapısını kullanabilir bu da aklınızda olsun. Şu an Jira kullanıyoruz ama o an için kullanmıyorduk, zamanı gelince o da buradan paylaşılacak.

sonar.projectVersion variable’ı hayatımızı kurtardı ve buna build numarasını geçince bir önceki analizle arasındaki farkı gördük iyiye mi gidiyoruz gördük.

Bunun bize bedeli önceden binbir zorlukla kurup tek tek versiyonlayarak analysis history’mizi kaybetmemize yol açtı. İyi ki çok o toplara girmeden bu entegrasyonu yaptık da hatayı başlarda yaptık. Tabii yol alıp belli bir kalite artışı yapmıştık ve Hesapkurdu Dev Origins’imizin origin kısmını kaybettik. (Zaten son dönemlerde tüm origins hikayeleri vasat değil mi?) Üzücü oldu ama n’abalım dedik.

Önemli olsa da nasılsa yapabildiğimiz kendi git entegrasyonumuzu yaptık. Burada pull request yapısını zaten kurmuştuk ve daha da benimseyerek hızlı bir şekilde bunu yaptık. Burada detaya girilecek pek bir şey yok sadece master branch CI’ları ile diğer branch’leri ayrı ayrı dinlemesi önemli. Yoksa olay bir anda karışabilir yani çok alakasız bir feature branch’ten master analizleriniz ya da test raporlarınıza girebilir ve bir anda yüzlerce hata görebilirsiniz. Kodunuza bağlı tabii, biz bunu daha önceden tecrübe ettiğimiz için dikkatli kurduk bu konu da sıkıntı yaşanabilecek bana göre tek noktayı da geçtik gittik. Biz feature branching yapısıyla devam ediyoruz, hatta bununla alakalı bir yazımız daha ilerleyen günlerde gelecek ;)

Package manager olarak bower ve nuget kullanıyoruz. Bunlar için extension arama, yazma vb. işlere girmedik. Zaten bunlar cli’dan çok sağlıklı çalışıyor. Nuget cli’ı nuget.org’dan indirdik, npm kurduk, hazır yazılı olan command’leri powershell’ini yazdık ve Jenkins’e build step olarak ekledik. En sıkıntısız kısım burası oldu. Hemen entegre edildi beş dakika da kullanıma hazır hale geldi, bi daha arkamıza bakmadık.

En son olarak Post Build aşamamız için bir notification işimiz vardı. Burada Slack ve email kanallarını kullandık. Build server işini yaptı mı yapmadı mı her dakika kontrol etmek mümkün değil böyle bir efor verilmez. Bunun için post build aşamasında hata olduğu zaman hata sebepleriyle beraber logu push yapan bir email yapısı kurduk. Ayrıca builder çalışma ve step by step olarak bildirim veren bir slack kanalı açtık. Buradan hem aşamaları yazılı olarak bildirimini alabiliyoruz. Slack entegrasyonu gayet basit ve slack’in kendi sağladığı bir plugin var. Burada oluşturduğu adresi pipeline’ınıza ilgili bölüme yazıp kaydetmek dışında bir iş yok. Email kısmında ise şöyle önemli bir ayrıntı var. Bizim gibi çok fazla mail atan bir firma iseniz ve reputation çok önemliyse yani email’lerin junk’a düşmesini istemiyorsanız, bu domain’de ve email server’ından yapmamanızda fayda var. Hatta bu konuyla alakalı bir yazımız var. Arge ekibimizin değerli üyesi Ezgi Peker tarafından kaleme alınan E-mail akış sorunlarımızı nasıl aştık? yazısını okuyabilirsiniz. Biz de atacağımız email’leri destekleyecek kadar bir servis entegre ettik. Burada emailjet provider’ı günde belirli bir sayıya kadar ücretsiz entegre edebilirsiniz. Zaten sadece hataları yolladığı için günde yüzlerce hata mail’i geliyorsa orada zaten bir sıkıntı olduğu aşikar değil mi?

Toparlarsak…

Biz Jenkins kullandık ve plugin havuzundan çok memnun kaldık. Zaten mevcutta sahip olduğumuz sunucularımız da olduğu için cloud kullanmadık. Hem ucuz oldu hem güçlü hem kontrollü. Entegrasyonlar can sıkıcı oldu ama çok şey öğrendik. Yedekli çalışın, hayatınızın merkezine koymadan önce tüm configuration’ın yedeğini alın ve haybeye her şeyin son sürümünü kullanmadan önce patch/version notlarını iyi okuyun. Burada sizin canınızı gerçekten yakacak şeyler barınabiliyor ya da her şeyinizi çözebilecek bir feature…

Dikkat ederseniz testlerden, onların CI’a entegrasyonlarından ve configuration’ları çok konu etmedim. Bunlar bu yazının konusu değil. Bu yazılarımız da çok yakında sizlerle. Eğer sizin de detayını merak ettiğiniz bir adım var ise bana mesaj atın lütfen anlatmaktan ve bunu yazılaştırmaktan mutluluk duyacağımdan emin olabilirsiniz.

Bir dahaki yazımıza kadar esenlikle kalın…

Saygılarımla.

--

--

Orhun Begendi
hesapkurdu-development

Senior Enginner, Tech Lead, Hardcore Developer, Software Craftsman.