Jenkins’de CI/CD süreçleri ve Pipeline Mantığı

Elman Badalov
5 min readNov 23, 2020

Selamlar ben Elman. Bestcloudfor.me teknoloji şirketinde Cloud Native Engineer olarak çalışmaktayım. DevOps kültürünün hızla yayıldığı dönemde sık sık karşılaştığımız otomasyon süreçlerinin farklı bir boyutunu bugün sizlere anlatmaya çalışacağım. Bu mimaride çalışan bir çok mühendis Jenkins tool’unu otomasyon süreçlerinde pipeline job’ları oluşturmak ve bu süreci daha da mükemmel bir şekilde yönetmek için kullanıyor. Peki ya Jenkins nedir?, Hayatımızda bize hangi kolaylıkları sağlıyor?, CI/CD süreçleri nasıl işliyor?, Pipeline mantığı nedir ve nasıl Jenkins job hazırlanabilir?. Sizler için bu soruları cevaplayarak ve örnekler sunarak yazımı bitirmeyi hedefliyorum. Hazırsak başlayalım :)

Jenkins nedir?

İlk adımda “Jenkins nedir?” ve “Jenkins bize hangi kolaylıkları sağlıyor?” sorularına cevap vermek istiyorum.

Jenkins java ile yazılmış açık kaynak kodlu bir otomasyon sunucusudur. Yazılım geliştirme süreçlerini otomatize etmemize yarar.

2005 yılında Sun Microsystems’te çalışan ve bir geliştirici olan Kohsuke Kawaguchi tarafından Hudson isimli bir CI aracı geliştirildi. 2009 yılında Oracle’ın Sun’ı satın almasıyla birlikte, geliştiriciler ve Oracle arasında çıkan anlaşmazlıklar neticesinde, geliştiriciler, Hudson kodunu alarak farklı bir proje oluşturdular. Böylece Jenkins ortaya çıkmış oldu.

Kodu yazarız, tamam olduğunu düşündüğümüzde, commit ederiz. Jenkins bu noktada devreye girerek, kodu otomatik olarak derler, varsa testleri çalıştırır. Kod ile ilgili problemler varsa en basitinden derlenmiyorsa, kod standartlarına aykırı bir durum varsa veya yazdığımız testler hata veriyorsa bize sonucunu gösterir ve mail atarak o an çalışan test’le ilgili bilgilenmemizi sağlar.

Bahsettiğim şey aslında sürekli entegrasyon (continuous integration) mevzusudur. Bu kavramı sıklıkla duyuyoruz. İngilizce kısaltması CI olan sürekli entegrasyon yabancı kaynaklarda karşılaşılan ve sürekli gündemde olan bir konudur. O yüzden CI mantığından da bahsetmekte fayda var.

Tabiki Jenkins’e giriş yapmışken burada kullanılan ve Jenkins’in araçlardan da bahsetmemizde fayda var. Burada 3 araçtan bahsedeceğim. Job, Node ve Plugin.

Job: Bir Jenkins projesidir. Otomatize etmek istediğimiz işleri burada belirleriz. Örneğin, job’a config üzerinden şu repository’i çek, şu şartlarda build et, şu testleri çalıştır ve belirlenen kişilere mail at gibi işlemleri söyleyebiliriz. Jenkins, manuel olarak yapılan build, test ve deploy gibi işlemleri uygular ve bu süreçte yaşanabilecek tüm aksaklık ve iletişim eksikliğini en aza indirir. Jenkins eğer build veya test aşamasında herhangi bir hata ile karşılaşırsa deploy işlemini gerçekleştirmez ve geliştiriciyi bilgilendirir.

Node: job’un üzerinde çalıştığı sunucuyu ifade eder. Testleri başka bir bilgisayarda koşmak istediğimizde node oluşturur ve bağlantı için gerekli şartları gerçekleştirdikten sonra node’da testlerimizi koşabiliriz.

Plugin (eklenti): Jenkins saf haliyle yüklenir, ihtiyacımıza göre plugin yükler ve bunları kullanılırız. Örneğin, Job çalıştıktan sonra mail atması için “Email Extension” eklentisini yüklemeli ve post-build adımında kullanmalıyız.

Pipeline: işlerin ardışık bir sırada yapılması, bir işlemin çıktısının sonraki gelen işlemin girdisi olması anlamına gelir. Örneğin, Bir test adımının başarısız olması durumunda diğer bir testin hiç başlamaması gibi.

Şimdi ise “CI/CD süreçleri nasıl işliyor?” konusuna daha detaylı değinmek istiyorum.

Sürekli Entegrasyon (Continuous Integration — CI)

