“Continuous Integration/Continuous Deployment” yani “Sürekli Entegrasyon/Sürekli Dağıtım” anlamına gelen CI/CD süreçlerini kolaylaştıran GitLab CI/CD, yazılım projelerinin derlenmesi, test edilmesi ve dağıtılması için kullanılan bir süreçtir. gitlab-ci.yml dosyası, GitLab tarafından bu CI/CD işlemlerinin nasıl yürütüleceğini belirlemek için kullanılır. Bu yazıda, GitLab CI/CD kullanarak commit'te oluşan değişiklikleri bir FTP sunucusuna otomatik olarak nasıl aktarılacağını anlatan YAML dosyasından bahsedeceğiz.
.gitlab-ci.yml
Dosyanın formatı olan YML, "Yet Another Markup Language" tanımının kısaltmasıdır ve kolay okunabilen bir dildir. Repository (depo) içinde commit, push (aktarım) gibi işlemler gerçekleşince hangi işlemlerin yapılacağını gösteren yapılandırma dosyasıdır. Bu dosya içinde stages (aşamalar), jobs (işler), rules (kurallar), script (komutlar) ve artifacts (çıktılar) bulunur. Bunların ne işe yaradıklarına sırasıyla değineceğiz.
stages
Build, test ve deploy işlerini belirtmek için kullanılır. Eğer başlangıçta özel olarak tanımlanmazsa varsayılan sıra “.pre, build, test, deploy, .post” şeklindedir.
stages:
- build
- test
- deploy
Build aşamasında yazılımın derlenmesi ve bağımlılıkların yüklenmesi işlemleri gerçekleştirilir.
Test aşamasında test işlemleri yapılır.
Son aşama olan deploy aşamasında testleri geçen kod, sunucuya gönderilir.
jobs
Jobs, belirli aşamalarda çalıştırılan görevleri/işleri ifade eder. Aşağıdaki örnekte görüldüğü gibi alt başlığında “stage” ile bu işin hangi aşamada çalışacağı belirlenir. İşin aşaması tanımlanmazsa varsayılan olarak test aşamasında çalışır.
job1:
stage: test
job 2:
stage: deploy
rules
Kurallar, yazılı olduğu görevin hangi durumlarda çalışacağını belirler. Kural belirtirken "if", "changes", "exists", "when" ifadelerinden en az biri bulunmalıdır. Önemli bir nokta şudur ki kurallardan biri doğruysa geri kalanına bakılmaz. Yani ilk kural doğru ise kalanların hiçbir önemi yok diyebiliriz.
Örneğin aşağıdaki kural, sadece master adlı branch’e yapılan commit’lerde komutların çalışmasını sağlar. Bu durum gerçekleşmezse "when: never" diğer durumlarda çalışmayı engeller. Branch değeri predefined variable (önceden tanımlı değişken) olan “$CI_COMMIT_BRANCH” değişkeninden çekilir. Buraya tıklayarak önceden tanımlı değişkenler hakkında daha fazla bilgi edinebilirsiniz. rules:
- if: '$CI_COMMIT_BRANCH == "master"'
- when: never
Yukarıdaki gibi sadece master'da çalışması kuralı varsa diğer branchlerde yapılan değişiklikler master'a aktarılmadıkça (push edilmedikçe) YAML dosyası çalışmaz. Buna ek olarak "revert changes", "cherry pick" gibi işlemlerle de pipeline'ı aktifleştirmek mümkün. Bu terimler hakkında daha fazla bilgiye resmî Gitlab dökümantasyonundan ulaşabilirsiniz.
When ise "always", "never" gibi başka işlerden bağımsız durumlarla veya önceki işin sonucuna bağlı olan "on_success", "on_failure" gibi durumlarla kullanılabilir.
Aşağıda bulunan bir başka kural örneğinde branch adı main ise tanımlanan değişkenler (varible) atanır. rules:
- if: '$CI_COMMIT_BRANCH == "main"'
variables:
FTP_HOST: "$FTP_HOST_PROD"
FTP_USER: "$FTP_USER_PROD"
FTP_PASSWORD: "$FTP_PASSWORD_PROD"
script
İş içinde gerçekleşecek komutlar buraya yazılır.
Örneğin otomatik aktarım sürecinde aktarılan veri isimlerini tutmak için log dosyamızı aşağıdaki gibi oluşturabiliriz. Log dosyasına nasıl erişilebileceğine yazının ilerleyen kısımlarında değineceğiz.
script:
- LOG_FILE="deploy_log_10032025.log"
Gelelim asıl mesele olan aktarıma. Aşağıdaki kod parçasında güncel çalışma ile bir önceki commit kıyaslanıyor (HEAD~1 HEAD). Belirlenen filtreye göre (added (eklenen), copied (kopyalanan), modified (güncellenen), deleted (silinen), renamed (yeniden adlandırılan) gibi) değişen dosyalar seçilerek sadece isimleri yeni dosyaya atanıyor. Eğer dosya boş değilse (-s) okunup kullanıcı adı, şifre ve sunucu bilgileri çekilip transfer işlemi (-T) gerçekleştiriliyor. İşlem sonrasında değişen dosyaları log dosyasında tutmak için dosyaya echo komutu ile dosyanın adı gönderiliyor.
- changed_files=$(git diff --name-only --diff-filter=ACM HEAD~1 HEAD)
- if [ -n "$changed_files" ]; then
echo "$changed_files" > changed_files.txt;
fi
- if [ -s changed_files.txt ]; then
cat changed_files.txt | while read file; do
curl -T "$file" --ftp-create-dirs -u "$FTP_USER:$FTP_PASSWORD" "ftp://$FTP_HOST/public_html/$file" && echo "$file güncellendi" >> "$LOG_FILE";
done
fi
Ayrıca curl komutu ile duruma bağlı olarak "-s" ile çıktılar sadeleştirilebilir, "-v" ile daha detaylı sonuçlar görülebilir.
Burada kullanılan FTP_HOST, FTP_USER ve FTP_PASSWORD değerleri Gitlab arayüzünden tanımlanabilir. Bu dosyanın başında da tanımlanabilir ancak güvenlik riski sebepleriyle önerilmez.
artifacts
Bir iş, çıktı olarak dosya verebilir. Verilen bu çıktı "artifact" olarak adlandırılır. Bu çıktılar Gitlab arayüzünden veya API aracılığıyla indirilebilir. Daha yenisi gelmediği sürece son işten kalan çıktılar silinmez.
Çıktı parametresi olan “paths” hangi dosyaların çıktılara dahil edileceğini seçer. Birden fazla olabilir. “Expire_in” ile çıktıların ne kadar süre tutulacağı ayarlanabilir. Bu değer tanımlanmazsa varsayılan silme süresi 30 gün sonrasıdır. Eğer değere saniye, yıl gibi zaman birimi belirtilmeden sadece sayı girilirse saniye olarak algılanır. Yani '42' ile '42 seconds' aynı işlevi görür.
artifacts:
paths:
- deploy_log_10032025.log
expire_in: 2 yrs
Bu şekilde Gitlab’a gönderilen verilerin otomatik olarak FTP’ye aktarılması mümkündür.
Yazar: Berkay UZUN
Kaynakça
docs.gitlab.com