Blog'a dön
•
ByteGurus

GitHub Actions ile CI/CD Hattını Hızlandırmak

GitHub Actions'ta CI/CD hattını hızlandırma ve maliyeti düşürme: önbellek, paralel işler, yol filtreleri, Docker katman önbelleği, eşzamanlılık ve zaman aşımı.

CI/CD GitHub Actions DevOps

İyi ayarlanmış bir CI/CD hattı, hızlı ve güvenilir dağıtımın temelidir. GitHub Actions derleme, test ve dağıtımı otomatikleştirmek için güçlü ve kod deposuyla bütünleşik bir araç; ama pek çok ekip hattını ayarlamadığı için hem zaman hem para kaybeder. Bu rehber GitHub Actions hatlarını hızlandırmanın ve ucuzlatmanın pratik yollarını anlatıyor.

Neden önemli

Hızlı bir hattın getirdikleri:

  • Kısa geri bildirim döngüsü: geliştirici sonucu saatler değil dakikalar içinde görür
  • Daha düşük maliyet: daha az çalışma dakikası, daha düşük fatura
  • Daha sık doğrulama: hızlı hat daha sık çalıştırılır
  • Daha iyi geliştirici deneyimi: derleme beklemek kimsenin işi değildir
  • Daha sık dağıtım: hızlı hat gerçek sürekli dağıtımı mümkün kılar

1. Bağımlılıkları önbelleğe alın

Bağımlılık kurulumu çoğu iş akışının en yavaş adımıdır. setup-* eylemlerinin yerleşik önbelleği ya da actions/cache bu adımı kısaltır.

Node.js:

name: Derle ve test et
on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: 'npm'          # ~/.npm indirme önbelleğini saklar

      - run: npm ci
      - run: npm test
      - run: npm run build

cache: 'npm' paketlerin indirme önbelleğini (~/.npm) saklar, node_modules klasörünü değil; npm ci yine çalışır ama paketleri ağdan indirmez. Kazancı ölçmek için önbellekli ve önbelleksiz iki çalışmanın süresini karşılaştırın.

Python, özel önbellek anahtarıyla:

- uses: actions/cache@v4
  with:
    path: ~/.cache/pip
    key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }}
    restore-keys: |
      ${{ runner.os }}-pip-

- run: pip install -r requirements.txt

Anahtarı bağımlılık dosyasının özetinden üretmek, önbelleğin yalnız bağımlılıklar değiştiğinde yenilenmesini sağlar.

2. İşleri paralel çalıştırın

Birbirine bağlı olmayan işleri sırayla çalıştırmak süreyi boşa harcar. GitHub Actions’ta ayrı işler (jobs) varsayılan olarak paralel çalışır:

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ['3.11', '3.12', '3.13']
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
          cache: 'pip'
      - run: pip install -r requirements.txt
      - run: pytest

  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: pipx run ruff check .

  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: pipx run bandit -r src

Testler üç Python sürümünde, lint ve güvenlik taraması da onlarla aynı anda çalışır; toplam süre en uzun işin süresine iner. Büyük test takımlarını parçalara bölüp (sharding) matriste dağıtmak aynı kazancı tek sürüm içinde de sağlar.

3. Yalnız gerekeni çalıştırın

Yalnız dokümantasyon değiştiğinde tüm testleri çalıştırmak gereksizdir. En basit yol tetikleyiciye yol filtresi koymaktır:

on:
  push:
    branches: [main]
    paths:
      - 'src/**'
      - 'package*.json'
      - '.github/workflows/ci.yml'
  pull_request:
    paths:
      - 'src/**'
      - 'package*.json'

Tek bir iş akışında hangi parçanın değiştiğine göre farklı işler çalıştırmak gerekiyorsa (monorepo gibi) değişen yolları hesaplayan bir adım ve iş düzeyinde if koşulu kullanın. Zorunlu durum kontrolü (required check) olan işleri tamamen atlamak, pull request’i “bekleniyor” durumunda bırakabilir; bu durumda işi çalıştırıp içindeki adımları atlamak daha güvenlidir.

