İçeriğe atla

Organizasyon Düzeyinde Yeniden Kullanılabilir GitHub Actions Workflow'ları: Mimari, Güvenlik ve Benimseme

Organizasyon düzeyinde paylaşımlı bir GitHub Actions platformu kurma rehberi: mimari kararlar, güvenlik yönetişimi, benimseme ve en maliyetli 7 hata.

Ayhan Sipahi Ayhan Sipahi

GitHub Actions ile başlamak aldatıcı derecede basittir. Bir YAML dosyası kopyalarsınız, birkaç adım eklersiniz ve pipeline çalışır. Bu basitlik, farklı ekiplerin sahiplendiği düzinelerce repository kendi build, test ve deploy biçimini taşımaya başladığında ölçeklenmez. Sonuç orta ve büyük ölçekli mühendislik organizasyonlarında tanıdıktır: ince farklılıklar içeren yüzlerce workflow dosyası, tutarsız güvenlik uygulamaları, büyük farklılıklar gösteren build süreleri ve platform mühendislerinin platform yeteneği geliştirmek yerine “GitHub Actions’da X’i nasıl yaparım?” sorularını yanıtladığı bir destek kuyruğu.

Bu ölçekte varsayılan seçenek, GitHub Actions’ın üç paylaşım mekanizmasını birlikte kullanan organizasyon düzeyinde paylaşımlı bir platformdur: yapı taşı olarak composite action’lar, altın yol olarak reusable workflow’lar ve yeni repository’leri kurmak için workflow template’leri. Birkaç ekibe dağılmış yaklaşık 20 mikroservis çalıştıran bir e-ticaret organizasyonunda bu ayrım ortalama build süresini yaklaşık 45 dakikadan yaklaşık 12 dakikaya indirdi, CI ile ilgili destek taleplerini %70 azalttı ve altı ay içinde %85 benimseme oranına ulaştı. Yol boyunca en pahalıya mal olan yedi hata, yolunda giden kısımlardan daha fazla ilgiyi hak ediyor.

Paylaşımlı Platform Gereksinimi#

Ölçüm yapmaya başlamadan önce bile belirtiler açıktı:

  • Her yerde tekrar: Ortalama workflow dosyası yaklaşık 500 satır YAML’dı ve bunun kabaca %80’i repository’ler arasında aynıydı. Ekipler birbirinden kopyalıyor ve zaman içinde farklılaşıyordu.
  • Tutarsız güvenlik duruşu: Bazı repo’lar action sürümlerini SHA ile sabitlemiş, diğerleri @latest kullanıyordu. Bazıları AWS için OIDC yapılandırmış, diğerleri hâlâ secret olarak saklanan uzun ömürlü erişim anahtarları kullanıyordu.
  • Yavaş build’ler: Ortalama build süresi yaklaşık 45 dakikaydı. Ekipler zaman içinde cache, paralellik veya runner seçimini dikkate almadan adımlar eklemişti.
  • Destek yükü: Platform ekibi haftada yaklaşık 30 CI ile ilgili talep alıyordu; bunlar çoğunlukla yapılandırma, hata ayıklama ve “benim makinemde çalışıyor” sorunlarıyla ilgiliydi.
  • Onboarding sürtünmesi: Yeni projelerin CI/CD kurulumu günler alıyordu çünkü standart bir şablon yoktu ve kurumsal bilgi Slack konuşmalarında yaşıyordu.

Hedef: ekiplere CI/CD için “altın yol” sağlayan ama gerektiğinde özelleştirme esnekliğini koruyan bir platform.

Note

“Altın yol” (golden path), iyi desteklenen, fikirli bir varsayılan yapıdır. Ekipler sapabilir, ancak desteklenen yol kullanım senaryolarının %80’inden fazlasını minimum yapılandırmayla karşılamalıdır.

Mimari Kararlar ve Ödünleşimler#

