GitHub Actions ile CI/CD Pipeline Otomasyonu

# Rehber: Modern CI/CD Pipeline Otomasyonu (GitHub Actions) CI/CD, kodun test edilmesini, derlenmesini ve dağıtılmasını otomatikleştirir. GitHub Acti...

GitHub Actions ile CI/CD Pipeline Otomasyonu

Rehber: Modern CI/CD Pipeline Otomasyonu (GitHub Actions)

CI/CD, kodun test edilmesini, derlenmesini ve dağıtılmasını otomatikleştirir. GitHub Actions bu süreci depo içinde YAML ile tanımlamanıza olanak tanır: ayrı bir CI sunucusu kurmadan, kod ile birlikte sürümlenen iş akışları yazarsınız.

Bu rehber, GitHub Actions'ın temel kavramlarını ve üretimde işe yarayan kalıpları ele alır. Örnekler ubuntu-latest çalıştırıcı üzerinde çalışacak şekilde yazılmıştır; eylem (action) sürümleri için @v4 gibi ana sürüm etiketleri kullanılmıştır. Bu tür etiketler GitHub tarafından yönetilir ve zaman içinde güncellenir; belirli bir sürüm numarasını ezberlemek yerine resmi dokümantasyondan güncel etiketi doğrulamanız beklenir.

Önkoşullar

  • GitHub deposu ve depoya yazma yetkiniz.
  • Depoda .github/workflows/ dizini (yoksa oluşturulur).
  • İş akışının çalıştıracağı araçların (dil çalışma zamanı, paket yöneticisi vb.) kurulum adımlarının tanımlanması.

Temel Kavramlar

  • Workflow (iş akışı): .github/workflows/ altındaki bir YAML dosyası. Bir veya daha fazla job içerir.
  • Event (olay): İş akışını tetikleyen şey (push, pull_request, schedule, workflow_dispatch vb.).
  • Job: Aynı çalıştırıcıda çalışan adımlar kümesi. Varsayılan olarak job'lar paralel çalışır.
  • Step: Bir job içindeki tek bir görev. Ya bir run komutu ya da bir uses eylemidir.
  • Runner: Job'u çalıştıran makine. GitHub tarafından barındırılan veya kendi barındırdığınız (self-hosted) çalıştırıcı olabilir.
  • Action: Yeniden kullanılabilir bir görev birimi. uses ile çağrılır.

İlk İş Akışı: Test ve Derleme

Aşağıdaki örnek, main dalına yapılan push ve pull request'lerde test çalıştırır. Node.js kullanılıyor; başka bir dilde setup-* eylemini ve test komutunu değiştirmeniz yeterlidir.

name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Depoyu çek
        uses: actions/checkout@v4

      - name: Node.js kur
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Bağımlılıkları kur
        run: npm ci

      - name: Testleri çalıştır
        run: npm test

Beklenen davranış: npm ci, package-lock.json dosyasına göre deterministik bir kurulum yapar; npm install'a kıyasla kilit dosyasını değiştirmez. cache: 'npm' seçeneği bağımlılık önbelleğini etkinleştirir ve sonraki çalıştırmaları hızlandırır.

Job'ları Zincirlemek: needs

Varsayılan olarak job'lar paralel çalışır. Bir job'un diğerini beklemesi için needs kullanın.

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm test

  build:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run build

build job'u yalnızca test başarıyla tamamlandığında çalışır. Bir job başarısız olursa ona bağlı job'lar varsayılan olarak atlanır.

Matris Stratejisi ile Çoklu Ortam

Aynı testleri birden çok dil sürümünde veya işletim sisteminde çalıştırmak için strategy.matrix kullanın.

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest]
        node: ['18', '20']
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
      - run: npm ci
      - run: npm test

fail-fast: false, bir kombinasyon başarısız olduğunda diğerlerinin iptal edilmemesini sağlar; hata matrisinin tamamını görmek için kullanışlıdır. Toplam job sayısı os × node kadardır; matrisi gereğinden fazla büyütmek dakika tüketimini artırır.

Sırlar ve Ortam Değişkenleri

Sırlar (token, parola, API anahtarı) kod içine yazılmaz. Depo veya organizasyon ayarlarından tanımlanır ve secrets bağlamıyla kullanılır.

steps:
  - name: Dağıt
    env:
      API_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
    run: ./deploy.sh