Dağıtımı yalnız ana daldan yapın:

  deploy:
    needs: [test, lint, security]
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    runs-on: ubuntu-latest
    environment: production
    steps:
      - run: ./deploy.sh

4. Docker katmanlarını önbelleğe alın

Konteyner imajı derleyen hatlarda katman önbelleği en büyük kazançlardandır:

- uses: docker/setup-buildx-action@v3

- uses: docker/build-push-action@v6
  with:
    context: .
    push: ${{ github.ref == 'refs/heads/main' }}
    tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
    cache-from: type=gha
    cache-to: type=gha,mode=max

type=gha, katmanları GitHub’ın önbellek servisinde saklar. Dockerfile’da sık değişen satırları (uygulama kodunun kopyalanması) sona, seyrek değişenleri (bağımlılık kurulumu) başa koymak önbelleğin işe yarama oranını belirler.

5. Maliyeti ve boşa çalışmayı denetleyin

  • Çalıştırıcı seçimi: işlerin çoğunda ubuntu-latest; Windows ve macOS dakikaları daha pahalıdır, yalnız gerektiğinde kullanın
  • Zaman aşımı: takılan bir iş varsayılan olarak saatlerce dakika tüketebilir
  • Eşzamanlılık: aynı dal için yeni bir çalışma başladığında eskisini iptal edin
concurrency:
  group: ci-${{ github.ref }}
  cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 30

Ana dalda iptali kapatmak bilinçli bir tercih: yarıda kesilen bir dağıtım, tamamlanmamış bir sürüm bırakabilir.

6. Artefaktları sınırlayın

Büyük artefakt yüklemeleri hem süreyi hem depolama maliyetini artırır:

- uses: actions/upload-artifact@v4
  if: always()
  with:
    name: test-results
    path: coverage/
    retention-days: 7

retention-days, artefaktların süresiz birikmesini engeller.

Uygulama sırası

Yavaş ve faturası büyüyen bir hatta bu teknikleri şu sırayla uygulayın ve her adımdan sonra derleme süresini ve aylık dakikayı ölçün:

  1. Bağımlılık önbelleği: çoğu zaman tek başına en büyük kazanç
  2. Paralel işler: sürümler ve test parçaları arasında
  3. Yol filtreleri ve koşullu dağıtım: değişmeyen parçaları çalıştırmamak
  4. Docker katman önbelleği: konteyner derlemeleri için
  5. Eşzamanlılık ve zaman aşımı: boşa çalışan işleri kesmek

Özet

  1. Önbelleğe alın: bağımlılık ve katmanlar
  2. Paralel çalıştırın: bağımsız işleri aynı anda
  3. Erken düşün: hızlı kontrolleri (lint, tip denetimi) başa alın
  4. Gerekmeyeni çalıştırmayın: yol filtreleri ve koşullar
  5. Maliyeti izleyin: Actions kullanım raporu bunu kolaylaştırır
  6. Eylemleri güncel tutun: eski sürümler bir gün çalışmayı bırakır; Dependabot github-actions güncellemelerini açın
  7. Kararları yazın: sıra dışı bir iş akışı tercihinin gerekçesi dosyada yorum olarak dursun

İlk adım için en yavaş iş akışınızı seçin, darboğazını bulun, tek bir teknik uygulayın ve ölçün. Hangi değişikliğin işe yaradığını ancak ölçerek bilirsiniz.

Hattınızı birlikte gözden geçirmek isterseniz bize yazın.

B

ByteGurus

Yazar

Tüm yazılara dön
Başlamaya hazır mısınız?

Projenize başlamaya hazır mısınız?

Fikirlerinizi hayata geçirmek için size nasıl yardımcı olabileceğimizi konuşalım.