Her mimari karar bir ödünleşim içerir. Büyük olanları şöyle değerlendirebilirsiniz.

Composite Action’lar vs. Reusable Workflow’lar vs. Workflow Template’leri#

Bu ilk ve en belirleyici karardı. GitHub Actions, CI/CD mantığını paylaşmak için üç mekanizma sunar ve her biri farklı amaçlara hizmet eder:

ÖzellikComposite Action’larReusable Workflow’larWorkflow Template’leri
Soyutlama düzeyiTek adım veya adım grubuTüm job veya workflowYeni repo’lar için başlangıç noktası
Input/OutputTam destekTam destekManuel kopyalama, sonra özelleştirme
Secret erişimiÇağıranın bağlamını devralırAçık secrets: inherit veya adlandırılmışYok (repo’ya kopyalanır)
İç içe kullanımDiğer composite’leri çağırabilirComposite çağırabilir; 10 seviyeye kadar derinlik, toplam 50 çağrıYok
SürümlemeGit tag / SHAGit tag / SHAKopyalama anındaki anlık görüntü
Drift önlemeMerkezi güncellemeMerkezi güncellemeKopyalandıktan sonra yok
Adımlara görünürlükUI’da daraltılmışUI’da ayrı jobTam görünürlük

Her biri farklı bir nedenle yerini alır:

  • Composite action’lar yeniden kullanılabilir yapı taşları için (Node.js kurulumu ve cache, linting çalıştırma, Docker image’ları oluşturma)
  • Reusable workflow’lar standartlaştırılmış pipeline’lar için (bir Node.js servisi için build-test-deploy, deploy-to-ECS)
  • Workflow template’leri yeni repository’leri mantıklı bir başlangıç yapılandırmasıyla oluşturmak için

Reusable workflow’lar composite action’lardan kurulur: workflow ince bir orkestrasyon katmanı olarak kalır, implementasyonu action’lar taşır.

Paylaşımlı Action’lar için Monorepo vs. Multi-Repo#

BoyutMonorepoMulti-Repo
KeşfedilebilirlikTüm action’lar tek yerdeRepository’lere dağılmış
Çapraz değişikliklerTek PR her şeyi güncellerBirden fazla repo’da birden fazla PR
SürümlemePaylaşımlı release döngüsüBağımsız sürümler
CODEOWNERSTek dosya, yol bazlı kurallarRepo bazlı yapılandırma
Action’lar için CIHer şeyi birlikte test etBağımsız test pipeline’ları
Patlama yarıçapıKötü bir release tüm action’ları etkilerİzole hatalar

Varsayılan olarak monorepo. Keşfedilebilirlik ve çapraz değişiklik avantajları, özellikle katı branch koruması ve otomatik testlerle birleştirildiğinde patlama yarıçapı endişesini aşar. Patlama yarıçapını, bireysel action’ları bağımsız semver tag’leriyle yayınlayarak azaltın.

Repository Yapısı#

shared-actions/
├── actions/
│  ├── setup-node/
│  │  ├── action.yml
│  │  └── README.md
│  ├── docker-build/
│  │  ├── action.yml
│  │  └── README.md
│  ├── deploy-ecs/
│  │  ├── action.yml
│  │  └── README.md
│  └── security-scan/
│  ├── action.yml
│  └── README.md
├── workflows/
│  ├── node-service.yml
│  ├── python-service.yml
│  └── deploy-production.yml
├── tests/
│  ├── setup-node.test.yml
│  └── docker-build.test.yml
├── .github/
│  ├── CODEOWNERS
│  └── workflows/
│  ├── test-actions.yml
│  └── release.yml
└── docs/
    ├── CONTRIBUTING.md
    └── MIGRATION.md

Sürümleme Stratejisi#

Sürümleme, güvenlik ile geliştirici deneyiminin çarpıştığı noktadır. Katmanlı bir yaklaşım burada iyi çalışır:

Most secure Immutable

Balanced Predictable

