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
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()
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 }}-
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
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.