· Admin

Laravel ile CI/CD: GitHub Actions Kullanımı

Manuel deploy "git pull → composer install → migrate" döngüsü küçük projelerde çalışır ama ekip büyüdüğünde, test yazmaya başladığınızda ve deployment hataları arttığında CI/CD kaçınılmaz oluyor. GitHub Actions ücretsiz ve GitHub ile native entegre — Laravel projeleri için ideal.

CI/CD Nedir?

  • CI (Continuous Integration): Her push'ta otomatik test çalıştırma. Kod bozuk mu hemen belli olur.
  • CD (Continuous Deployment): Testler geçtiyse otomatik deploy. Manuel SSH bağlantısına gerek yok.

Temel CI Pipeline

.github/workflows/ci.yml:

name: CI

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

jobs:
  test:
    runs-on: ubuntu-latest

    services:
      mysql:
        image: mysql:8.0
        env:
          MYSQL_ROOT_PASSWORD: root
          MYSQL_DATABASE: testing
        ports:
          - 3306:3306
        options: >-
          --health-cmd="mysqladmin ping"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=3

    steps:
      - uses: actions/checkout@v4

      - name: PHP Kurulumu
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.3'
          extensions: mbstring, xml, bcmath, mysql
          coverage: none

      - name: Composer Cache
        uses: actions/cache@v4
        with:
          path: vendor
          key: composer-${{ hashFiles('composer.lock') }}

      - name: Bağımlılıkları Yükle
        run: composer install --no-dev --no-interaction --prefer-dist

      - name: .env Hazırla
        run: |
          cp .env.example .env
          php artisan key:generate

      - name: Migration
        env:
          DB_CONNECTION: mysql
          DB_HOST: 127.0.0.1
          DB_PORT: 3306
          DB_DATABASE: testing
          DB_USERNAME: root
          DB_PASSWORD: root
        run: php artisan migrate --force

      - name: Testleri Çalıştır
        env:
          DB_CONNECTION: mysql
          DB_HOST: 127.0.0.1
          DB_PORT: 3306
          DB_DATABASE: testing
          DB_USERNAME: root
          DB_PASSWORD: root
        run: php artisan test

Her push ve PR'da otomatik çalışır. Test fail ederse merge engellenebilir.

CD: Otomatik Deploy

Testler başarılıysa sunucuya deploy:

.github/workflows/deploy.yml:

name: Deploy

on:
  push:
    branches: [main]

jobs:
  test:
    # ... yukarıdaki test job'ı

  deploy:
    needs: test
    runs-on: ubuntu-latest
    if: success()

    steps:
      - name: Sunucuya Deploy
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SERVER_IP }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /var/www/app
            php artisan down --retry=60
            git pull origin main
            composer install --no-dev --optimize-autoloader --no-interaction
            php artisan migrate --force
            php artisan config:cache
            php artisan route:cache
            php artisan view:cache
            php artisan queue:restart
            php artisan up

GitHub Secrets Ayarlama

Repository → Settings → Secrets and variables → Actions:

  • SERVER_IP → Sunucu IP adresi
  • SERVER_USER → SSH kullanıcısı
  • SSH_PRIVATE_KEY → Sunucuya erişim için private key

SSH key oluşturma:

ssh-keygen -t ed25519 -C "github-actions"
# Private key → GitHub Secret
# Public key → Sunucuda ~/.ssh/authorized_keys

Linting ve Code Quality

Test öncesi kod kalitesi kontrolü:

      - name: PHP Stan
        run: vendor/bin/phpstan analyse --memory-limit=256M

      - name: Pint (Code Style)
        run: vendor/bin/pint --test

Node.js Build (Frontend)

Frontend asset'leri varsa:

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

      - name: Frontend Build
        run: |
          npm ci
          npm run build

Branch Protection

GitHub'da main branch'i koruma:

  1. Settings → Branches → Branch protection rules
  2. "Require status checks to pass before merging" aktif
  3. CI workflow'unu zorunlu check olarak seç

Artık testler geçmeden main'e merge yapılamaz.

Matrix Testing

Birden fazla PHP versiyonunda test:

strategy:
  matrix:
    php-version: ['8.2', '8.3']

steps:
  - uses: shivammathur/setup-php@v2
    with:
      php-version: ${{ matrix.php-version }}

Cache Stratejisi

Composer ve npm cache ile build süresi %50 kısalır:

      - uses: actions/cache@v4
        with:
          path: vendor
          key: composer-${{ hashFiles('composer.lock') }}

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

Pratik İpuçları

  • --no-dev flag'i: Production'da dev bağımlılıklarını yüklemeyin
  • --force flag'i: Production'da migration confirmation'ı atlar
  • php artisan down: Deploy sırasında bakım modu
  • queue:restart: Worker'ların yeni kodu alması için
  • Rollback planı: Deploy başarısız olursa git revert otomatik olabilir

Sonuç

GitHub Actions ile Laravel projeleriniz için sağlam bir CI/CD pipeline kurmak hem ücretsiz hem de basit. Push yaptığınızda testler otomatik çalışır, başarılıysa sunucuya deploy olur. Manuel deploy hatalarını ortadan kaldırır ve güvenle kod yazmanızı sağlar.