Most convenient Auto-updates

SHA Pinning abc1234...

Semver Tag v2.1.3

Major Tag v2

@main Living edge

Uygulanması gereken politika:

  • Harici üçüncü parti action’lar: SHA sabitleme zorunludur. İstisna yoktur. Dependabot güncelleme PR’larını yönetir.
  • Dahili paylaşımlı action’lar: Production için semver tag’leri, geliştirme ortamları için major tag’ler.
  • Asla @main kullanılmaz: Dahili action’lar için bile, production workflow’larında doğrudan bir branch’e referans verilmesi yasaktır.

Warning

Üçüncü parti action’lar için @main veya @latest kullanmak bir tedarik zinciri saldırı vektörüdür. Ele geçirilmiş bir upstream repository, onu referans alan her workflow’a kötü amaçlı kod enjekte edebilir. Harici action’lar için her zaman SHA ile sabitleyin.

Self-Hosted vs. GitHub-Hosted Runner’lar#

BoyutGitHub-HostedSelf-Hosted
BakımSıfırYama, ölçekleme, izleme
Ölçekte maliyetDakika başı faturalandırma artarSabit altyapı maliyeti, yüksek hacimde daha iyi
GüvenlikGeçici, temiz ortamTemizliği yönetmezseniz kalıcı
Ağ erişimiYalnızca genel internetVPC erişimi, özel registry’ler
ÖzelleştirmeMevcut image’larla sınırlıAraçlar üzerinde tam kontrol
Başlangıç süresi~20-40sn (sıcak)~5-10sn (önceden ısıtılmış)
GPU/ÖzelleştirilmişSınırlı seçeneklerTam kontrol

Hibrit bir yapı kurun. Çoğu iş yükü için GitHub-hosted büyük runner’lar; özel ağ erişimi gerektiren işler (staging veritabanlarına karşı entegrasyon testleri, özel ECS cluster’larına deployment) için VPC içindeki self-hosted runner’lar. Eski ortam sorununu önlemek için ECS Fargate üzerinde geçici (ephemeral) self-hosted runner’lar kullanılır.

İmplementasyon Detayları#

Composite Action Örneği: Cache ile Node.js Kurulumu#

Bu action, repository’ler arasında tekrarlayan yaklaşık 30 satır YAML’ı tek bir adımla değiştirir:

# actions/setup-node/action.yml
name: "Setup Node.js with Caching"
description: "Sets up Node.js, restores npm cache, and installs dependencies"
inputs:
  node-version:
    description: "Node.js version to use"
    required: false
    default: "20"
  working-directory:
    description: "Directory containing package.json"
    required: false
    default: "."

runs:
  using: "composite"
  steps:
    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: ${{ inputs.node-version }}

    - name: Cache npm dependencies
      uses: actions/cache@v4
      id: npm-cache
      with:
        path: ~/.npm
        key: npm-${{ runner.os }}-${{ hashFiles(format('{0}/package-lock.json', inputs.working-directory)) }}
        restore-keys: |
          npm-${{ runner.os }}-

    - name: Install dependencies
      shell: bash
      working-directory: ${{ inputs.working-directory }}
      run: npm ci

Reusable Workflow: Node.js Servis Pipeline’ı#

Bu, Node.js servisleri için “altın yol” workflow’udur. Birden fazla paylaşımlı action’ı compose eder ve repo başına pipeline YAML’ını yaklaşık 500 satırdan yaklaşık 50 satıra düşürür:

# workflows/node-service.yml
name: Node.js Service Pipeline

on:
  workflow_call:
    inputs:
      node-version:
        type: string
        default: "20"
      deploy-environment:
        type: string
        required: true
      aws-region:
        type: string
        default: "eu-central-1"
      run-e2e:
        type: boolean
        default: false
    secrets:
      AWS_ROLE_ARN:
        required: true

