İçeriğe geç
DevOps

GitHub Actions ile CI/CD Pipeline Oluşturma

Tarık Tunç
GitHub Actions ile CI/CD Pipeline Oluşturma

GitHub Actions ile CI/CD Pipeline Oluşturma

Sürekli entegrasyon (CI) ve sürekli dağıtım (CD), modern yazılım geliştirme süreçlerinin temel taşlarıdır. GitHub Actions, GitHub repository'lerinize doğrudan entegre edilmiş güçlü bir otomasyon platformudur. Kod push ettiğinizde testlerin çalışması, build'in oluşturulması ve uygulamanızın otomatik deploy edilmesi gibi işlemleri workflow dosyaları ile tanımlayabilirsiniz. Bu rehberde GitHub Actions'ın temellerinden production-ready pipeline oluşturmaya kadar her şeyi adım adım inceleyeceğiz.

GitHub Actions Temel Kavramları

GitHub Actions ekosistemini anlamak için birkaç temel kavramı bilmeniz gerekir:

  • Workflow: Otomatik çalışan süreçlerin tanımlandığı YAML dosyası (.github/workflows/ altında)
  • Event (Trigger): Workflow'u tetikleyen olay (push, pull_request, schedule vb.)
  • Job: Workflow içindeki bağımsız çalışma birimleri
  • Step: Job içindeki her bir adım
  • Action: Yeniden kullanılabilir, paylaşılabilir görev birimleri
  • Runner: Workflow'ların çalıştığı sanal makine

İlk Workflow Dosyanızı Oluşturma

Basit bir CI pipeline'ı ile başlayalım. Repository'nizde .github/workflows/ci.yml dosyası oluşturun:

# .github/workflows/ci.yml
name: CI Pipeline

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

jobs:
  test:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [18, 20, 22]

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run linter
        run: npm run lint

      - name: Run tests
        run: npm test

      - name: Build project
        run: npm run build
Bilgi: npm ci komutu, npm install'a göre CI ortamlarında daha güvenilirdir. package-lock.json dosyasını birebir takip eder ve node_modules klasörünü sıfırdan oluşturur.

Environment Secrets ve Variables

API anahtarları, veritabanı bağlantı bilgileri gibi hassas verileri GitHub Secrets ile güvenli şekilde saklayabilirsiniz:

# Secrets kullanımı
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to production
        env:
          API_KEY: ${{ secrets.API_KEY }}
          DATABASE_URL: ${{ secrets.DATABASE_URL }}
        run: |
          echo "Deploying with secure credentials..."
          npm run deploy

      - name: Notify Slack
        uses: 8398a7/action-slack@v3
        with:
          status: ${{ job.status }}
          webhook_url: ${{ secrets.SLACK_WEBHOOK }}
        if: always()
Uyarı: Secret'ları asla workflow log'larında yazdırmayın. GitHub otomatik olarak secret değerlerini maskeler, ancak base64 encode veya parçalı yazdırma gibi dolaylı yollarla sızabilirler. Secret'ları her zaman environment variable olarak kullanın.

Production-Ready CI/CD Pipeline

Gerçek bir projede kullanabileceğiniz kapsamlı bir pipeline oluşturalım:

# .github/workflows/production.yml
name: Production Pipeline

on:
  push:
    branches: [main]

permissions:
  contents: read
  deployments: write

jobs:
  quality:
    name: Code Quality
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - run: npm ci
      - run: npm run lint
      - run: npm run type-check
      - run: npm run test:coverage

      - name: Upload coverage
        uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}

  build:
    name: Build
    needs: quality
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - run: npm ci
      - run: npm run build

      - name: Upload build artifact
        uses: actions/upload-artifact@v4
        with:
          name: build-output
          path: .next/
          retention-days: 1

  deploy:
    name: Deploy to Production
    needs: build
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4

      - name: Download build artifact
        uses: actions/download-artifact@v4
        with:
          name: build-output
          path: .next/

      - name: Deploy to Vercel
        uses: amondnet/vercel-action@v25
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
          vercel-args: '--prod'