Güvenlik notları:

  • Sırlar günlüklere yazdırılmamalıdır; GitHub bilinen desenleri maskeler ama bu garanti değildir. echo ile sır yazdırmaktan kaçının.
  • pull_request olayında çalışan iş akışları, çatallanmış (fork) depolardan gelen PR'larda sırlara erişemez. Bu, kötü niyetli PR'ların sırları sızdırmasını engelleyen bir tasarım tercihidir.
  • pull_request_target tetikleyicisi sırlara erişebilir; ancak gelen PR kodunu çalıştırırsanız sırları sızdırma riski doğar. Bu tetikleyiciyi yalnızca ne yaptığınızdan emin olduğunuzda ve PR kodunu çalıştırmadan kullanın.
  • Üçüncü taraf eylemleri ana sürüm etiketiyle (@v4) çağırmak yaygındır; en sıkı güvenlik için eylemleri tam commit SHA'sına sabitlemek de bir seçenektir.

Önbellekleme

Bağımlılık kurulumunu hızlandırmak için actions/cache veya yerleşik önbellek desteği kullanılır. Önbellek anahtarı, bağımlılık dosyasının içeriğine bağlanmalıdır; aksi halde eski önbellek yanlış sonuç üretebilir.

- uses: actions/cache@v4
  with:
    path: ~/.npm
    key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-npm-

hashFiles, kilit dosyası değiştiğinde yeni bir önbellek anahtarı üretir; restore-keys ise tam eşleşme bulunamazsa en yakın önbelleği geri yükler.

Koşullu Çalıştırma

Adımları veya job'ları belirli koşullarda çalıştırmak için if kullanın.

- name: Yalnızca main dalında dağıt
  if: github.ref == 'refs/heads/main' && github.event_name == 'push'
  run: ./deploy.sh

if ifadelerinde ${{ }} sözdizimi isteğe bağlıdır; GitHub bu ifadeleri zaten ifade olarak değerlendirir. Koşulları açık yazmak, yanlışlıkla üretime dağıtım gibi hataları önler.

Artifact (Çıktı) Yönetimi

Bir job'da üretilen dosyaları (derleme çıktısı, test raporu) saklamak veya başka job'lara aktarmak için artifact kullanılır.

- name: Derleme çıktısını yükle
  uses: actions/upload-artifact@v4
  with:
    name: build-output
    path: dist/

Artifact'ler varsayılan olarak belirli bir saklama süresiyle tutulur; süreyi retention-days ile ayarlayabilirsiniz. Artifact'ler job'lar arasında paylaşılabilir ama bunun için indirme adımı gerekir.

Güvenli Dağıtım İçin Ortamlar (Environments)

Üretim dağıtımını korumak için GitHub'ın "Environments" özelliği kullanılabilir. Bir ortama koruma kuralı (örneğin manuel onay veya belirli dallarla sınırlama) ekleyebilirsiniz.

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4
      - run: ./deploy.sh

environment: production tanımı, o ortama atanmış koruma kurallarını devreye sokar. Onay gerektiren bir ortamda job, onay verilene kadar bekler. Bu, kazara üretime dağıtımı engellemenin en pratik yollarından biridir.

Yaygın Hatalar

  • Kilit dosyası yerine npm install kullanmak: npm ci deterministik kurulum sağlar; CI'da tercih edilmelidir.
  • Sırları günlüğe yazdırmak: Sızıntı riski yaratır. Hata ayıklarken bile sır değerlerini yazdırmayın.
  • needs olmadan bağımlı job'lar tanımlamak: Job'lar paralel başlar; sıralama bekliyorsanız needs şarttır.
  • pull_request_target ile gelen PR kodunu çalıştırmak: Sır sızıntısına yol açabilir.
  • Önbellek anahtarını bağımlılık dosyasına bağlamamak: Eski önbellek yanlış veya tutarsız sonuç üretir.
  • Matrisi gereğinden fazla büyütmek: Dakika tüketimini ve geri bildirim süresini artırır.
  • Sürüm etiketlerini sabitlememek: @main gibi hareketli referanslar beklenmedik değişiklikler getirir; ana sürüm etiketi veya commit SHA'sı kullanın.

Sonuç

GitHub Actions'ta sağlam bir pipeline'ın temeli birkaç ilkeye dayanır: olayları ve job bağımlılıklarını açık tanımlamak, sırları asla koda gömmemek, önbelleği doğru anahtarlamak ve üretim dağıtımını ortam korumalarıyla sınırlamak. Bu yapıyı kurduğunuzda test, derleme ve dağıtım adımlarını hem hızlı hem de denetlenebilir biçimde otomatikleştirebilirsiniz.

İLGİLİ İÇERİKLER

Bunları da Okumak İsteyebilirsiniz