permissions:
  id-token: write
  contents: read

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: our-org/shared-actions/actions/setup-node@v2
        with:
          node-version: ${{ inputs.node-version }}

      - name: Lint
        run: npm run lint

      - name: Unit tests
        run: npm run test:unit -- --coverage

      - name: Build
        run: npm run build

      - uses: our-org/shared-actions/actions/security-scan@v2

  deploy:
    needs: build-and-test
    runs-on: ubuntu-latest
    environment: ${{ inputs.deploy-environment }}
    steps:
      - uses: actions/checkout@v4

      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: ${{ inputs.aws-region }}

      - uses: our-org/shared-actions/actions/deploy-ecs@v2
        with:
          environment: ${{ inputs.deploy-environment }}

Consumer Repository’de Kalan Yapılandırma#

Bu, tipik bir Node.js servisi için tüm CI/CD yapılandırmasıdır. Başlangıç noktasındaki 500 satırlık dosyalarla karşılaştırın:

# .github/workflows/ci.yml (in consumer repo)
name: CI/CD

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

jobs:
  pipeline:
    uses: our-org/shared-actions/.github/workflows/node-service.yml@v2
    with:
      node-version: "20"
      deploy-environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}
      run-e2e: ${{ github.ref == 'refs/heads/main' }}
    secrets:
      AWS_ROLE_ARN: ${{ secrets.AWS_DEPLOY_ROLE_ARN }}

Bu yaklaşık 20 satır YAML’dır. Ekip, build cache’i, güvenlik taraması, OIDC tabanlı AWS kimlik doğrulaması ve standartlaştırılmış deploy sürecini hiçbirini yapılandırmadan elde eder.

Otomatik Release Pipeline’ı#

Paylaşımlı actions monorepo’sunda, değişiklikler main’e merge edildiğinde bireysel action’lar için semver tag’leri oluşturan bir release workflow’u bulunur:

# .github/workflows/release.yml
name: Release Actions

on:
  push:
    branches: [main]
    paths:
      - "actions/**"
      - "workflows/**"

jobs:
  detect-changes:
    runs-on: ubuntu-latest
    outputs:
      changed-actions: ${{ steps.changes.outputs.actions }}
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - id: changes
        run: |
          changed=$(git diff --name-only HEAD~1 HEAD | grep '^actions/' | cut -d'/' -f2 | sort -u | jq -R . | jq -s .)
          echo "actions=$changed" >> "$GITHUB_OUTPUT"

  release:
    needs: detect-changes
    if: needs.detect-changes.outputs.changed-actions != '[]'
    runs-on: ubuntu-latest
    strategy:
      matrix:
        action: ${{ fromJson(needs.detect-changes.outputs.changed-actions) }}
    steps:
      - uses: actions/checkout@v4

      - name: Determine version bump
        id: version
        run: |
          # Read version from action.yml metadata or use conventional commits
          echo "version=v2.1.3" >> "$GITHUB_OUTPUT"

      - name: Create release tag
        run: |
          git tag "${{ matrix.action }}/${{ steps.version.outputs.version }}"
          git push origin "${{ matrix.action }}/${{ steps.version.outputs.version }}"

Güvenlik ve Yönetişim Katmanı#

Ölçekte güvenlik isteğe bağlı değildir. Bireysel ekiplerin düşünmesine gerek kalmayacak şekilde birden fazla katman aracılığıyla uygulanır.

AWS Kimlik Doğrulamasında OIDC#

GitHub secret’ları olarak saklanan uzun ömürlü AWS kimlik bilgileri bir sorumluluktur. Hepsini belirli repository’lere ve ortamlara kapsamlandırılmış OIDC federasyonuyla değiştirmek bu riski ortadan kaldırır:

# IAM trust policy (Terraform)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
        },
        "StringLike": {
          "token.actions.githubusercontent.com:sub": "repo:our-org/service-*:environment:production"
        }
      }
    }
  ]
}

