İ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:
- Bağımlılık önbelleği: çoğu zaman tek başına en büyük kazanç
- Paralel işler: sürümler ve test parçaları arasında
- Yol filtreleri ve koşullu dağıtım: değişmeyen parçaları çalıştırmamak
- Docker katman önbelleği: konteyner derlemeleri için
- Eşzamanlılık ve zaman aşımı: boşa çalışan işleri kesmek
Özet
- Önbelleğe alın: bağımlılık ve katmanlar
- Paralel çalıştırın: bağımsız işleri aynı anda
- Erken düşün: hızlı kontrolleri (lint, tip denetimi) başa alın
- Gerekmeyeni çalıştırmayın: yol filtreleri ve koşullar
- Maliyeti izleyin: Actions kullanım raporu bunu kolaylaştırır
- Eylemleri güncel tutun: eski sürümler bir gün çalışmayı bırakır; Dependabot
github-actionsgüncellemelerini açın - 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.
ByteGurus
Yazar