Herkese merhaba!

Bu yazımda bireysel ve çalıştığım yerde düzenli olarak kullandığımız Git bazlı revizyon hosting sistemi Bitbucket üzerinde projeyi host ederken, otomatik veya manuel olarak kodun test süreçlerini tetiklemeyi, build, minify, bundling gibi süreçlerden geçirip uygulama sunucusuna aktarmayı anlatacağım. Birçok Git bazlı hosting sistemlerine rağmen Bitbucket’ı seçmemin sebebi hem ürün bağımlılığı, hem de sınırsız private repository veriyor olmasından dolayı.

Bitbucket Pipelines Nedir?

Bitbucket Pipelines, Bitbucket Cloud’un üzerinde geliştirilmiş, Test, build ve deploy işlemlerini herhangi başka üçüncü parti bir araca ihtiyaç duymadan yapabileceğiniz Bitbucket’ın kendi ürünüdür.

Peki bu sadece Bitbucket’ta mı var?

Tabii ki hayır. Gitlab’in kendi CI/CD pipeline çözümü var. Buradan göz atabilirsiniz. Github’ın da marketinde CI/CD ürünleri mevcut, ancak hatırlatmakta fayda var, bunlar üçüncü parti ürünler, yani Gitlab veya Bitbucket’ta olduğu gibi Github’ın kendi süreçleri içerisine eklenmiş değil.

Nasıl çalışır?

Test etmek için öncelikle bir repo açalım. Bitbucket’ın sol menüsünde “Pipelines” alt menüsüne tıklayalım. Eğer Pipelines’ı aktifleştirmediyseniz burada size bir commit ile aktif hale getirmenizi sağlayacaktır.

Pipelines

Pipelines’ı aktifleştirmenin yolu repository’nize tek bir dosyayı eklemekten geçer: bitbucket-pipelines.yml. Peki bu yaml dosyasının çalışma prensibi nedir?

Öncelikle üst taraftaki tanımdan başlayalım. Örneğin ben PHP ortamı seçtiğimde image: php:7.1.1 olarak değişmekte. Bunun sebebi, bitbucket pipeline’ının aslında bir docker image’ını çekmesi, container olarak ayaklandırması, ve sizin burada tanımladığınız tüm scriptleri onun üzerinde çalıştırmasıdır. Bir başka örnek göstermem gerekirse, Jekyll tarafından çalıştırılan bu blog’un ruby:2.4.0 image’ı üzerinden build süreçleri yürütülür. Eğer siz bir image değeri belirtmezseniz pipeline default image üzerinden yürütülür, ancak burada istediğimiz tüm fonksiyonların çalışmama ihtimalini hatırlamak önemli.

Sonrasında başlayan kısımda pipelines altında süreç tanımlamaları, nasıl tetikleneceği ve hangi branch’e ait olduğu gibi bilgiler yazılır.

  • default herhangi bir pipeline tanımı olmayan branchlere commit veya merge işlemi yapıldığında tetiklenecek olan işlemlerdir, ancak işinizi görecek olan build süreçlerinizi branchlere bağlamak olacaktır.
  • branches ve altında branch isimlerinizi belirttiğiniz zaman, ilgili branch’e commit veya merge yapıldığı zaman otomatik tetiklenecek olan işlemlerdir.
  • custom altında yine işlem ismi belirterek manuel olarak tetiklenecek işlemler yazılabilir.

branches altında branch’inizin ismini eklediğiniz zaman altında olacak olan işlemleri, default altında yazacağınız işlemleri veya custom altında isim belirterek yapmak istediğiniz işlemlerin hepsi - step kelimesi ile başlar. Her step, altında script ile belirteceğiniz işlemleri içeren birer build sürecidir, iş parçacıklarıdır. Her step kısmı için ayrı docker süreçleri oluşturulur ve yürütülür. Bu yürütme esnasında yapmak istediğiniz işlemleri de script altında belirtirsiniz.

Örnek, bu blog!

Örneğin, ben bu blog’u build etmek istiyorum. O zaman ihtiyaçlarım şu şekilde olmalı:

  1. ruby olan bir makine
  2. gemleri restore etmek
  3. bundle scriptleri çalıştırmak

Eğer benim elimde güncel ruby yüklü olan bir makine varsa, bundleçalıştırabiliyor olurum. Aslında bu durum 3 ihtiyacımı da çözer. Bu yüzden bitbucket-pipelines.yml’ı oluştururken, Bitbucket’ın önerdiği ruby image’ını, veya Docker Hub‘a girip ihtiyacınız olan image’ı image: kısmına ekleyebilirsiniz

script altına yazdığım her adım birer bash komutu içerir. Bu sayede - ile başlayarak birer satır komut yazıp işlemlerimizi istediğimiz gibi yapabiliriz.

Örnek bitbucket-pipelines.yml şu şekilde olacak:

image: ruby:2.4.0

pipelines:
    branches:
        master:
            - step:
                script:
                - bundle install
                - bundle exec jekyll build

Her satır birer bash işlemi, içinde bulunduğumuz ortam da bir container olduğu için, aslında bir sunucuya bağlanıp yaptığımız her işlemi yaptırabiliriz! Örneğin, diyelim ki build işlemini tamamladık, ve ben pipeline içinden deploy yapmak istiyorum. Bu bana sunucuya pipeline içerisinden bağlantı kurmayı gerektirir. Repository‘nin altında Settings menüsü altında SSH Keys bölümü altında repository’nize ait private ve public ssh key tanımlayabilirsiniz. Public anahtarınızı alıp sunucunuzda ~/.ssh/authorized_keys altına eklediğiniz zaman, ssh ip yaptığınız zaman, ssh’ın sunduğu bütün nimetleri pipeline’ınız içerisinden kullanabilirsiniz. Bu blogun son ihtiyaçları, build işlemi bittikten sonra ortaya çıkan _site klasörünü gziplemek, bu gzipli dosyayı sunucuya atmak, sitenin sunulan klasörüne arşivi açmak, sunucunun web sunucu yazılımını (nginx, apache, vs) yeniden yüklemek. Bunları da ekledikten sonra ortaya çıkan bitbucket-pipelines.yml’nin son hali şu şekilde:

image: ruby:2.4.0

pipelines:
    branches:
        master:
            - step:
                script:
                - bundle install
                - bundle exec jekyll build
                - cd ./_site
                - tar -zcf ~/blog.tar.gz .
                - scp ~/blog.tar.gz root@138.197.187.14:~/blog.tar.gz
                - ssh root@138.197.187.14 "rm -rf /srv/www/blog/ && mkdir /srv/www/blog"
                - ssh root@138.197.187.14 "tar -zxf ~/blog.tar.gz -C /srv/www/blog/"
                - ssh root@138.197.187.14 "chown -R www-data. /srv/www"
                - ssh root@138.197.187.14 "service nginx reload"

Son olarak

Bitbucket Pipelines’ın tüm bölümlerine burada değinememiş olsam da buradaki confluence dökümanında tüm özelliklerine göz atabilir, farklı olan diğer güçlerini de ortaya çıkarabilirsiniz. Pipeline’lar süre bazında harcama yapmış sayılırlar. Ücretsiz kullanıcıların da aylık 50 dakika kullanım sınırı var ve bu hesabınıza tanımlı bütün repositoryler için ortak bir sayı. O yüzden eğer ücretsiz kullanmaya devam edecekseniz kullanım miktarlarınızı Pipelines menüsünde sağ üstte olan Usage bölümünü kontrol edebilirsiniz.

Keyifli kodlamalar!