sub claim koşulu kritik öneme sahiptir. Hangi repository’lerin ve ortamların bu rolü üstlenebileceğini kısıtlar. our-org/random-fork adlı bir repository, workflow yapılandırmasını bir şekilde elde etmiş olsa bile production rollerini üstlenemez.

Tedarik Zinciri Güvenliği#

Çok katmanlı bir tedarik zinciri güvenlik stratejisi şu şekilde görünür:

Enforcement Layer

CODEOWNERS Required reviews

Branch Protection No direct pushes

Repository Rulesets Security scans on all repos

Detection Layer

Dependabot Action update PRs

OpenSSF Scorecard Supply chain health

StepSecurity Harden Runner Runtime monitoring

Prevention Layer

SHA Pinning All external actions

Minimal Permissions permissions: {}

OIDC Authentication No stored credentials

Temel yapılandırmalar:

  • StepSecurity Harden Runner: Workflow yürütmesi sırasında giden ağ çağrılarını izler. Ele geçirilmiş bir action, secret’ları bilinmeyen bir endpoint’e sızdırmaya çalışırsa işaretlenir.
  • Action’lar için Dependabot: Sabitlenmiş action SHA’larının daha yeni sürümleri olduğunda otomatik PR’lar oluşturur; güvenlikten ödün vermeden güncel kalınır.
  • OpenSSF Scorecard: Paylaşımlı actions repo’sundaki güvenlik zayıflıklarını ortaya çıkarmak için haftalık çalışır.

CODEOWNERS ve Branch Koruması#

Paylaşımlı actions repository’sinde katı yönetişim kuralları geçerlidir:

# .github/CODEOWNERS
# Platform team owns everything by default
* @our-org/platform-engineering

# Security team must review security-related actions
actions/security-scan/ @our-org/security-team @our-org/platform-engineering
workflows/deploy-*.yml @our-org/security-team @our-org/platform-engineering

# Individual teams own their contributed actions
actions/mobile-build/ @our-org/mobile-team @our-org/platform-engineering

Branch koruma kuralları:

  • 2 onaylayıcı review gerektirir (en az 1’i platform ekibinden)
  • Durum kontrollerinin başarılı olması gerekir (tüm action testleri geçmeli)
  • İmzalı commit’ler gerektirir
  • main’e force push veya silme yasaktır
  • Yeni push’larda eski review’ları geçersiz kılar

Minimal Token İzinleri#

Her workflow en kısıtlayıcı izinlerle başlar ve yalnızca ihtiyaç duyduğu izinleri açıkça ekler:

# Default: no permissions
permissions: {}

# Then grant only what's needed per job
jobs:
  deploy:
    permissions:
      id-token: write  # For OIDC
      contents: read  # For checkout

Tip

Workflow düzeyinde permissions: {} ayarlayın ve ardından her job’ın sadece ihtiyaç duyduğunu verin. Bu, en az ayrıcalık ilkesini takip eder ve güvenlik duruşunu bir bakışta denetlenebilir kılar.

Benimseme ve Ölçüm Stratejisi#

Platform kurmak kolay kısımdır. Büyük bir mikroservis organizasyonundaki birden fazla ekibin onu kullanmasını sağlamak asıl zorluktur.

Inner Source Katkı Modeli#

Yukarıdan aşağıya bir zorunluluk yerine inner source modeli daha iyi çalışır. Platform ekibi temel action’ları yönetir; ancak herhangi bir mühendis katkıda bulunabilir:

Propose Open RFC issue

Develop Fork & implement

Review Platform team + CODEOWNERS

Release Automated semver tag

Adopt Teams consume new action

Katkı süreci:

  1. RFC issue: Sorunu ve önerilen action’ı tanımlayın. Platform ekibi kapsam, adlandırma ve mevcut örtüşmeler hakkında geri bildirim verir.
  2. İmplementasyon: Katkıda bulunan, action, testler ve dokümantasyonla birlikte bir PR açar.
  3. Review: Platform ekibi tutarlılık, güvenlik ve composability açısından inceler. CODEOWNERS doğru kişilerin review yapmasını sağlar.
  4. Release: Merge edilen PR’lar uygun semver tag’leriyle otomatik release’leri tetikler.
  5. Duyuru: Yeni action’lar mühendislik Slack kanalında bir kullanım örneğiyle duyurulur.