Caching ile Pipeline Hızlandırma

CI pipeline'larında en çok zaman alan adım genellikle bağımlılıkların yüklenmesidir. Caching stratejileri ile bu süreyi dramatik şekilde azaltabilirsiniz:

steps:
  - uses: actions/checkout@v4

  - uses: actions/setup-node@v4
    with:
      node-version: 20
      cache: 'npm'

  # Cypress binary cache
  - name: Cache Cypress binary
    uses: actions/cache@v4
    with:
      path: ~/.cache/Cypress
      key: cypress-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
      restore-keys: |
        cypress-${{ runner.os }}-

  # Next.js build cache
  - name: Cache Next.js build
    uses: actions/cache@v4
    with:
      path: .next/cache
      key: nextjs-${{ runner.os }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
      restore-keys: |
        nextjs-${{ runner.os }}-
İpucu: actions/setup-node@v4 action'ının cache parametresi, npm/yarn/pnpm cache'ini otomatik olarak yönetir. Ek bir cache adımı eklemenize gerek kalmaz. Ancak Cypress gibi büyük binary'ler için ayrı cache tanımlamak faydalıdır.

Reusable Workflows ve Composite Actions

Tekrar eden workflow adımlarını yeniden kullanılabilir hale getirmek için composite action veya reusable workflow tanımlayabilirsiniz:

# .github/workflows/reusable-test.yml
name: Reusable Test Workflow

on:
  workflow_call:
    inputs:
      node-version:
        required: false
        type: string
        default: '20'

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node-version }}
          cache: 'npm'
      - run: npm ci
      - run: npm test

# Ana workflow'da kullanımı:
# .github/workflows/main.yml
# jobs:
#   call-tests:
#     uses: ./.github/workflows/reusable-test.yml
#     with:
#       node-version: '20'

Conditional Jobs ve Matrix Strategy

Farklı koşullara göre farklı job'lar çalıştırabilir veya matrix strategy ile paralel test süreçleri oluşturabilirsiniz:

jobs:
  detect-changes:
    runs-on: ubuntu-latest
    outputs:
      frontend: ${{ steps.filter.outputs.frontend }}
      backend: ${{ steps.filter.outputs.backend }}
    steps:
      - uses: actions/checkout@v4
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            frontend:
              - 'src/frontend/**'
            backend:
              - 'src/backend/**'

  test-frontend:
    needs: detect-changes
    if: needs.detect-changes.outputs.frontend == 'true'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run test:frontend

  test-backend:
    needs: detect-changes
    if: needs.detect-changes.outputs.backend == 'true'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run test:backend
Bilgi: dorny/paths-filter action'ı ile değişen dosyalara göre sadece ilgili job'ları çalıştırabilirsiniz. Bu, monorepo projelerinde CI süresini önemli ölçüde kısaltır.

Scheduled Workflows ve Cron Jobs

Belirli zamanlarda otomatik çalışan workflow'lar tanımlayabilirsiniz:

on:
  schedule:
    # Her gün gece 02:00'de (UTC) dependency audit çalıştır
    - cron: '0 2 * * *'

jobs:
  security-audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm audit --audit-level=high
      - name: Check for outdated packages
        run: npm outdated || true

Sonuç

GitHub Actions, CI/CD pipeline'larınızı doğrudan repository'niz içinde tanımlamanızı ve yönetmenizi sağlayan güçlü bir platformdur. YAML tabanlı konfigürasyonu, zengin marketplace action'ları ve GitHub ile doğal entegrasyonu sayesinde hızlıca production-ready pipeline'lar oluşturabilirsiniz. Küçük başlayın, temel CI ile test ve lint adımlarını otomatikleştirin, ardından CD, caching ve conditional job'lar ekleyerek pipeline'ınızı olgunlaştırın.

Kaynaklar

İlgili Yazılar