GitHub Actions Nedir? CI/CD Otomasyonuna Giriş

GitHub Actions'la kod push'ladığında testlerin otomatik çalışmasını, build alınmasını ve deploy edilmesini nasıl kuracağını YAML örnekleriyle adım adım anlatıyorum.

Programlar
GitHub Actions Nedir? CI/CD Otomasyonuna Giriş

Bir pull request açtığında testlerin kendiliğinden koştuğunu, main dalına birleşince sitenin otomatik güncellendiğini gördüysen, arkasında büyük ihtimalle GitHub Actions vardı. GitHub bu özelliği 2019'da kullanıma açtı; o günden beri ayrı bir CI/CD aracı kurmadan, otomasyonu doğrudan reponun içine tanımlayabilirsin. Jenkins gibi araçlarla kıyaslandığında kurulum yükü büyük ölçüde ortadan kalkıyor, çünkü çalıştırma ortamları (runner) zaten GitHub'ın sunucularında hazır duruyor.

Bu yazıda workflow dosyasının yapısını, ilk pipeline'ı nasıl kuracağını, matrix build ile birden fazla ortamda test etmeyi ve secrets yönetimini gerçek YAML örnekleriyle anlatıyorum. Örnekleri kendi reponda deneyerek takip edebilirsin.

GitHub Actions Nedir ve Nasıl Çalışır

GitHub Actions, reponun .github/workflows/ klasörüne yazılan YAML dosyalarıyla tetiklenen bir otomasyon sistemi. Push, pull request açılması, issue oluşturulması ya da zamanlanmış bir saat gibi bir olay gerçekleştiğinde GitHub bu dosyayı okuyor ve tanımlı adımları kendi sunucularında, runner denen geçici sanal makinelerde çalıştırıyor.

Runner'lar varsayılan olarak Ubuntu, Windows veya macOS imajı kullanıyor; her çalıştırmada sıfırdan kuruluyor, iş bitince siliniyor. Kendi sunucunu self-hosted runner olarak da bağlayabilirsin, GPU gerektiren bir build ya da şirket içi ağa erişim gereken bir iş için bu tercih ediliyor. Ücretsiz katmanda public repolar sınırsız dakika kullanabilir, private repolarda ise aylık bir dakika kotası var. Bu kota zamanla değişebilir; güncel rakamı GitHub'ın fiyatlandırma sayfasından kontrol etmek gerekiyor.

Sonuçta Jenkins gibi ayrı bir sunucu kurup bakımını üstlenmene gerek kalmıyor. Workflow dosyası reponun bir parçası olduğu için kodla birlikte versiyonlanıyor ve pull request içinde review edilebilir.

İş Akışı Dosyasının Anatomisi: Trigger, Job, Step

Her workflow dosyası üç katmandan kuruluyor. En üstte on: anahtarı hangi olayın workflow'u tetikleyeceğini belirliyor. Onun altında jobs: bloğu yer alıyor; her job kendi runner'ında, diğerlerinden bağımsız çalışıyor. Job'ın içinde de sırayla işleyen steps: listesi bulunuyor.

CI/CD boru hattının push, test, build ve deploy aşamalarını gösteren akış şeması

Basit bir CI workflow'u şöyle kuruluyor:

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

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npm test

actions/checkout@v4 adımı reponu runner'a klonluyor, actions/setup-node@v4 adımı Node.js kuruyor. Sonraki iki satır bağımlılıkları yüklüyor ve testleri çalıştırıyor. uses: hazır bir action'ı çağırırken run: doğrudan shell komutu çalıştırıyor; aynı step içinde ikisi bir arada kullanılamıyor, her step ya biri ya diğeri. Workflow sözdiziminin temellerini GitHub Actions'ın resmi öğreticisinden öğrenebilirsiniz.

Tetikleyici seçimi önemli, çünkü yanlış tetikleyici gereksiz dakika tüketiyor. En sık kullanılan dört tetikleyici şöyle:

TetikleyiciNe zaman çalışırTipik kullanım
pushBelirtilen branch'e commit gidinceHer commit'te lint/test
pull_requestPR açılınca veya güncelleninceMerge öncesi doğrulama
scheduleCron ifadesiyle belirlenen saatteGece nightly build, bağımlılık taraması
workflow_dispatchManuel olarak Actions sekmesinden tetikleninceElle tetiklenen deploy

İlk CI/CD Boru Hattını Kurmak

CI (continuous integration) kısmı genelde test ve lint çalıştırmakla sınırlı kalıyor: kod push'landığında hatalı bir şeyi erken yakalamak amacı taşıyor. CD (continuous deployment) ise testler geçtikten sonra kodu otomatik olarak bir ortama göndermek anlamına geliyor. Bu ortam staging olabilir, production olabilir.

Test ve deploy işini ayrı job'lara bölmek mantıklı, çünkü deploy job'ı yalnızca test job'ı başarılı olduğunda çalışmalı. Bu bağımlılığı needs: anahtarıyla kuruyorsun:

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

  deploy:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Deploy to server
        run: ./deploy.sh
        env:
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}

if: koşulu deploy'un yalnızca main dalında çalışmasını sağlıyor. Bir feature branch'te testler geçse bile deploy tetiklenmiyor. Bu ayrım takım büyüdükçe daha da önem kazanıyor, çünkü herkesin branch'inde otomatik deploy denemesi hem gereksiz hem riskli.

Gerçek projelerde genelde üçüncü bir job daha eklenir: build. Docker image oluşturup registry'ye push etmek ya da statik siteyi derleyip CDN'e yüklemek gibi işler test ile deploy arasına giriyor. Job sayısı arttıkça needs: [test, build] yazarak birden fazla bağımlılık da tanımlayabilirsin.

Matris Derlemeleri ile Çoklu Ortam Testi

Bir kütüphane geliştiriyorsan tek Node sürümünde test etmek yeterli olmuyor, çünkü kullanıcıların hangi sürümü çalıştıracağını bilemezsin. Matrix strategy tam bu noktada işe yarıyor: aynı job'ı farklı parametre kombinasyonlarıyla paralel çalıştırıyor.

GitHub Actions YAML workflow dosyasını gösteren kod editörü penceresi
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18, 20, 22]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm ci
      - run: npm test

Bu tanım aynı test job'ını üç kez, her defasında farklı bir Node sürümüyle paralel çalıştırıyor. Matrise os: [ubuntu-latest, windows-latest, macos-latest] ekleyerek sürüm ve işletim sistemini çapraz kombinasyonlarla da test edebilirsin. Üç sürüm çarpı üç işletim sistemi, dokuz ayrı çalıştırma anlamına geliyor.

Dikkat edilmesi gereken nokta, matrix'in dakika tüketimini katlaması. Private repoda kota kısıtlıysa exclude: ile gereksiz kombinasyonları eleyip yalnızca gerçekten desteklediğin kombinasyonları bırakman gerekiyor.

Gizli Bilgileri ve İzinleri Güvenli Yönetmek

API anahtarını, deploy token'ını ya da veritabanı şifresini workflow dosyasına düz metin olarak yazma. Bu bilgileri repo ayarlarındaki Settings > Secrets and variables > Actions bölümünden tanımlıyorsun, workflow içinde de ${{ secrets.SECRET_ADI }} şeklinde çağırıyorsun.

Matrix strategy ile farklı Node.js sürümlerinde paralel çalışan test job'larını gösteren şema
- name: Push Docker image
  run: docker push myapp:latest
  env:
    REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}

Secrets, log çıktısında otomatik olarak *** şeklinde maskeleniyor. Yanlışlıkla echo $REGISTRY_TOKEN yazsan bile değer ekrana basılmıyor. Fork'lardan gelen pull request'lerde secrets'a erişim varsayılan olarak kısıtlı. Bu kısıtlama, kötü niyetli birinin PR açıp secrets'ı sızdırmaya çalışmasını önlemek için konulmuş. Bu davranışı anlamadan değiştirmemek gerekiyor.

En az ayrıcalık ilkesini workflow izinlerinde de uygulaman gerekiyor. GITHUB_TOKEN her çalıştırmada otomatik oluşuyor ve varsayılan olarak geniş yetkiler taşıyabilir. permissions: bloğuyla bu yetkiyi daraltmak iyi bir alışkanlık:

permissions:
  contents: read
  pull-requests: write

Organizasyon seviyesinde hangi action'ların kullanılabileceğini de kısıtlayabilirsin. Marketplace'te binlerce hazır action bulunuyor ama hepsi resmi GitHub tarafından yazılmıyor. Üçüncü taraf bir action'ı prod pipeline'ına eklemeden önce kaynağını incelemek makul bir önlem. Mümkünse commit SHA'sına pin'lemek de bu önlemi güçlendiriyor.

Workflow'u Hızlandırmak: Cache ve Paralel Çalıştırma

Bağımlılık kurulumu her çalıştırmada baştan yapılırsa dakikalar boşa gidiyor. actions/cache action'ı node_modules, pip paketleri ya da Maven repository'sini önbelleğe alarak bunu engelliyor.

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

Cache anahtarı package-lock.json dosyasının hash'ine bağlanıyor. Bağımlılıklar değişmediği sürece aynı cache tekrar kullanılıyor, değiştiğinde ise otomatik olarak yeni bir cache oluşuyor. Bu sayede eski veriyle çalışma riski ortadan kalkıyor.

Başka bir hız kazanımı gereksiz tetiklemeleri önlemekten geliyor. Yalnızca docs/ klasöründeki bir dosya değiştiyse testleri yeniden çalıştırmanın bir anlamı yok:

  • paths: ve paths-ignore: ayarlarıyla hangi dosya değişikliklerinin workflow'u tetikleyeceğini sınırlayabilirsin
  • needs: kullanmadan bıraktığın bağımsız job'ları GitHub otomatik olarak paralel çalıştırır
  • concurrency: ayarıyla aynı branch'te üst üste gelen çalıştırmaları iptal edip yalnızca sonuncusunu bekletebilirsin

Bu üç ayarı birlikte uyguladığında, özellikle büyük monorepo'larda pipeline süresi ciddi oranda kısalabilir.

Actions'ı Kod Dışında Kullanmak

GitHub Actions yalnızca build-test-deploy için kullanılmıyor. Issue açıldığında otomatik etiket eklemek, uzun süre güncellenmeyen pull request'leri kapatmak ya da belirli aralıklarla bağımlılık güncellemelerini kontrol etmek gibi proje yönetimi işlerini de otomatikleştirebilirsin.

workflow_dispatch ile manuel tetiklenen bir workflow tanımlayabilirsin. Haftalık rapor oluşturmak ya da eski branch'leri temizlemek gibi tek seferlik işleri Actions sekmesinden tek tıkla çalıştırabilirsin. Marketplace'teki actions/stale gibi hazır action'lar bu tür rutin işleri sıfırdan yazmana gerek bırakmıyor.

GitHub'ın resmi Actions dokümantasyonunu takip etmek, yeni eklenen özellikleri ve güncel limitleri görmek için iyi bir alışkanlık. Workflow dosyasını küçük tutmak ve her job'a tek bir sorumluluk vermek, dosyayı altı ay sonra tekrar açtığında ne yaptığını hatırlamanı kolaylaştırıyor.

Celil Uyanikoglu

Yazan Celil Uyanikoglu

Bilgisayar mühendisiyim; 25 yılı aşkın süredir bilgi işlem sektörünün içindeyim. Bu blogu 2020'de, işimde her gün karşılaştığım sorunların çözümlerini bir yere yazmak için açtım: Linux, güvenlik, tarayıcılar, yapay zeka araçları. Yazdığım her rehberi önce kendi bilgisayarımda ya da sunucumda deniyorum; çalıştığını görmediğim adımı yayınlamam. Hatalı ya da eskimiş bir şey görürsen iletişim sayfasından yaz — düzeltirim.

Yorum

Henüz yorum yok.

Sohbete katıl. Yorumlar yayınlanmadan önce moderasyondan geçer.

Yorum yap

E-posta adresin yayınlanmaz. Yorumlar moderasyondan sonra yayınlanır.

Sırada

İlgili notlar