Bu model benimseme için kritik öneme sahiptir. Mobil ekip mobile-build action’ını katkı olarak sunduğunda, diğer ekipler bunu platform ekibinin yazdığı bir action’a kıyasla çok daha kolay benimsedi.

Geçiş Planı#

İşin ağırlığını yapılandırılmış bir geçiş rehberi taşır. Kritik nokta, ekipleri her şeyi bir kerede geçirmeye zorlamamaktır:

  1. Faz 1: Kimlik bilgisi yönetimini OIDC ile değiştirme (güvenlik kazanımı, workflow değişikliği gerektirmez)
  2. Faz 2: setup-node veya setup-python composite action’larını benimseme (kolay değişim, anında cache avantajları)
  3. Faz 3: Standart servis pipeline’ları için reusable workflow’lara geçiş
  4. Faz 4: Güvenlik taraması için repository ruleset’leri benimseme

Her faz bağımsız olarak değerliydi, bu da ekiplerin kademeli olarak geçiş yapabilmesi anlamına geliyordu.

DORA Metrikleri Dashboard’u#

Temel DORA metriklerini ve platforma özgü KPI’ları izlemek etkiyi net biçimde ortaya koyar:

MetrikPlatform ÖncesiPlatform SonrasıDeğişim
Deployment SıklığıEkip başına haftada ~2Ekip başına haftada ~8+%300
Değişiklik İçin Bekleme Süresi~4 gün~1,5 gün-%62
Değişiklik Hata Oranı~%18~%8-%56
Başarısız Dağıtım Kurtarma Süresi~3 saat~45 dakika-%75
Ortalama Build Süresi~45 dakika~12 dakika-%73
Haftalık CI Destek Talepleri~30~9-%70
Repo Başına Pipeline YAML~500 satır~50 satır-%90

Note

Bu iyileştirmeler yalnızca paylaşımlı actions platformundan kaynaklanmadı. Cache, runner optimizasyonu ve paralellik de önemli katkılarda bulundu. Platform, tüm bu optimizasyonları tutarlı bir şekilde benimsemeyi kolaylaştırdı.

Öğrenilen Dersler ve En Büyük 7 Hata#

Bunlar en çok zaman kaybettiren hatalardır. Her biri, sıfırdan başlarken farklı yapılması gereken bir şeydir.

Hata 1: Geri Bildirim Almadan Çok Fazla Şey İnşa Etmek#

Herhangi bir ekip kullanmadan önce kapsamlı bir paylaşımlı action seti oluşturmak için haftalar harcamak yaygın bir tuzaktır: soyutlamalar ekiplerin projelerini gerçekte nasıl yapılandırdığıyla genellikle eşleşmez ve gerçek kullanım yanlış varsayımları ortaya çıkarınca birkaç action’ı yeniden yazmak gerekir. En küçük faydalı action’ı önce teslim etmek bunun çoğunu önler. Sadece setup-node ile başlayın, 5 ekibin kullanmasını sağlayın, sonra genişleyin.

Hata 2: Aşırı Soyut Reusable Workflow’lar#

Input’lar aracılığıyla olası her yapılandırmayı karşılamaya çalışan reusable workflow’lar fazla karmaşık hale gelir. node-service.yml workflow’u 23 input’a ulaşır ve ekipler bunu kendi YAML’larını yazmaktan daha zor bulur.

Daha az input ve daha fikirli varsayılanlar daha iyi sonuç verir: workflow’ları 4-6 input ile sınırlayın. Bir ekip önemli ölçüde farklı davranışa ihtiyaç duyarsa, workflow’u parametrize etmek yerine paylaşımlı action’lardan compose eder.

