Modern yazılım dünyasında, uygulamaların hızlı, güvenilir ve sürekli bir şekilde geliştirilip dağıtılması hiç olmadığı kadar kritik. Peki, karmaşık geliştirme süreçlerini nasıl basitleştirir, hataları erkenden yakalar ve ürününüzü pazara daha hızlı sunarsınız? İşte tam bu noktada GitLab CI/CD devreye girerek, otomasyonun gücünü parmaklarınızın ucuna getiriyor. Bu kapsamlı rehberde, GitLab CI/CD’nin temel prensiplerinden ileri düzey kullanım ipuçlarına kadar her şeyi adım adım keşfedeceğiz. Gelin, CI/CD dünyasına doğru heyecan verici bir yolculuğa çıkalım ve yazılım geliştirme süreçlerinizi nasıl dönüştürebileceğinizi öğrenelim!
Günümüzün rekabetçi teknoloji ortamında, yazılım projeleri her zamankinden daha karmaşık ve dinamik hale geldi. Geliştirici ekipleri, kullanıcı beklentilerini karşılamak ve piyasa taleplerine ayak uydurmak için sürekli yeni özellikler eklemek, mevcutları iyileştirmek ve hataları gidermek zorundadır. Bu sürekli değişim ve geliştirme döngüsü, manuel süreçlerle yönetildiğinde beraberinde birçok zorluğu getirir: entegrasyon çatışmaları, geciken testler, hatalı dağıtımlar ve uzun geri bildirim süreleri gibi. İşte bu sorunlara kalıcı bir çözüm sunmak amacıyla Sürekli Entegrasyon (CI) ve Sürekli Teslimat/Dağıtım (CD) kavramları ortaya çıkmıştır.
Peki, tam olarak nedir bu CI/CD ve neden modern yazılım geliştirme için vazgeçilmezdir? Sürekli Entegrasyon (CI), geliştiricilerin kod değişikliklerini düzenli olarak merkezi bir depoda birleştirdiği ve bu birleşme sonrasında otomatik testlerin çalıştığı bir yazılım geliştirme uygulamasıdır. Her bir entegrasyonun otomatik olarak test edilmesi sayesinde, entegrasyon hataları erken aşamada tespit edilir ve çözülür. Bu durum, geliştirme döngüsünün başında potansiyel sorunları ele alarak ileride ortaya çıkabilecek maliyetli sorunların önüne geçer. Ayrıca, kod tabanının her zaman kararlı ve dağıtıma hazır olmasını sağlar.
Sürekli Teslimat (CD) ise, CI’ın bir uzantısıdır. Kod değişiklikleri başarıyla entegre edilip test edildikten sonra, bu değişikliklerin üretim ortamına veya benzer bir test ortamına otomatik olarak yayınlanmaya hazır hale getirilmesi sürecidir. Bu, genellikle bir manuel onay adımı gerektirebilir, ancak teknik olarak dağıtımın her an yapılabilir olduğu anlamına gelir. Sürekli Dağıtım ise, bu süreci bir adım öteye taşıyarak, başarılı bir şekilde test edilen her değişikliğin, herhangi bir manuel insan müdahalesi olmaksızın doğrudan üretim ortamına otomatik olarak dağıtıldığı bir uygulamadır. Bu sayede, yeni özellikler ve hata düzeltmeleri kullanıcılara çok daha hızlı ulaştırılabilir.
CI/CD’nin benimsenmesi, geliştirme ekiplerine hız, güvenilirlik ve verimlilik kazandırır. Otomatikleştirilmiş testler sayesinde, kod kalitesi artar ve hata oranı düşer. Otomatik dağıtım, manuel hataları ortadan kaldırır ve dağıtım sürelerini önemli ölçüde kısaltır. Geliştiriciler, kod yazmaya daha fazla odaklanabilir ve operasyonel görevlerle daha az zaman kaybederler. Ayrıca, hızlı geri bildirim döngüleri, ekiplerin daha çevik olmasına ve müşteri ihtiyaçlarına daha hızlı yanıt vermesine olanak tanır. Sonuç olarak, CI/CD sadece bir teknoloji değil, aynı zamanda yazılım geliştirme felsefesinin önemli bir parçasıdır ve modern DevOps kültürünün temel taşlarından biridir.
GitLab CI/CD Nedir ve Neden Vazgeçilmezdir?
GitLab, popüler bir web tabanlı Git depo yöneticisi olmasının yanı sıra, yazılım geliştirme yaşam döngüsünün her aşamasını kapsayan entegre bir DevOps platformudur. Bu platformun en güçlü bileşenlerinden biri de şüphesiz GitLab CI/CD’dir. GitLab CI/CD, projeleriniz için doğrudan GitLab içerisinde eksiksiz bir sürekli entegrasyon, sürekli teslimat ve sürekli dağıtım çözümü sunar. Harici bir araç kurma veya başka bir hizmetle entegrasyon yapma ihtiyacını ortadan kaldırarak, sürüm kontrolünden dağıtıma kadar tüm süreçleri tek bir platformda yönetmenizi sağlar. Bu entegre yaklaşım, geliştirme ekiplerinin işbirliğini artırır, karmaşıklığı azaltır ve genel verimliliği önemli ölçüde artırır.
GitLab CI/CD’nin vazgeçilmez olmasının birçok nedeni vardır. Öncelikle, pipeline’ları doğrudan Git deponuzda tanımlamanızı sağlayan .gitlab-ci.yml dosyası ile yapılandırma, kodunuzla birlikte saklanır. Bu, “infrastructure as code” (altyapı kod olarak) prensibine benzer şekilde, “pipeline as code” (pipeline kod olarak) yaklaşımını benimsemenizi sağlar. Böylece, versiyon kontrolü altında tutulan pipeline tanımları, kod değişiklikleriyle birlikte gözden geçirilebilir, test edilebilir ve sürümle birlikte evrimleşebilir. Bu durum, CI/CD süreçlerinizin şeffaflığını ve yönetilebilirliğini artırır.
Bir diğer önemli avantajı ise GitLab Runner’lardır. GitLab Runner’lar, GitLab CI/CD pipeline’ınızdaki işleri (job) çalıştıran hafif ve bağımsız aracı yazılımlardır. Kendi sunucularınızda, bulut ortamlarında, hatta Docker konteynerlerinde çalıştırılabilirler. Bu esneklik, projelerinizin özel gereksinimlerine göre özelleştirilmiş derleme ortamları kurmanıza olanak tanır. Örneğin, farklı işletim sistemlerinde (Linux, Windows, macOS) veya belirli donanım konfigürasyonlarına sahip makinelerde testler yapmanız gerekiyorsa, bunu kolayca yapabilirsiniz. Herhangi bir programlama dili veya teknolojisiyle uyumlu olması, GitLab CI/CD’yi neredeyse her türlü proje için ideal bir çözüm haline getirir.
GitLab CI/CD’nin ana bileşenleri şunlardır:
- Pipeline (Boru Hattı): Bir projenin tüm CI/CD sürecini temsil eden üst düzey yapıdır. Genellikle, derleme (build), test etme (test) ve dağıtma (deploy) gibi aşamalardan oluşur.
- Stage (Aşama): Bir pipeline’ın mantıksal olarak gruplandırılmış adımlarıdır. Aşamalardaki işler (job) paralel olarak çalışabilir, ancak aşamalar genellikle sırayla çalışır. Örneğin, ‘build’ aşaması ‘test’ aşamasından önce tamamlanmalıdır.
- Job (İş): Bir aşama içinde çalışan en küçük birimdir. Her iş, belirli bir görevi yerine getirir; örneğin, kodu derlemek, testleri çalıştırmak veya bir uygulamayı dağıtmak. İşler, belirli bir ortamda (Runner üzerinde) tanımlanan komutları yürütür.
- Runner (Koşucu): İşleri fiziksel veya sanal makinelerde yürüten aracıdır. GitLab sunucusu, Runner’lara iş atar ve Runner’lar da bu işleri kendi ortamlarında çalıştırır. Paylaşımlı Runner’lar veya kendi özel Runner’larınızı kullanabilirsiniz.
Bu bileşenlerin entegre ve esnek yapısı sayesinde, GitLab CI/CD yazılım geliştirme süreçlerinizi daha verimli, şeffaf ve güvenilir hale getirir. Hata bulma sürelerini kısaltır, ürün kalitesini artırır ve yeni özellikleri kullanıcılara ulaştırma hızınızı önemli ölçüde artırır. Kısacası, modern DevOps pratiklerini benimsemek isteyen her ekip için GitLab CI/CD, vazgeçilmez bir araçtır.
İlk GitLab CI/CD Pipeline’ınızı Nasıl Oluşturursunuz? (.gitlab-ci.yml Anatomisi)
GitLab CI/CD’nin kalbi, projenizin kök dizininde bulunan .gitlab-ci.yml adlı yapılandırma dosyasıdır. Bu YAML dosyası, pipeline’ınızın nasıl çalışacağını, hangi aşamalardan geçeceğini ve her aşamada hangi işlerin (job) yürütüleceğini tanımlar. Bu dosya sayesinde, tüm CI/CD sürecinizi kod olarak ifade edebilir ve sürüm kontrolü altında tutabilirsiniz. Bu bölüm, temel bir .gitlab-ci.yml dosyasının anatomisini açıklayacak ve ilk pipeline’ınızı oluşturmanız için adım adım bir rehber sunacaktır.
Temel Yapı Taşları: Stages, Jobs ve Script Komutları
Bir .gitlab-ci.yml dosyası genellikle stages anahtar kelimesiyle başlar. Bu, pipeline’ınızın mantıksal aşamalarını tanımlar. Örneğin, tipik bir web uygulaması için build, test ve deploy gibi aşamalarınız olabilir. Aşamalardaki her bir iş (job), bu aşamaların sırasına göre yürütülür. Aynı aşama içindeki işler paralel olarak çalıştırılabilirken, farklı aşamalar birbirini takip eder ve önceki aşamanın başarılı bir şekilde tamamlanmasını bekler.
Her bir iş, kendi adı altında tanımlanır ve en az bir script anahtar kelimesi içermelidir. script anahtar kelimesi, bu işin GitLab Runner tarafından yürütülecek komutlarını listeler. Bu komutlar, genellikle bağımlılıkları yükleme, kodu derleme, testleri çalıştırma veya uygulamayı bir sunucuya dağıtma gibi görevleri içerir. İşte basit bir .gitlab-ci.yml dosyasının görünümü:
# .gitlab-ci.yml dosyasının başlangıcı
# Pipeline'ımızın aşamalarını tanımlıyoruz.
# Aşamalardaki işler paralel çalışırken, aşamalar sırayla çalışır.
stages:
- build
- test
- deploy
# 'build_job' adında bir iş tanımlıyoruz.
# Bu iş 'build' aşamasında çalışacak.
build_job:
stage: build
# Bu iş için bir Docker imajı belirliyoruz. Runner bu imajı kullanarak ortamı hazırlar.
image: node:16-alpine
script:
- echo "Uygulama oluşturuluyor..."
- npm install
- npm run build
# Bu işin çıktısı olan 'build' klasörünü bir sonraki aşamalara aktarıyoruz.
artifacts:
paths:
- build/
expire_in: 1 day # Üretilen dosyaların ne kadar süre saklanacağını belirtir
# 'test_job' adında bir iş tanımlıyoruz.
# Bu iş 'test' aşamasında çalışacak.
test_job:
stage: test
image: node:16-alpine
script:
- echo "Testler çalıştırılıyor..."
- npm install # Önceki aşamadan gelen bağımlılıklar için gerekebilir veya cache kullanılabilir.
- npm test
# 'build' aşamasından gelen artefaktları (build klasörü) bu işe indiriyoruz.
needs:
- build_job
# 'deploy_job' adında bir iş tanımlıyoruz.
# Bu iş 'deploy' aşamasında çalışacak.
# Bu işin sadece 'main' branch'ine yapılan push'larda çalışmasını sağlıyoruz.
deploy_job:
stage: deploy
image: alpine/git # Dağıtım için basit bir Alpine Linux ve Git içeren imaj
script:
- echo "Uygulama dağıtılıyor..."
- cp -r build/ /var/www/html/ # Örnek bir dağıtım komutu
- echo "Uygulama başarıyla dağıtıldı!"
# Sadece 'main' branch'inde değişiklik olduğunda bu işi çalıştır.
rules:
- if: $CI_COMMIT_BRANCH == "main"
# Önceki aşamadan gelen artefaktları (build klasörü) bu işe indiriyoruz.
needs:
- test_job
Yukarıdaki örnekte:
stages:build,testvedeployaşamalarını tanımlar. Bunlar sırasıyla çalışacaktır.build_job:buildaşamasında çalışan bir iş.node:16-alpineDocker imajını kullanarak bağımlılıkları kurar (npm install) ve uygulamayı derler (npm run build).artifactsanahtar kelimesi ile derlenmiş dosyaların (build/klasörü) saklanmasını ve bir sonraki aşamalarda kullanılabilmesini sağlar.test_job:testaşamasında çalışan bir iş. Yinenode:16-alpineimajını kullanır venpm testkomutuyla testleri çalıştırır.needs: ['build_job']ifadesi, bu işinbuild_job'ın başarılı bir şekilde tamamlanmasını beklediğini ve onun artefaktlarına ihtiyaç duyduğunu belirtir.deploy_job:deployaşamasında çalışan bir iş.rulesanahtar kelimesi ile sadecemainbranch'ine yapılan push'larda çalışacak şekilde koşullandırılmıştır. Bu iş,test_job'dan sonra çalışır ve örnek bir dağıtım komutu içerir.
image, before_script, after_script ve variables
GitLab CI/CD, pipeline'larınızı daha güçlü ve esnek hale getirecek birçok ek anahtar kelime sunar:
image: Her işin hangi Docker imajı içinde çalışacağını belirler. Bu, işin yürütüleceği ortamı standardize etmenizi sağlar. Global olarak veya iş bazında tanımlanabilir.before_script: Her işinscriptbölümünden önce çalışacak komutları tanımlar. Genellikle bağımlılık kurulumları veya genel yapılandırmalar için kullanılır.after_script: Her işinscriptbölümünden sonra (başarılı veya başarısız olmasına bakılmaksızın) çalışacak komutları tanımlar. Temizlik veya raporlama için kullanılabilir.variables: Pipeline genelinde veya belirli bir iş için kullanılabilecek özel değişkenleri tanımlar. Hassas bilgiler için GitLab UI üzerinden "CI/CD Variables" kullanılması önerilir.
# Global bir Docker imajı tanımlayabiliriz
default:
image: node:16-alpine # Tüm işler bu imajı kullanacak varsayılan olarak
stages:
- build
- test
- deploy
variables:
# Özel bir değişken tanımlıyoruz
APP_VERSION: 1.0.0
build_job:
stage: build
script:
- echo "Uygulama versiyonu: $APP_VERSION"
- npm install
- npm run build
artifacts:
paths:
- build/
test_job:
stage: test
# Bu iş için farklı bir imaj kullanabiliriz (varsayılanı geçersiz kılar)
image: node:18-alpine
before_script:
- echo "Test ortamı hazırlanıyor..."
script:
- npm test
after_script:
- echo "Testler tamamlandı."
needs:
- build_job
deploy_job:
stage: deploy
script:
- echo "Uygulama versiyon $APP_VERSION ile dağıtılıyor..."
- # Dağıtım komutları buraya gelir
rules:
- if: $CI_COMMIT_BRANCH == "main"
needs:
- test_job
Bu temel yapılandırmalarla, projeniz için güçlü ve otomatik bir CI/CD pipeline'ı oluşturmaya başlayabilirsiniz. .gitlab-ci.yml dosyasını projenizin kök dizinine ekledikten sonra, GitLab otomatik olarak yeni commit'ler için pipeline'ı tetikleyecek ve tanımladığınız işleri çalıştıracaktır. Bu, geliştirme sürecinizi otomatize etme yolunda atacağınız ilk ve en önemli adımdır.
Gerçek Dünya Senaryolarında GitLab CI/CD: Bir Web Uygulaması için Otomatik Test ve Dağıtım Nasıl Yapılır?
Teorik bilgilerin ardından, şimdi GitLab CI/CD'nin gerçek bir senaryoda nasıl çalıştığını inceleyelim. Bu vaka analizinde, hem bir frontend (React) hem de bir backend (Node.js Express API) içeren basit bir web uygulamasını ele alacağız. Amacımız, kod değişiklikleri yapıldığında otomatik olarak testlerin çalıştırılmasını, frontend ve backend uygulamalarının derlenmesini ve ardından bir test ortamına (staging) otomatik olarak dağıtılmasını sağlayacak bir CI/CD pipeline'ı oluşturmaktır. Bu senaryo, modern web geliştirme süreçlerinde sıklıkla karşılaşılan zorlukları otomasyonla nasıl aşabileceğinizi gösterecektir.
Senaryo Detayları
- Frontend: React tabanlı bir SPA (Single Page Application). Bağımlılık yönetimi için npm kullanılıyor. Testler için Jest, derleme için Webpack/CRA (Create React App) build scripti kullanılıyor.
- Backend: Node.js ve Express.js ile yazılmış RESTful API. Bağımlılık yönetimi için npm kullanılıyor. Testler için Mocha/Chai kullanılıyor.
- Hedef Ortamlar:
mainbranch'ine yapılan push'larda otomatik olarak bir "Staging" ortamına dağıtım yapılacak. Manuel onay ile bir "Production" ortamına dağıtım opsiyonu da bulunacak.
.gitlab-ci.yml Dosyası Oluşturma
Bu senaryo için oldukça detaylı bir .gitlab-ci.yml dosyası oluşturacağız. Her iki uygulama (frontend ve backend) için ayrı ayrı derleme, test ve dağıtım aşamalarını yöneteceğiz. Artefaktları kullanarak derlenmiş çıktıları aşamalar arasında aktaracağız.
# .gitlab-ci.yml - Gerçek Dünya Web Uygulaması için CI/CD Pipeline
# Varsayılan Docker imajı ve genel ayarlar
default:
image: node:18-alpine # Ortak Node.js ortamı
tags:
- my-self-hosted-runner # Belirli bir Runner kullanmak için
# Pipeline aşamaları
stages:
- build # Frontend ve Backend'i derle
- test # Frontend ve Backend testlerini çalıştır
- deploy # Staging ve Production'a dağıtım
# ====== FRONTEND İŞLERİ ======
frontend_build:
stage: build
# Çalışma dizinini frontend projesinin içine taşıyoruz
before_script:
- cd frontend
script:
- npm install --production=false # Geliştirme bağımlılıkları dahil
- npm run build
artifacts:
paths:
- frontend/build/ # Derlenmiş frontend dosyalarını sakla
expire_in: 1 week # Artefaktların saklama süresi
# Sadece frontend klasöründe değişiklik olduğunda çalışır (performans optimizasyonu)
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
changes:
- frontend/**/*
- if: '$CI_COMMIT_BRANCH != "main"'
changes:
- frontend/**/*
when: on_success
frontend_test:
stage: test
before_script:
- cd frontend
script:
- npm install --production=false
- npm test # Frontend testlerini çalıştır
needs:
- frontend_build # Frontend derleme işinin bitmesini bekle
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
changes:
- frontend/**/*
- if: '$CI_COMMIT_BRANCH != "main"'
changes:
- frontend/**/*
when: on_success
# ====== BACKEND İŞLERİ ======
backend_build:
stage: build
before_script:
- cd backend
script:
- npm install --production=false
artifacts:
paths:
- backend/node_modules/ # Bağımlılıkları sakla (dağıtım için)
expire_in: 1 week
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
changes:
- backend/**/*
- if: '$CI_COMMIT_BRANCH != "main"'
changes:
- backend/**/*
when: on_success
backend_test:
stage: test
before_script:
- cd backend
script:
- npm install --production=false
- npm test # Backend testlerini çalıştır
needs:
- backend_build # Backend derleme işinin bitmesini bekle
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
changes:
- backend/**/*
- if: '$CI_COMMIT_BRANCH != "main"'
changes:
- backend/**/*
when: on_success
# ====== DAĞITIM İŞLERİ ======
deploy_staging:
stage: deploy
image: alpine/git # Dağıtım için daha hafif bir imaj
before_script:
- apk add --no-cache rsync openssh-client # SSH ve Rsync kur
- eval "$(ssh-agent -s)"
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - # SSH anahtarını ekle (GitLab CI/CD Variable)
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- ssh-keyscan $STAGING_SERVER_IP >> ~/.ssh/known_hosts # Güvenli bağlantı için
- chmod 644 ~/.ssh/known_hosts
script:
- echo "Frontend ve Backend Staging ortamına dağıtılıyor..."
- rsync -avz --delete frontend/build/ $STAGING_USER@$STAGING_SERVER_IP:/var/www/html/frontend # Frontend dağıtımı
- rsync -avz --delete backend/ $STAGING_USER@$STAGING_SERVER_IP:/var/www/html/backend # Backend dağıtımı
- ssh $STAGING_USER@$STAGING_SERVER_IP "cd /var/www/html/backend && npm install --production" # Backend bağımlılıklarını kur (artefakttan da çekilebilir)
- ssh $STAGING_USER@$STAGING_SERVER_IP "pm2 restart backend-app || pm2 start /var/www/html/backend/app.js --name backend-app" # Backend'i yeniden başlat
environment:
name: staging
url: https://staging.example.com
rules:
- if: '$CI_COMMIT_BRANCH == "main"' # Sadece main branch'inden staging'e otomatik dağıtım
needs:
- frontend_test
- backend_test
deploy_production:
stage: deploy
image: alpine/git
before_script:
- apk add --no-cache rsync openssh-client
- eval "$(ssh-agent -s)"
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- ssh-keyscan $PRODUCTION_SERVER_IP >> ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts
script:
- echo "Frontend ve Backend Production ortamına dağıtılıyor..."
- rsync -avz --delete frontend/build/ $PRODUCTION_USER@$PRODUCTION_SERVER_IP:/var/www/html/frontend
- rsync -avz --delete backend/ $PRODUCTION_USER@$PRODUCTION_SERVER_IP:/var/www/html/backend
- ssh $PRODUCTION_USER@$PRODUCTION_SERVER_IP "cd /var/www/html/backend && npm install --production"
- ssh $PRODUCTION_USER@$PRODUCTION_SERVER_IP "pm2 restart backend-app || pm2 start /var/www/html/backend/app.js --name backend-app"
environment:
name: production
url: https://example.com
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: manual # main branch'inden production'a manuel onay ile dağıtım
needs:
- deploy_staging # Staging dağıtımının başarılı olmasını bekle
Açıklamalar ve Önemli Detaylar
- Dizin Yapısı: Bu senaryo, projenizin kök dizininde
frontend/vebackend/adında iki alt dizin olduğunu varsayar. before_scriptile Dizin Değiştirme: Her işin başındacd frontendveyacd backendkullanarak ilgili proje dizinine geçiş yapıyoruz. Bu, komutların doğru yerde çalışmasını sağlar.artifactsKullanımı:frontend_buildişi, derlenmiş React uygulamasını içerenfrontend/build/dizinini artefakt olarak saklar.deploy_stagingvedeploy_productionişleri bu artefaktları otomatik olarak indirir ve dağıtım sırasında kullanır. Benzer şekilde,backend_buildişi bağımlılıkları saklar, ancak dağıtım aşamasında doğrudan sunucudanpm installyapmak daha yaygın ve güvenlidir.rulesile Koşullu Çalıştırma:- Derleme ve test işleri, sadece ilgili dizinlerde (
frontend//*veyabackend//*) değişiklik olduğunda çalışacak şekilde optimize edilmiştir. Bu, gereksiz pipeline çalıştırmalarını önler ve kaynak kullanımını azaltır. deploy_stagingişi, sadecemainbranch'ine yapılan push'larda otomatik olarak tetiklenir.deploy_productionişi,mainbranch'inde manuel olarak tetiklenecek şekilde ayarlanmıştır (when: manual). Bu, canlıya dağıtım öncesi manuel kontrol sağlar.
- Derleme ve test işleri, sadece ilgili dizinlerde (
needsKullanımı: İşler arasındaki bağımlılıkları belirtmek içinneedsanahtar kelimesi kullanılır. Örneğin, frontend testleri derleme işi bitmeden çalışamaz.- Dağıtım Stratejisi (SSH ve rsync): Dağıtım işleri,
alpine/gitgibi hafif bir Docker imajı kullanır. SSH ve rsync araçlarını kurarak, derlenmiş dosyaları uzak sunuculara güvenli bir şekilde aktarırız.SSH_PRIVATE_KEY,STAGING_SERVER_IPgibi hassas bilgiler GitLab CI/CD Değişkenleri olarak saklanmalıdır ve pipeline dosyasında direkt olarak yer almamalıdır. - Ortam Değişkenleri (
environment):deploy_stagingvedeploy_productionişleri içinenvironmentanahtar kelimesi kullanılmıştır. Bu, GitLab arayüzünde her dağıtımın hangi ortama yapıldığını gösterir ve ortam bağlantılarına erişim sağlar.
Bu detaylı senaryo, GitLab CI/CD'nin bir web uygulamasının geliştirme, test ve dağıtım süreçlerini ne kadar etkili bir şekilde otomatize edebileceğini göstermektedir. Bu sayede, geliştirme ekibi daha hızlı geri bildirim alır, manuel hatalar azalır ve uygulama sürekli olarak güncel ve kararlı bir şekilde kullanıcılara sunulur. Bu, modern DevOps prensiplerinin ve çevik metodolojilerin temelini oluşturur.
İleri Düzey GitLab CI/CD Özellikleri: Pipeline'larınızı Daha Akıllı ve Hızlı Hale Getirmek İçin Ne Kullanmalısınız?
GitLab CI/CD'nin temel özellikleriyle bir pipeline oluşturmak kolaydır, ancak büyük ve karmaşık projelerde performans, güvenlik ve esnekliği artırmak için ileri düzey özelliklerden yararlanmak gerekir. Bu bölüm, pipeline'larınızı daha akıllı, hızlı ve yönetilebilir hale getirecek bazı kritik özellikleri ve en iyi uygulamaları ele alacaktır.
Cache (Önbellek) Kullanımı
Büyük projelerde bağımlılıkların her pipeline çalıştırmasında yeniden indirilmesi, zaman ve kaynak israfına yol açar. cache anahtar kelimesi, bağımlılıkları veya derleme çıktılarını depolayarak ve bir sonraki çalıştırmalarda tekrar kullanarak bu süreci hızlandırır. Bu, özellikle Node.js (node_modules), Java (Maven/Gradle) veya Python (pip) gibi dillerde bağımlılıkların boyutunun büyük olduğu durumlarda çok faydalıdır.
my_build_job:
stage: build
image: node:18-alpine
cache:
key: ${CI_COMMIT_REF_SLUG} # Branch'e özgü bir anahtar
paths:
- node_modules/ # node_modules klasörünü önbelleğe al
policy: pull-push # Önbelleği indir ve sonunda güncelle
script:
- npm install
- npm run build
cache ile bağımlılıklar yalnızca bir kez indirilir ve sonraki çalıştırmalarda önbellekten çekilir, bu da işlerin çok daha hızlı tamamlanmasını sağlar. key ile farklı branch'ler veya projeler için ayrı önbellekler oluşturabilirsiniz.
Artifacts (Üretilen Dosyalar) Yönetimi
artifacts, bir işin sonunda üretilen dosyaları (derlenmiş uygulamalar, test raporları, log dosyaları vb.) saklamak ve sonraki işlere aktarmak için kullanılır. Bu, özellikle bir aşamada derlenen uygulamanın sonraki aşamalarda test edilmesi veya dağıtılması gerektiğinde çok önemlidir.
build_application:
stage: build
script:
- make build
artifacts:
paths:
- dist/ # dist klasörünü artefakt olarak sakla
expire_in: 1 week # Saklama süresi
test_application:
stage: test
script:
- make test ARTIFACT_PATH=dist/ # Önceki işten gelen dist klasörünü kullan
needs: ["build_application"] # build_application işinin artefaktlarına ihtiyaç duyar
artifacts ayrıca GitLab UI üzerinden indirilebilir veya tarayıcıda görüntülenebilir hale getirilebilir (örneğin HTML test raporları).
rules Anahtar Kelimesi ile Koşullu İş Yürütme
rules, bir işin ne zaman çalışacağını veya atlanacağını son derece esnek bir şekilde belirlemenizi sağlar. Bu, only/except'ten çok daha güçlüdür ve karmaşık koşullar tanımlamanıza olanak tanır. Örneğin, belirli bir branch'te, belirli bir tag'de veya bir değişkenin değerine göre işleri çalıştırabilirsiniz.
deploy_production:
stage: deploy
script:
- echo "Deploying to production..."
rules:
- if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/' # Sadece vX.Y.Z formatındaki tag'lerde çalıştır
when: manual # Manuel onay gerektir
- if: '$CI_COMMIT_BRANCH == "main"' # main branch'inde otomatik çalıştır
when: on_success
- when: never # Diğer durumlarda asla çalıştırma
Bu örnekte, production dağıtımı sadece belirli bir tag yapıldığında manuel olarak veya main branch'ine push yapıldığında otomatik olarak tetiklenir. rules ile daha temiz ve okunabilir koşullar yazabilirsiniz.
Parent-Child Pipelines ve DAGs (Directed Acyclic Graphs)
Büyük monorepo'lar veya mikroservis mimarileri için tek bir devasa .gitlab-ci.yml dosyası yönetmek zor olabilir. Parent-Child Pipelines ve DAGs, bu sorunu çözmek için tasarlanmıştır:
- Parent-Child Pipelines: Bir ana pipeline'ın (parent) dinamik olarak alt pipeline'lar (child) oluşturmasını sağlar. Her alt pipeline kendi
.gitlab-ci.ymldosyasına sahip olabilir ve sadece ilgili kod değişiklikleri olduğunda tetiklenebilir. Bu, pipeline'ları modüler hale getirir ve paralel çalışmayı artırır. - DAGs (Directed Acyclic Graphs): İşler arasındaki bağımlılıkları tanımlamanıza olanak tanır. Varsayılan olarak aşamalar sırayla çalışırken, DAGs ile farklı aşamalardaki bağımsız işlerin paralel çalışmasını sağlayarak pipeline süresini kısaltabilirsiniz. Bu,
needsanahtar kelimesi ile gerçekleştirilir.
# Parent Pipeline: child pipeline'ı tetikler
trigger_child_pipeline:
stage: build
trigger:
include: path/to/child-ci.yml # Child pipeline dosyasının yolu
strategy: depend # Parent pipeline, child pipeline'ın sonucunu bekler
Bu özellikler, büyük ölçekli ve karmaşık projeler için CI/CD süreçlerini optimize etmede kilit rol oynar. Modülerlik, koşullu çalıştırma ve performans artırıcı mekanizmalar sayesinde, pipeline'larınız daha hızlı, daha güvenilir ve daha yönetilebilir hale gelir.
GitLab CI/CD ve Mobil Uyumlu Geliştirme Süreçleri: Responsive Tasarımın Rolü
Günümüz internet dünyasında, bir web sitesinin veya uygulamasının farklı cihaz boyutlarına ve ekran çözünürlüklerine uyum sağlayabilmesi kritik bir öneme sahiptir. Mobil uyumluluk ve responsive tasarım, artık bir lüks değil, standart bir gerekliliktir. Kullanıcıların büyük bir kısmı internete mobil cihazlar üzerinden eriştiği için, projenizin bu beklentiyi karşılaması doğrudan kullanıcı deneyimini ve dolayısıyla iş başarısını etkiler. Peki, GitLab CI/CD, bu mobil uyumlu geliştirme süreçlerine nasıl entegre edilebilir ve responsive tasarımın kalitesini nasıl garanti altına alabiliriz?
GitLab CI/CD, yazılım geliştirme sürecinin her aşamasında otomasyon sağladığı gibi, mobil uyumluluğun ve responsive tasarımın da sürekli olarak denetlenmesine olanak tanır. Bir frontend projesi için pipeline'ınızda, responsive tasarımın doğruluğunu ve çeşitli ekran boyutlarındaki davranışını test eden otomatik adımlar ekleyebilirsiniz. Bu, hem görsel regresyonları erkenden yakalamanıza hem de farklı cihazlar için tutarlı bir deneyim sunmanıza yardımcı olur.
CI/CD ile Responsive Tasarımın Otomatik Kontrolü
GitLab CI/CD pipeline'ınızda responsive tasarım kontrolleri için çeşitli yöntemler kullanabilirsiniz:
- Görsel Regresyon Testleri: Selenium, Cypress, Playwright gibi araçlar veya özel görsel regresyon test kütüphaneleri kullanarak, belirli ekran boyutlarında web sayfanızın ekran görüntülerini alıp, bu görüntüleri referans görüntülerle karşılaştırabilirsiniz. Her yeni kod değişikliğinde, farklı cihaz boyutları için sayfanın beklendiği gibi göründüğünden emin olursunuz.
- Linting ve Code Standardı Kontrolleri: CSS preprocessor'larınız (Sass, Less) veya PostCSS gibi araçlarınızla responsive tasarım için belirlenen standartlara uyulup uyulmadığını otomatik olarak kontrol edebilirsiniz. Örneğin, belirli breakpoint'lerin doğru kullanılıp kullanılmadığı veya gereksiz stiller içerip içermediği denetlenebilir.
- Performans Testleri: Mobil cihazlarda sayfa yükleme hızı ve performans kritik önem taşır. Lighthouse veya WebPageTest gibi araçları CI/CD pipeline'ınıza entegre ederek, web uygulamanızın mobil performans skorlarını düzenli olarak ölçebilir ve olumsuz değişiklikleri erkenden tespit edebilirsiniz.
Örneğin, bir frontend projeniz varsa, derleme ve test aşamalarından sonra görsel regresyon testleri çalıştıran bir iş ekleyebilirsiniz:
visual_regression_test:
stage: test
image: cypress/browsers:node16.14.0-chrome99-ff97
script:
- npm install
- npm run cypress:run -- --config video=false --env SIZES="375,768,1280" # Farklı ekran boyutlarında testler
artifacts:
when: always
paths:
- cypress/screenshots/
- cypress/videos/
expire_in: 1 day
needs:
- frontend_build # Frontend derleme işinin artefaktlarına ihtiyaç duyabilir
Bu iş, Cypress gibi bir araç kullanarak belirli ekran boyutlarında (örneğin 375px mobil, 768px tablet, 1280px masaüstü) otomatik testler çalıştırır ve ekran görüntüleri veya videolar oluşturur. Bu çıktılar artefakt olarak saklanarak, geliştiricilerin pipeline başarısız olduğunda sorunu görsel olarak incelemesine olanak tanır.
Mobil uyumlu HTML'e bir örnek teşkil etmesi açısından, tipik bir responsive CSS media query aşağıdaki gibi görünebilir. Bu tür kurallar CI/CD pipeline'ındaki görsel testlerle veya linting araçlarıyla doğrulanabilir:
/* Temel stil (Mobil öncelikli) */
body {
font-size: 16px;
margin: 10px;
}
/* Orta boyutlu ekranlar için (tabletler) */
@media (min-width: 768px) {
body {
font-size: 18px;
margin: 20px;
}
.sidebar {
width: 200px;
float: left;
}
}
/* Büyük ekranlar için (masaüstü) */
@media (min-width: 1200px) {
body {
font-size: 20px;
margin: 30px;
}
.sidebar {
width: 250px;
float: left;
}
.main-content {
margin-left: 270px;
}
}
Sonuç olarak, GitLab CI/CD, responsive tasarımın ve mobil uyumluluğun sadece tasarım aşamasında değil, tüm geliştirme ve dağıtım yaşam döngüsü boyunca sürdürülmesini ve kalitesinin garanti altına alınmasını sağlayan güçlü bir araçtır. Otomatik testler ve kontroller sayesinde, ürününüzün her zaman ve her cihazda mükemmel bir kullanıcı deneyimi sunmasını sağlayabilirsiniz.
GitLab CI/CD İpuçları ve En İyi Uygulamalar: Pipeline'larınızı Daha Etkili Kullanmak İçin Püf Noktaları Nelerdir?
GitLab CI/CD'den en iyi şekilde yararlanmak için sadece temel özelliklerini bilmek yeterli değildir; aynı zamanda deneyimli kullanıcıların kullandığı ipuçlarını ve en iyi uygulamaları benimsemek de önemlidir. Bu bölümde, pipeline'larınızın güvenliğini, performansını ve sürdürülebilirliğini artıracak stratejiler üzerinde duracağız.
1. Hassas Veri Yönetimi: Değişkenler ve Secret'lar
Dağıtım anahtarları, API token'ları, veritabanı şifreleri gibi hassas bilgiler asla .gitlab-ci.yml dosyasının içinde veya Git deposunda düz metin olarak saklanmamalıdır. GitLab CI/CD, bu tür verileri güvenli bir şekilde yönetmek için "CI/CD Variables" özelliğini sunar.
- Ortam Değişkenleri: GitLab arayüzünde (Settings -> CI/CD -> Variables) tanımlanan değişkenler, pipeline işleri çalışırken otomatik olarak ortam değişkenleri olarak erişilebilir hale gelir. Bunları "Protected" (Korunmuş) ve "Masked" (Maskelenmiş) olarak işaretleyerek daha da güvenli hale getirebilirsiniz.
- Vault Entegrasyonu: Daha ileri düzey güvenlik gereksinimleri için, GitLab'ın HashiCorp Vault gibi harici secret yönetim sistemleriyle entegrasyonu mevcuttur. Bu, secret'ların yaşam döngüsünü daha merkezi ve güvenli bir şekilde yönetmenizi sağlar.
deploy_job:
stage: deploy
script:
- echo "Deploying with API Key: $API_KEY" # API_KEY GitLab CI/CD Variable'dan gelir
- ssh -i $SSH_PRIVATE_KEY user@host "..." # SSH_PRIVATE_KEY de bir değişkendir
API_KEY veya SSH_PRIVATE_KEY gibi değişkenler GitLab UI'da tanımlanmıştır ve pipeline tarafından güvenli bir şekilde kullanılır.
2. Pipeline Performansını Optimize Etme
- Paralel Çalıştırma: Aynı aşama içindeki işler paralel olarak çalışır. Bağımsız testleri veya derleme adımlarını ayrı işler olarak tanımlayarak pipeline sürenizi kısaltabilirsiniz.
- Önbellekleme (Caching): Daha önce bahsedildiği gibi,
cachekullanarak bağımlılıkların yeniden indirilmesini önleyin. Anahtar stratejisini (key) doğru belirlemek önemlidir (örneğin branch bazlı veya global). - Docker İmajlarını Optimize Etme: İşleriniz için mümkün olduğunca küçük ve optimize edilmiş Docker imajları kullanın. Gerekli araçları içeren özel imajlar oluşturmak, indirme sürelerini ve disk alanını azaltır.
- Sadece İlgili Değişikliklerde Çalıştırma (
rules: changes): Bir önceki gerçek dünya senaryosunda olduğu gibi,rules: if: '$CI_COMMIT_BRANCH == "main"' changes: [...]ile sadece ilgili kod veya dizinlerde değişiklik olduğunda belirli işlerin çalışmasını sağlayın. Bu, monorepo'larda çok verimli olabilir.
3. Pipeline Kodunun Yeniden Kullanılabilirliği ve Modülerliği
Büyük projelerde veya birden fazla benzer projeyi yönetirken, pipeline kodunu yeniden kullanılabilir ve modüler hale getirmek önemlidir. Bu, DRY (Don't Repeat Yourself) prensibini uygulamanıza yardımcı olur.
extendsAnahtar Kelimesi: Ortak iş veya job şablonları tanımlayabilir ve diğer işlerin bu şablonları miras almasını sağlayabilirsiniz. Bu, benzer işler için kod tekrarını önler.includeAnahtar Kelimesi: Harici YAML dosyalarını pipeline tanımınıza dahil etmenizi sağlar. Bu sayede, ortak CI/CD yapılandırmalarını ayrı dosyalarda saklayabilir ve birden fazla projede yeniden kullanabilirsiniz. Örneğin, tüm projeleriniz için ortak bir test işi tanımlayabilir ve her projenin.gitlab-ci.ymldosyasına dahil edebilirsiniz.
# .gitlab-ci.yml
include:
- 'templates/.gitlab-ci-build.yml' # Ortak build şablonunu dahil et
- 'templates/.gitlab-ci-deploy.yml' # Ortak deploy şablonunu dahil et
# templates/.gitlab-ci-build.yml içeriği:
.build_template: # Nokta ile başlayan işler gizli şablonlardır
image: node:18-alpine
script:
- echo "Building..."
- npm install
- npm run build
# Mevcut pipeline'da şablonu kullan
my_app_build:
extends: .build_template # .build_template şablonunu miras al
stage: build
artifacts:
paths:
- build/
Bu yöntemler, pipeline'larınızın daha düzenli, okunabilir ve yönetilebilir olmasını sağlar, özellikle de CI/CD stratejinizin zamanla evrimleşmesi gerektiğinde esneklik sunar.
debug modu ekleyerek veya CI_DEBUG_TRACE: "true" ortam değişkenini kullanarak işlerin neden başarısız olduğunu anlamak için daha fazla log çıktısı alabilirsiniz.
Bu ipuçları ve en iyi uygulamalar, GitLab CI/CD kullanımınızı bir sonraki seviyeye taşıyarak, daha güvenli, hızlı ve sürdürülebilir yazılım geliştirme süreçleri oluşturmanıza yardımcı olacaktır. Otomasyonun gücünden tam olarak yararlanmak için sürekli öğrenmeye ve pipeline'larınızı optimize etmeye devam edin.
Sonuç: GitLab CI/CD ile Geleceğin Yazılım Geliştirme Süreçleri
Bu kapsamlı rehber boyunca, GitLab CI/CD'nin temel prensiplerinden başlayarak, pratik pipeline oluşturma adımlarına, gerçek dünya senaryolarından ileri düzey özelliklere ve en iyi uygulamalara kadar birçok konuyu derinlemesine inceledik. Modern yazılım geliştirme dünyasında sürekli entegrasyon ve teslimatın ne kadar kritik olduğunu, GitLab CI/CD'nin bu süreçleri nasıl tek bir platformda entegre ederek verimliliği ve güvenilirliği artırdığını detaylı bir şekilde gördük.
GitLab CI/CD, basit bir statik web sitesinden karmaşık mikroservis mimarilerine kadar her türlü projeye uyarlanabilen esnek ve güçlü bir araç setidir. Kodunuzu otomatik olarak test etmek, derlemek ve dağıtmak, hataları erkenden yakalamak ve yeni özellikleri kullanıcılara hızla ulaştırmak artık bir lüks değil, bir zorunluluktur. Otomatikleştirilmiş pipeline'lar sayesinde geliştiriciler, operasyonel yüklerden kurtulup daha fazla inovasyona odaklanabilirken, ekipler daha şeffaf ve işbirliğine dayalı bir çalışma ortamı elde eder.
Unutmayın ki CI/CD yolculuğu sürekli bir öğrenme ve iyileştirme sürecidir. Pipeline'larınızı düzenli olarak gözden geçirmek, performans darboğazlarını gidermek, güvenlik açıklarını kapatmak ve yeni GitLab özelliklerini takip etmek, bu süreçten en yüksek verimi almanızı sağlayacaktır. GitLab CI/CD, DevOps kültürünü benimseyen ekipler için sadece bir araç değil, aynı zamanda yazılım geliştirme pratiklerini dönüştüren stratejik bir yatırımdır. Geleceğin yazılım geliştirme süreçlerinde otomasyonun ve sürekli akışın vazgeçilmez bir parçası olmaya devam edecektir.
Sıkça Sorulan Sorular
-
S: GitLab CI/CD kullanmak ücretli midir?
C: GitLab CI/CD'nin temel özellikleri ve Paylaşımlı Runner'lar, GitLab'ın ücretsiz (Free) planında sınırlı dakikalarla birlikte gelir. Kendi özel Runner'larınızı kurarak bu sınırlamayı aşabilirsiniz. Daha gelişmiş özellikler ve daha fazla CI/CD dakikası için ücretli GitLab planları mevcuttur.
-
S: Kendi GitLab Runner'ımı nasıl kurarım?
C: Kendi GitLab Runner'ınızı Linux, Windows veya macOS sistemlerinize kolayca kurabilirsiniz. Kurulum talimatları GitLab dokümantasyonunda detaylı olarak verilmiştir. Kurulumdan sonra Runner'ı GitLab örneğinize kaydetmeniz ve pipeline işlerinde kullanmak üzere etiketlemeniz gerekir.
-
S: CI/CD Pipeline'ım neden başarısız oluyor? Nasıl hata ayıklayabilirim?
C: Pipeline başarısızlıkları genellikle
.gitlab-ci.ymldosyasındaki sözdizimi hatalarından, yanlış komutlardan, eksik bağımlılıklardan veya ortam sorunlarından kaynaklanır. Hata ayıklama için şunları yapabilirsiniz: İş loglarını dikkatlice inceleyin, işin Docker imajını yerel olarak çalıştırıp komutları manuel olarak deneyin,echokomutlarıyla değişken değerlerini ve komut çıktılarını kontrol edin veyaCI_DEBUG_TRACE: "true"değişkenini kullanarak daha detaylı loglar alın. -
S: GitLab CI/CD'yi farklı programlama dilleri veya teknolojileriyle kullanabilir miyim?
C: Kesinlikle! GitLab CI/CD agnostik bir yapıya sahiptir. İşlerinizde kullanacağınız Docker imajını belirleyerek (örneğin
node,python,ruby,maven,golangimajları), herhangi bir programlama dili veya teknolojiyle CI/CD süreçleri oluşturabilirsiniz. Sadece ilgili dillerin veya araçların komutlarınıscriptbölümüne eklemeniz yeterlidir. -
S: GitLab CI/CD'de "stages" ve "needs" arasındaki fark nedir?
C:
stages, pipeline'daki mantıksal aşamaları (örneğin build, test, deploy) tanımlar ve aşamalar genellikle sırayla çalışır. Aynı aşama içindeki işler paralel çalışabilir.needsise işler arasındaki belirli bağımlılıkları tanımlar. Bir iş, kendinden önceki herhangi bir aşamadaki veya kendi aşamasındaki belirli bir işin tamamlanmasını bekleyebilir. Bu, aşama sıralamasından bağımsız olarak işlerin daha esnek bir şekilde paralel çalışmasını sağlayarak pipeline süresini optimize etmenizi sağlar.