Sürekli entegrasyon, geliştiricilerin kodlarının periodik olarak ortak bir yere (depo — repository) işlenmesi, bununla birlikte bir araç tarafından otomatik olarak derlenmesi ve kalitesinin denetlenmesi. Böylece hatalı bir durum varsa sorun hemen tespit edilecektir. Bu sayede otomasyon daha doğru ve hatasız bir şekilde devam ettirilecektir.

Unutmamanız gereken en önemli şey, sürekli entegrasyonun en büyük amacının hataların hızlı bir şekilde ortaya çıkarılmasıdır.

Hatalar içerisinde derleme hataları olabilir, başarısız (birim, arayüz, entegrasyon) testler olabilir veya statik kod analizinde ortaya çıkan eksiklikler olabilir.

Jenkins, dünyada en çok kullanılan CI aracıdır.

Jenkins’in “Hayatımızda bize hangi kolaylıkları sağlıyor?” konu başlığına değinirsek şunları görmüş olacağız. Başlıklar halinde ifade etmem gerekirse, Jenkins’i şu sebeplerle kullanırız:

  1. Projemizi derlemek için
  2. Otomatik olarak testlerin çalışmasını sağlamak, böylece hataları en kısa zamanda teşhis edip, zamanında müdahale etmek için
  3. Statik kod analizi yapmak için

CI süreçlerinden bahsettiğimize göre şimdi de CD (Continuous Delivery – Sürekli Teslimat) süreçlerine değinmek istiyorum.

Sürekli Teslimat (Continuous Delivery — CD)

Kodun her an kurulumunun yapılabilir halde olmasını sağlamak diye tarif edebiliriz.

Bu pratiği uygulamak için, canlı ortama benzer bir staging (test) ortamına yazılımın periyodik olarak sürekli dağıtımının yapılması gerekmektedir.

Sürekli teslimat pratiği, kodun sağlıklı, çalışabilir bir düzeyde olduğunun sağlanması olarak görebiliriz. Aynı zamanda CD sürecinin, sürekli entegrasyondan daha kapsamlı testlerden ve adımlardan oluştuğunu görebiliriz.

Şimdi ise yazımın “Pipeline mantığı nedir ve nasıl Jenkins job hazırlanabilir?” isimli son başlığına değinmek istiyorum.

Pipeline Mantığı

Yukarıda da bahsettiğimiz CI/CD süreçleri aslında pipeline mantığında çalışır ve burada adımlar sıralı bir şekilde bir birine bağlı olarak devam eder. Örneğin, build aşamasından geçemeyen bir script deploy işlemine geçmeden durdurulur ve mail olarak hatalı işlem yapıldığını bildirir.

Jenkins Pipeline tanımı JenkinsFile isminde bir dosyaya yazılır.

İki türlü tanımlama şekli var: Declarative, Scripted

Bu iki tür pipeline yazım şeklinden declarative olanı sonradan gelmiş ve daha gelişmiş olanıdır.

Resmi Jenkins dokümanlarında tavsiye edilen yöntem declarative tanımlamadır.

Scripted tanımlamada groovy kullanılarak yapılır. Declarative tanımlama tavsiye edilmesine rağmen, scripted tanımlama ile herhangi bir kısıtlama olmadan herşeyi yapabiliriz.

Scripted tanımlama bize daha esnek bir tanımlama imkanı sunuyor. İkisini de tercih edebiliriz. Seçim bize kalıyor.

Başlangıç düzeyindeki kişiler için ise, declarative tanımlama daha basit ve uygun olacaktır.

Şimdi ise bir örnek pipeline yaparak işin mutfağını görelim :)

Örnek bir pipeline

Yeni Item diyerek tanımlamaya başlayalım:

My Echo Job ismini veriyoruz ve Pipeline seçeneğine tıklıyoruz, ardından OK düğmesine tıklıyoruz:

Ardından gelen ekranda Pipeline kısmına gidip aşağıdaki pipeline tanımını seçiyoruz:

Script Code

Script’ın yaptığı tek şey, çıktıya testing diye bir ifade göndermek. Şimdi Yapılandır diyerek işlemi başlatalım:

Biraz bekledikten sonra Yapılandırma Geçmişi kısmında job’ın bir nolu çalışmasını göreceğiz:

Bir nolu linke tıklayınca çalışmanın detayına gideriz. Konsol çıktısına tıklayalım:

Gördüğünüz gibi testing ifadesini konsola yazdırmış olduk.

Umarım keyifle okuyacağınız ve beğeneceğiniz bir yazı olmuştur. Şimdiden keyifli okumalar… :)

--

--