Hata 3: Workflow Hata Ayıklama Deneyimini Göz Ardı Etmek#

Bir reusable workflow başarısız olduğunda, hata çağıran workflow’un loglarında görünür, ama gerçek adımlar reusable workflow’un tanımındadır; bu, özellikle ara adımlar net görünmediğinde hata ayıklama sırasında ekiplerin kafasını karıştırdı.

Açığı büyük ölçüde kapatan değişiklikler:

  • Composite action’lara açık adım adlarıyla ayrıntılı loglama
  • Daraltılabilir bölümler için ::group:: / ::endgroup:: log komutları
  • Log çıktısına yazılan paylaşımlı action sürümü; böylece hata ayıklama tam olarak hangi sürümün çalıştığını görebilir

Hata 4: Breaking Change Politikası Olmaması#

Cache stratejisini değiştiren bir setup-node v2, standart dışı node_modules konumu olan repository’leri bozabilir ve böyle bir değişiklik 15 repo’da aynı anda hataya yol açar. Belgelenmiş bir breaking change politikasıyla semantik sürümleme bu zararın çoğunu önler: major sürüm artışları bir geçiş rehberi ve iki haftalık bir kullanımdan kaldırma bildirimi gerektirir, ayrıca yeni action sürümlerini örnek consumer repository’lere karşı test eden otomatik bir uyumluluk kontrolü yayınlamadan önce çalışır.

Hata 5: Runner Maliyetlerini Küçümsemek#

Hız için tüm job’ları varsayılan olarak ubuntu-latest-16core runner’lara atamak GitHub Actions faturasının beklenenden çok daha hızlı büyümesine yol açar. Her job büyük runner’lardan fayda görmez; bağımlılık yüklemesi genellikle CPU’ya değil ağa bağlıdır.

Varsayılan olarak standart runner’lar daha iyi sonuç verir; büyük runner’lara yalnızca belgelenmiş bir gerekçeyle job bazında geçilir. Büyük runner’ları önermeden önce yeni action’ları profillemek, build sürelerini gerçekten iyileştirip iyileştirmediklerini gösterir.

Hata 6: Güvenliği Sürtünme Kaynağı Hâline Getirmek#

Kötü ayarlanmış bir güvenlik taraması implementasyonu her pipeline’a 8 dakika ekler ve yanlış pozitiflerle dolu gürültülü raporlar üretir; ekipler güvenlik adımlarını atlamak için if: false koşulları eklemeye başlar ve bu da amacı tamamen boşa çıkarır. Güvenlik taramasının gerçek pipeline’larda tutunabilmesi için hızlı ve düşük gürültülü olması gerekir: artımlı tarama (PR’larda yalnızca değişen dosyalar, main’de tam tarama), sürekli yanlış pozitif üreten kural setlerinin ayarlanması ve tarama süresinin 90 saniyenin altına indirilmesi. Bir darboğaz olmaktan çıktığında benimseme yaklaşık %40’tan %95’e çıktı.

Hata 7: Eski Kalıplar için Kullanımdan Kaldırma Yolu Olmaması#

Paylaşımlı platform yayınlandığında kullanımdan kaldırma planı olmadan, repository’ler aylarca hem eski hem yeni pipeline’ları çalıştırır; işlem gücü israf edilir ve hangi sonuçlara güvenileceği konusunda kafa karışıklığı yaşanır.

Eski kalıpları algılayan, geçiş PR’ları üreten ve organizasyon genelinde ilerlemeyi izleyen bir migration CLI aracı bunu platform ölçeğinde çözer; çoğu durumda daha azı yeter: yeni pipeline’ın çalıştığı doğrulandıktan sonra kullanımdan kaldırılan workflow dosyalarını silmek için otomatik PR açan bir script.

Sonuçlar, Metrikler ve Gelecek Yol Haritası#

