Workflow Yazma
Giriş — Workflow'un Gücünü Keşfet
İlk workflow'unu yazdın: push gelince lint, test, build çalışıyor. Güzel. Ama gerçek dünya daha karmaşık. "PR açıldığında farklı şeyler çalışsın", "her gece otomatik güvenlik taraması yapsın", "API key'i güvenli şekilde pipeline'a vereyim", "hem Node 18 hem Node 20'de test edeyim", "npm install her seferinde 2 dakika sürmesin" — bu ihtiyaçların her biri GitHub Actions'ın ileri özelliklerine çıkarıyor.
Bu derste workflow'ların gerçek potansiyelini açığa çıkaracağız: tetikleyicileri (triggers) derinlemesine öğrenecek, ortam değişkenleri ve secret'larla çalışacak, matrix strategy ile paralel test matrisleri kuracak ve caching ile pipeline süresini dramatik şekilde düşüreceksin.
🎬 Analoji: Akıllı Ev Otomasyonu
Workflow tetikleyicilerini bir akıllı ev sistemine benzetelim:
Push tetikleyici = Kapıdan girince ışıklar yansın
PR tetikleyici = Zil çalınca kamera açılsın
Schedule tetikleyici = Her gece 23:00'te kapılar kilitlensin
Manual tetikleyici = Telefondaki butona basınca müzik çalsın
Webhook tetikleyici = Hava 0°C'nin altına düşünce ısıtma açılsın
Her tetikleyici farklı bir olaya tepki verir. Doğru tetikleyiciyi seçmek, workflow'unun ne zaman ve neden çalışacağını belirler.
┌──────────────────────────────────────────────────────────────┐
│ WORKFLOW TETİKLEYİCİLERİ │
│ │
│ 🔔 push → Kod push edildiğinde │
│ 🔔 pull_request → PR açıldığında/güncellendiğinde │
│ ⏰ schedule → Belirli zamanlarda (cron) │
│ 🖱️ workflow_dispatch → Manuel tetikleme (UI'dan) │
│ 🔗 repository_dispatch → Dış API'den tetikleme │
│ 🏷️ release → Release yayınlandığında │
│ 📋 issues → Issue açıldığında │
│ 🔄 workflow_run → Başka workflow bittiğinde │
└──────────────────────────────────────────────────────────────┘Tetikleyiciler (Triggers) Derinlemesine
push — Kod Push Edildiğinde
# Temel kullanım: Her push'ta
on: push
# Branch filtresi:
on:
push:
branches:
- main
- develop
- 'release/**' # release/1.0, release/2.0, ...
- '!release/beta-*' # release/beta-* hariç
# Tag filtresi:
on:
push:
tags:
- 'v*' # v1.0, v2.3.1, ...
# Path filtresi — sadece belirli dosyalar değiştiğinde:
on:
push:
paths:
- 'src/**' # src/ altı değiştiğinde
- 'package.json' # package.json değiştiğinde
paths-ignore:
- '**.md' # Markdown değişiklikleri atla
- 'docs/**' # docs/ değişiklikleri atla💡 İpucu:
pathsvepaths-ignorebirlikte kullanılmaz. Birisini seç. Genel kural: Az sayıda dosyayı dahil etmek istiyorsanpaths, az sayıda dosyayı hariç tutmak istiyorsanpaths-ignorekullan.
pull_request — PR Olayları
on:
pull_request:
branches: [main]
types:
- opened # PR yeni açıldı
- synchronize # PR'a yeni commit push edildi
- reopened # Kapatılıp tekrar açıldı
# Varsayılan: [opened, synchronize, reopened]
paths:
- 'src/**' # Sadece src/ değiştiğinde çalış# PR ve push'u birlikte kullanmak (en yaygın pattern):
on:
push:
branches: [main] # main'e merge olunca
pull_request:
branches: [main] # main'e PR açılıncapush vs pull_request farkı:
push:
→ Branch'e doğrudan push yapıldığında
→ Merge commit push edildiğinde
→ Workflow, push yapan kişinin izinleriyle çalışır
pull_request:
→ PR açıldığında veya güncellendiğinde
→ Fork'lardan gelen PR'larda GÜVENLİ: secret'lara erişim yok
→ Workflow, PR'ın merge preview'ında çalışır⚠️ Dikkat: Fork'lardan gelen
pull_requestevent'lerindesecretserişimi kapalıdır. Bu bir güvenlik önlemidir — rastgele birinin fork'undan gelen workflow kodun secret'larını çalabilir.pull_request_targetbunu açar ama çok dikkatli kullanılmalı.
schedule — Zamanlanmış Çalıştırma
Cron sözdizimi ile belirli zamanlarda otomatik çalıştırma:
on:
schedule:
# ┌───────────── dakika (0-59)
# │ ┌───────────── saat (0-23)
# │ │ ┌───────────── ayın günü (1-31)
# │ │ │ ┌───────────── ay (1-12)
# │ │ │ │ ┌───────────── haftanın günü (0-6, Pazar=0)
# │ │ │ │ │
# * * * * *
- cron: '0 2 * * *' # Her gün saat 02:00 UTC
- cron: '30 9 * * 1-5' # Hafta içi her gün 09:30 UTC
- cron: '0 0 1 * *' # Her ayın 1'i gece yarısı
- cron: '0 */6 * * *' # Her 6 saatte birYaygın Cron Örnekleri:
┌─────────────────────┬────────────────────────────────┐
│ Cron │ Açıklama │
├─────────────────────┼────────────────────────────────┤
│ '0 0 * * *' │ Her gün gece yarısı │
│ '0 2 * * 1' │ Her Pazartesi saat 02:00 │
│ '0 */4 * * *' │ Her 4 saatte bir │
│ '30 8 * * 1-5' │ Hafta içi 08:30 │
│ '0 0 1,15 * *' │ Ayın 1'i ve 15'i │
└─────────────────────┴────────────────────────────────┘# Örnek: Her gece güvenlik taraması
name: Nightly Security Scan
on:
schedule:
- cron: '0 3 * * *' # Her gün 03:00 UTC
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run security audit
run: npm audit --audit-level=high
- name: Check for vulnerabilities
run: npx snyk test⚠️ Dikkat: Schedule trigger'lar sadece varsayılan branch'te (genellikle main) çalışır. Başka bir branch'teki schedule workflow'u çalışmaz. Ayrıca GitHub, yoğun dönemlerde schedule'ları 15-60 dakika geciktirebilir — dakika hassasiyetinde bir zamanlama bekleme.
workflow_dispatch — Manuel Tetikleme
on:
workflow_dispatch:
inputs:
environment:
description: 'Deploy ortamı'
required: true
default: 'staging'
type: choice
options:
- staging
- production
debug:
description: 'Debug modu'
required: false
type: boolean
default: false
version:
description: 'Versiyon (ör: 1.2.3)'
required: false
type: string
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy
run: |
echo "Deploying to: ${{ inputs.environment }}"
echo "Version: ${{ inputs.version }}"
echo "Debug: ${{ inputs.debug }}"GitHub UI'da "Run workflow" butonu:
┌─────────────────────────────────────────────┐
│ Run workflow │
│ │
│ Branch: main ▼ │
│ │
│ Deploy ortamı: [staging ▼] │
│ Debug modu: [ ] ☐ │
│ Versiyon: [1.2.3 ] │
│ │
│ [Run workflow] │
└─────────────────────────────────────────────┘workflow_run — Başka Workflow Tamamlandığında
# CI tamamlandıktan sonra deploy et:
name: Deploy
on:
workflow_run:
workflows: ["CI Pipeline"] # CI workflow'u adı
types: [completed]
branches: [main]
jobs:
deploy:
# Sadece CI başarılıysa deploy et
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run deployOrtam Değişkenleri (Environment Variables)
Üç Seviye Ortam Değişkeni
# 1. Workflow seviyesi — tüm job'larda geçerli:
env:
NODE_ENV: production
APP_NAME: my-app
jobs:
build:
runs-on: ubuntu-latest
# 2. Job seviyesi — sadece bu job'da geçerli:
env:
DATABASE_URL: localhost:5432
steps:
- name: Test
# 3. Step seviyesi — sadece bu step'te geçerli:
env:
TEST_MODE: true
run: |
echo $NODE_ENV # production (workflow seviyesi)
echo $DATABASE_URL # localhost:5432 (job seviyesi)
echo $TEST_MODE # true (step seviyesi)Ortam Değişkeni Öncelik Sırası (dar kapsam kazanır):
Step env > Job env > Workflow env
Aynı isimde değişken varsa, en dar kapsamdaki geçerli olur.Varsayılan Ortam Değişkenleri
GitHub, her workflow'da otomatik olarak bazı değişkenleri tanımlar:
steps:
- name: Show default env vars
run: |
echo "CI: $CI" # true (her zaman)
echo "HOME: $HOME" # /home/runner
echo "GITHUB_REPOSITORY: $GITHUB_REPOSITORY" # user/repo
echo "GITHUB_REF: $GITHUB_REF" # refs/heads/main
echo "GITHUB_SHA: $GITHUB_SHA" # abc123...
echo "GITHUB_ACTOR: $GITHUB_ACTOR" # push yapan kişi
echo "GITHUB_WORKSPACE: $GITHUB_WORKSPACE" # checkout dizini
echo "RUNNER_OS: $RUNNER_OS" # LinuxStep Çıktıları (Outputs)
Bir step'in çıktısını başka bir step'te kullanmak:
steps:
- name: Get version
id: version # Bu step'e ID ver
run: |
VERSION=$(node -p "require('./package.json').version")
echo "app_version=$VERSION" >> $GITHUB_OUTPUT
- name: Use version
run: echo "Version is ${{ steps.version.outputs.app_version }}"Job Çıktıları
Bir job'un çıktısını başka bir job'da kullanmak:
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.ver.outputs.version }}
steps:
- id: ver
run: echo "version=1.2.3" >> $GITHUB_OUTPUT
deploy:
needs: prepare
runs-on: ubuntu-latest
steps:
- run: echo "Deploying v${{ needs.prepare.outputs.version }}"Secrets — Hassas Bilgileri Güvenle Yönet
API key'leri, token'ları, şifreleri workflow dosyasına yazmak felaket olur. Secret'lar bunun için var.
Secret Oluşturma
GitHub'da Secret Ekleme:
Repo bazlı:
Repository → Settings → Secrets and variables → Actions
→ "New repository secret"
→ Name: DEPLOY_TOKEN
→ Secret: ghp_xxxxxxxxxxxx
→ Add secret
Organization bazlı:
Organization → Settings → Secrets and variables → Actions
→ Tüm repo'larda veya seçili repo'larda kullanılabilir
Environment bazlı:
Repository → Settings → Environments → "production"
→ Environment secrets → Add secretSecret Kullanma
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy
env:
API_KEY: ${{ secrets.API_KEY }}
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
run: |
echo "Deploying with token..."
# Secret değerleri loglarda otomatik MASKELENİR:
# echo $API_KEY → ***
curl -H "Authorization: Bearer $DEPLOY_TOKEN" \
https://api.deploy.com/triggerSecret Güvenlik Kuralları
🔒 SECRET GÜVENLİK:
────────────────────
1. Secret'lar loglarda otomatik maskelenir (*** gösterilir)
2. Fork'lardan gelen PR'larda secret'lara ERİŞİM YOK
3. Secret isimleri GITHUB_ ile başlayamaz (reserved)
4. Secret'ı echo ile yazdırmaya çalışma (maskelense bile)
5. Secret'ı URL'e veya dosyaya yazma — log'a sızabilir
# ❌ YAPMA:
- run: echo ${{ secrets.TOKEN }} # Maskelenir ama riskli
- run: curl "https://api.com?key=$KEY" # URL log'a yazılabilir
# ✅ YAP:
- run: curl -H "Authorization: Bearer $KEY" https://api.com
env:
KEY: ${{ secrets.API_KEY }}GITHUB_TOKEN — Otomatik Token
GitHub, her workflow'da otomatik olarak GITHUB_TOKEN secret'ı sağlar. Ayrıca oluşturmana gerek yok:
steps:
- name: Comment on PR
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '✅ CI passed!'
})
- name: Create release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh release create v1.0.0 --generate-notesGITHUB_TOKEN İzinleri:
┌─────────────────┬────────────────────┐
│ İzin │ Varsayılan │
├─────────────────┼────────────────────┤
│ contents │ read (push: write) │
│ issues │ write │
│ pull-requests │ write │
│ packages │ read │
│ actions │ read │
│ metadata │ read │
└─────────────────┴────────────────────┘# İzinleri daraltmak (en iyi pratik):
permissions:
contents: read
pull-requests: write
jobs:
...💡 İpucu: Workflow'un başında
permissions:ile minimum gerekli izinleri belirt. Bu, supply chain saldırılarına karşı koruma sağlar. GITHUB_TOKEN'ın gereksiz yere geniş izinleri olmasını önlersin.
Variables — Secret Olmayan Yapılandırma
Secret olmayan ama workflow'da kullanmak istediğin değerler için Variables kullan:
GitHub'da Variable Ekleme:
Repository → Settings → Secrets and variables → Actions
→ Variables tab → "New repository variable"
→ Name: DEPLOY_ENVIRONMENT
→ Value: stagingsteps:
- name: Show variables
run: |
echo "Environment: ${{ vars.DEPLOY_ENVIRONMENT }}"
echo "Region: ${{ vars.AWS_REGION }}"Secret vs Variable:
┌────────────────┬────────────────────────┬───────────────────┐
│ │ Secret │ Variable │
├────────────────┼────────────────────────┼───────────────────┤
│ Değer │ Şifreli, maskelenir │ Açık metin │
│ Loglarda │ *** (gizli) │ Görünür │
│ Kullanım │ Token, API key, şifre │ URL, isim, flag │
│ Erişim │ ${{ secrets.NAME }} │ ${{ vars.NAME }} │
└────────────────┴────────────────────────┴───────────────────┘Matrix Strategy — Paralel Test Matrisi
Projenin farklı ortamlarda çalıştığını doğrulamak istiyorsun: farklı Node.js versiyonları, farklı işletim sistemleri, farklı veritabanları. Her kombinasyon için ayrı job yazmak yerine matrix strategy kullan.
Temel Matrix
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 20, 22]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm testBu 3 paralel job oluşturur:
Job 1: node-version = 18
Job 2: node-version = 20
Job 3: node-version = 22Çoklu Boyut Matrix
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node-version: [18, 20, 22]
# 2 × 3 = 6 paralel job!
runs-on: ${{ matrix.os }}
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}Sonuç: 6 job paralel çalışır
┌─────────────────┬─────────┬─────────┬─────────┐
│ │ Node 18 │ Node 20 │ Node 22 │
├─────────────────┼─────────┼─────────┼─────────┤
│ Ubuntu │ ✅ │ ✅ │ ✅ │
│ Windows │ ✅ │ ✅ │ ✅ │
└─────────────────┴─────────┴─────────┴─────────┘include ve exclude
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node-version: [18, 20]
# Belirli kombinasyonları EKLE:
include:
- os: ubuntu-latest
node-version: 22
experimental: true # Ekstra değişken
# Belirli kombinasyonları ÇIKAR:
exclude:
- os: windows-latest
node-version: 18 # Windows + Node 18 atlafail-fast
strategy:
fail-fast: true # Varsayılan: true
# Bir job başarısız olursa, diğerlerini de DURDUR
fail-fast: false # Bir job başarısız olsa bile diğerleri devam etsin
matrix:
node-version: [18, 20, 22]fail-fast: true (varsayılan)
Node 18: ✅ geçti
Node 20: ❌ başarısız → diğerleri de İPTAL
Node 22: ⏹️ iptal edildi
fail-fast: false
Node 18: ✅ geçti
Node 20: ❌ başarısız → diğerleri DEVAM
Node 22: ✅ geçti
→ Sonuç: 1/3 başarısız💡 İpucu: CI'da
fail-fast: falsekullanmak genelde daha iyi. Çünkü hangi ortamlarda hata olduğunu tam olarak görmek istersin.fail-fast: truezaman kazandırır ama bilgi kaybına yol açar.
max-parallel
strategy:
max-parallel: 2 # Aynı anda en fazla 2 job çalışsın
matrix:
node-version: [18, 20, 22]
# 3 job var ama aynı anda sadece 2 çalışırCaching — Pipeline'ı Hızlandır
Her workflow çalışmasında temiz bir runner başlar. Yani npm install her seferinde tüm paketleri sıfırdan indirir. Bu çok yavaş. Cache ile önceki çalışmadaki paketleri yeniden kullanabilirsin.
Cache Olmadan vs Cache ile
Cache OLMADAN:
npm ci → 120 saniye (her seferinde 200MB indirme)
Cache İLE:
İlk çalışma: npm ci → 120 saniye (+ cache kaydet)
Sonraki çalışmalar: npm ci → 15 saniye (cache'den yükle) ⚡actions/setup-node ile Otomatik Cache
En kolay yol — setup-node action'ı cache'i otomatik yönetir:
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm' # npm cache'ini otomatik yönet
# cache: 'yarn' # Yarn kullanıyorsan
# cache: 'pnpm' # pnpm kullanıyorsanBu tek satır, ~/.npm dizinini package-lock.json hash'ine göre cache'ler.
Manuel Cache (actions/cache)
Daha fazla kontrol istersen:
- name: Cache node modules
uses: actions/cache@v4
id: npm-cache
with:
path: node_modules # Cache'lenecek dizin
key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install dependencies
if: steps.npm-cache.outputs.cache-hit != 'true' # Cache yoksa yükle
run: npm ciCache Anahtarı Nasıl Çalışır?
Cache Key: linux-node-abc123 (package-lock.json hash'i)
1. Çalışma başladı
2. Cache key "linux-node-abc123" ara
├── Bulundu (cache hit) → Cache'den yükle (hızlı!)
└── Bulunamadı (cache miss)
├── restore-keys ile "linux-node-" prefixi dene
│ ├── Bulundu → Eski cache yükle + yeni paketleri ekle
│ └── Bulunamadı → Sıfırdan yükle
└── Çalışma sonunda yeni cache kaydetFarklı Diller İçin Cache
# Python:
- uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
# Ruby:
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
bundler-cache: true
# Java/Gradle:
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '21'
cache: 'gradle'
# Go:
- uses: actions/setup-go@v5
with:
go-version: '1.22'
cache: trueCache Limitleri
GitHub Cache Limitleri:
─────────────────────────
- Repo başına toplam: 10 GB
- Tek cache girişi: max 10 GB
- 7 gün erişilmeyen cache otomatik silinir
- Branch bazlı: her branch kendi cache'ini kullanır
(ama varsayılan branch'in cache'ine erişebilir)Concurrency — Çakışan Workflow'ları Yönet
Aynı branch'e hızla birden fazla push yapılırsa, birden fazla workflow aynı anda çalışır. Bu gereksiz kaynak israfıdır.
# Aynı grupta çalışan eski workflow'u iptal et:
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
# Örnek: main branch'e 3 push yaptın
# Push 1 → workflow başladı
# Push 2 → Push 1'in workflow'u İPTAL, yeni workflow başladı
# Push 3 → Push 2'nin workflow'u İPTAL, yeni workflow başladı
# Sonuç: Sadece Push 3'ün workflow'u çalışır# Deploy'da iptal etmek istemezsin — sıralı çalıştır:
concurrency:
group: deploy-production
cancel-in-progress: false # Bekle, sırayla çalıştırGerçek Dünya Workflow'u: Tam Örnek
# .github/workflows/ci.yml
name: CI Pipeline
on:
push:
branches: [main, develop]
paths-ignore:
- '**.md'
- 'docs/**'
- '.github/ISSUE_TEMPLATE/**'
pull_request:
branches: [main]
schedule:
- cron: '0 3 * * 1' # Her Pazartesi 03:00 — haftalık güvenlik taraması
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
env:
NODE_VERSION: '20'
CI: true
permissions:
contents: read
pull-requests: write
jobs:
# ──────────────────────────────────
# Job 1: Lint ve Format Kontrolü
# ──────────────────────────────────
lint:
name: 🔍 Lint & Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- run: npm ci
- name: ESLint
run: npm run lint
- name: Prettier
run: npx prettier --check .
# ──────────────────────────────────
# Job 2: Test Matrisi
# ──────────────────────────────────
test:
name: 🧪 Test (Node ${{ matrix.node-version }})
runs-on: ubuntu-latest
needs: lint
strategy:
fail-fast: false
matrix:
node-version: [18, 20, 22]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm test -- --coverage
- name: Upload coverage
if: matrix.node-version == 20
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage/
# ──────────────────────────────────
# Job 3: Build
# ──────────────────────────────────
build:
name: 🏗️ Build
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- run: npm ci
- run: npm run build
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: build-output
path: dist/
retention-days: 7
# ──────────────────────────────────
# Job 4: Güvenlik Taraması (Haftalık)
# ──────────────────────────────────
security:
name: 🔒 Security Audit
runs-on: ubuntu-latest
if: github.event_name == 'schedule' || github.event_name == 'push'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- run: npm audit --audit-level=moderateBu workflow'un akışı:
push/PR:
┌──────┐ ┌────────────────────────┐ ┌───────┐
│ Lint │────►│ Test (Node 18, 20, 22) │────►│ Build │
└──────┘ └────────────────────────┘ └───────┘
1 dk 3 dk (paralel) 1 dk
schedule (Pazartesi):
┌────────────┐
│ Security │
│ Audit │
└────────────┘Reusable Workflows — Tekrar Kullanılabilir Workflow
Birden fazla repo'da aynı CI pipeline'ı kullanıyorsan, kopyala-yapıştır yapmak yerine reusable workflow oluştur:
# .github/workflows/reusable-ci.yml (paylaşılan repo'da)
name: Reusable CI
on:
workflow_call: # Bu workflow başka workflow'lardan çağrılabilir
inputs:
node-version:
required: false
type: string
default: '20'
secrets:
NPM_TOKEN:
required: false
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
- run: npm ci
- run: npm test# Başka bir repo'dan çağır:
name: CI
on: [push, pull_request]
jobs:
ci:
uses: my-org/shared-workflows/.github/workflows/reusable-ci.yml@main
with:
node-version: '20'
secrets:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}Yaygın Hatalar
1. Secret'ı Echo ile Yazdırmak
# ❌ Secret değerini loga yazdırma!
- run: echo "Token: ${{ secrets.API_KEY }}"
# GitHub maskeler ama yine de riskli
# ✅ Secret'ı ortam değişkeni olarak kullan:
- run: curl -H "Auth: $TOKEN" https://api.com
env:
TOKEN: ${{ secrets.API_KEY }}2. Cache Key'inde Hash Kullanmamak
# ❌ Sabit cache key — bağımlılıklar değişince eski cache kullanılır
- uses: actions/cache@v4
with:
key: my-cache
# ✅ Lock file hash'i ile key oluştur:
- uses: actions/cache@v4
with:
key: npm-${{ hashFiles('package-lock.json') }}3. Gereksiz Yere Her Dosya Değişikliğinde Çalıştırmak
# ❌ README değiştirince bile CI çalışır:
on: push
# ✅ Sadece ilgili dosyalar değiştiğinde:
on:
push:
paths-ignore:
- '**.md'
- 'docs/**'
- 'LICENSE'Özet
Tetikleyiciler (triggers) workflow'un ne zaman çalışacağını belirler —
push,pull_request,schedule,workflow_dispatchen yaygın olanlarıdır;pathsvepaths-ignoreile gereksiz çalıştırmaları önleOrtam değişkenleri workflow, job ve step seviyesinde tanımlanır — dar kapsam geniş kapsamı override eder; step çıktıları
$GITHUB_OUTPUTile paylaşılırSecrets hassas bilgileri (token, API key) güvenli saklar — loglarda maskelenir, fork PR'larında erişilemez;
GITHUB_TOKENotomatik olarak sağlanırMatrix strategy farklı ortam kombinasyonlarında paralel test sağlar —
fail-fast: falseile tüm sonuçları gör,include/excludeile matrixi özelleştirCaching pipeline süresini dramatik şekilde düşürür —
setup-nodeile otomatik cache kullan veyaactions/cacheile manuel kontrol sağlaConcurrency ile çakışan workflow'ları yönet —
cancel-in-progress: trueeski çalışmaları iptal ederek kaynak tasarrufu sağlar
*Bir sonraki derste CI pipeline'ını derinleştireceğiz: Lint, test, build, artifact ve branch protection!*
AI Asistan
Sorularını yanıtlamaya hazır