Takip et

GitLab CI/CD: Yazılım Geliştirme Süreçlerinde Otomasyon ve Verimlilik

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.

Uzman İpucu: GitLab CI/CD, kodunuzu ve CI/CD yapılandırmanızı tek bir platformda birleştirerek “tek kaynak gerçeklik” ilkesini benimsetir. Bu, tutarlılığı artırır ve karmaşıklığı azaltır.

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, test ve deploy aşamalarını tanımlar. Bunlar sırasıyla çalışacaktır.
  • build_job: build aşamasında çalışan bir iş. node:16-alpine Docker imajını kullanarak bağımlılıkları kurar (npm install) ve uygulamayı derler (npm run build). artifacts anahtar kelimesi ile derlenmiş dosyaların (build/ klasörü) saklanmasını ve bir sonraki aşamalarda kullanılabilmesini sağlar.
  • test_job: test aşamasında çalışan bir iş. Yine node:16-alpine imajını kullanır ve npm test komutuyla testleri çalıştırır. needs: ['build_job'] ifadesi, bu işin build_job'ın başarılı bir şekilde tamamlanmasını beklediğini ve onun artefaktlarına ihtiyaç duyduğunu belirtir.
  • deploy_job: deploy aşamasında çalışan bir iş. rules anahtar kelimesi ile sadece main branch'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şin script bö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şin script bö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: main branch'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/ ve backend/ adında iki alt dizin olduğunu varsayar.
  • before_script ile Dizin Değiştirme: Her işin başında cd frontend veya cd backend kullanarak ilgili proje dizinine geçiş yapıyoruz. Bu, komutların doğru yerde çalışmasını sağlar.
  • artifacts Kullanımı: frontend_build işi, derlenmiş React uygulamasını içeren frontend/build/ dizinini artefakt olarak saklar. deploy_staging ve deploy_production işleri bu artefaktları otomatik olarak indirir ve dağıtım sırasında kullanır. Benzer şekilde, backend_build işi bağımlılıkları saklar, ancak dağıtım aşamasında doğrudan sunucuda npm install yapmak daha yaygın ve güvenlidir.
  • rules ile Koşullu Çalıştırma:
    • Derleme ve test işleri, sadece ilgili dizinlerde (frontend//* veya backend//*) 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_staging işi, sadece main branch'ine yapılan push'larda otomatik olarak tetiklenir.
    • deploy_production işi, main branch'inde manuel olarak tetiklenecek şekilde ayarlanmıştır (when: manual). Bu, canlıya dağıtım öncesi manuel kontrol sağlar.
  • needs Kullanımı: İşler arasındaki bağımlılıkları belirtmek için needs anahtar 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/git gibi 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_IP gibi 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_staging ve deploy_production işleri için environment anahtar 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.yml dosyası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, needs anahtar 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, cache kullanarak 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.

  • extends Anahtar 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.
  • include Anahtar 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.yml dosyası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.

Uzman İpucu: Pipeline'larınızda 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.yml dosyası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, echo komutlarıyla değişken değerlerini ve komut çıktılarını kontrol edin veya CI_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, golang imajları), herhangi bir programlama dili veya teknolojiyle CI/CD süreçleri oluşturabilirsiniz. Sadece ilgili dillerin veya araçların komutlarını script bö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. needs ise 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.

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.