Ölçülen Sonuçlar#

Altı aylık kademeli yaygınlaştırma sonrasında:

  • %85 benimseme oranı: 40 repository’den 34’ü paylaşımlı action’lara geçti. Kalan 6’sının özel pipeline’lar için meşru nedenleri var (özelleştirilmiş donanım, standart dışı build sistemleri).
  • Build süresi azalması: Ortalama, standartlaştırılmış cache, paralelleştirilmiş test yürütme ve doğru boyutlandırılmış runner’lar sayesinde yaklaşık 45 dakikadan yaklaşık 12 dakikaya düştü.
  • CI destek taleplerinde %70 azalma: Haftada yaklaşık 30’dan yaklaşık 9’a. Kalan talepler çoğunlukla “cache’i nasıl yapılandırırım” yerine gerçekten yeni gereksinimlerle ilgili.
  • Pipeline YAML azalması: Repository başına yaklaşık 500 satırdan yaklaşık 50 satıra. Bu, ekiplerin en doğrudan hissettikleri metriktir çünkü bilişsel yüklerini azaltır.
  • Güvenlik duruşu: Aktif repository’lerin %100’ü AWS kimlik doğrulaması için OIDC kullanıyor. GitHub secret’larında sıfır uzun ömürlü AWS kimlik bilgisi.

Mimariye Genel Bakış#

Infrastructure

Consumer Repositories (40+)

shared-actions monorepo

Composite Actions setup-node, docker-build, security-scan, deploy-ecs

Reusable Workflows node-service, python-service, deploy-production

Action Tests Automated validation

~50 lines YAML workflow_call reference

Hybrid Runners GitHub-hosted + Self-hosted

AWS OIDC Least-privilege roles

Metrics Dashboard DORA + Platform KPIs

Gelecek Yol Haritası#

Yatırım yapmaya değer alanlar:

  1. Dinamik pipeline oluşturma: Statik YAML yerine, repository metadata’sına (dil, deployment hedefi, uyumluluk gereksinimleri) dayalı workflow yapılandırmaları üretmek. Bu, repo başına yapılandırmayı sıfıra yakın düzeye indirebilir.
  2. PR başına geçici ortam: Her pull request için bir preview ortamı oluşturmak ve merge sonrası otomatik temizlik yapmak üzere paylaşımlı deploy action’ını kullanmak.
  3. Maliyet atıflandırma: GitHub Actions dakikalarını ekip, servis ve workflow türüne göre etiketleyerek mühendislik yöneticilerine CI/CD harcamaları üzerinde görünürlük sağlamak ve optimizasyon fırsatlarını belirlemeye yardımcı olmak.

İlk Adımlar#

Benzer bir işe girişen ekipler için işleyen bir sıralama:

  1. Tek bir yüksek değerli action ile başlayın (cache veya güvenlik taraması) ve 3-5 ekibin kullanmasını sağlayın.
  2. Öncesi ve sonrasını ölçün: build süreleri, destek talepleri, benimseme oranı.
  3. Katkı modeline erken yatırım yapın: değişiklikleri yalnızca platform ekibiyle sınırlamak bir darboğaz yaratır.
  4. Güvenliği görünmez tutun: ekipler bir kontrolü atlatıyorsa o kontrol işini yapmıyor demektir.
  5. Kullanımdan kaldırmayı ilk günden planlayın: her v1 sonunda v2 olur ve oraya ulaşacak bir yol gerekir.

Getiri, repository ve ekip sayısıyla birlikte büyür. Tek bir ekibin sahiplendiği birkaç repository varsa workflow template’i ve review disiplini aynı işi görür; platform yükünü ödemeye değmez. Birden fazla ekip workflow’ları bağımsız olarak yönetmeye başladığında tekrar, elle bakılabilecek hızdan daha çabuk büyür ve paylaşımlı yol daha ucuz seçenek hâline gelir.

Kaynaklar#

İlgili yazılar