Mayıs 27 2026

Git Commit Çöplüğüne Son: CI/CD Pipeline Süreçlerini Yerelde Test Etme Yöntemleri

Yazım hatası yüzünden patlayan bir build. Arkasından gelen “fix typo” commit’i. O da yemedi; “fix syntax again”, “please work”, “test 4” ve nihayetinde “really fix this time”. Tanıdık geldi mi? Reponun commit geçmişini adeta bir çöplüğe çeviren bu döngü, yalnızca estetik bir problem değil. Her push işleminde buluttaki runner’ın ayağa kalkmasını beklemek, saatlik faturaları şişirmek ve geri bildirim döngüsünü (feedback loop) dakikalarca uzatmak demektir. Profesyonel bir SRE veya DevOps mühendisi için bu kabul edilemez bir zaman kaybıdır.

Bu pratik rehberde, commit-push-wait döngüsünden kurtulup yerel pipeline testi (local cicd testing) süreçlerini nasıl profesyonelce kurgulayacağımızı ele alacağız. GitHub Actions ve GitLab CI pipeline’larınızı, uzak sunuculara hiç dokunmadan, doğrudan kendi terminalinizde nasıl simüle edeceğinizi gerçek senaryolarla inceleyeceğiz.

Neden Yerelde Test Etmeliyiz? (The SRE Perspective)

Bunu sadece “temiz git geçmişi” motivasyonuyla açıklamıyoruz. Altında yatan asıl nedenler tamamen operasyonel verimlilik ve güvenlikle ilgilidir:

  • Hızlı Geri Bildirim Döngüsü: Buluttaki bir runner’ın kuyrukta beklemesi, imajı çekmesi ve init olması ortalama 1-3 dakika sürer. Yerelde bu süre saniyeler mertebesindedir.
  • Maliyet Optimizasyonu: GitHub Actions veya GitLab CI faturalarınızın önemli bir kısmı, aslında “deneme-yanılma” aşamasındaki başarısız run’lardan kaynaklanır.
  • Güvenli Secret Yönetimi: Yeni bir entegrasyonu denerken production secret’larını ya da hassas API anahtarlarını geçici olarak buluttaki CI ortamına eklemek her zaman güvenlik riski barındırır.

GitHub Actions’ı Yerelde Koşturmak: act

GitHub Actions workflow’larını yerel makinede çalıştırmanın fiili standardı act aracıdır. `act`, lokalinizdeki Docker daemon’ını kullanarak GitHub’ın runner ortamlarını simüle eden container’lar ayağa kaldırır ve tanımladığınız adımları bu container’lar içinde çalıştırır.

act Kurulumu ve Temel Kullanımı

Kurulumu macOS işletim sistemlerinde Homebrew ile hızlıca yapabilirsiniz:

brew install nektos/tap/act

Eğer Linux kullanıyorsanız, doğrudan binary olarak çekebilirsiniz:

curl -s https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash

Gerçekçi Bir Senaryo: Secret’lar ve Matrix Yapıları

Diyelim ki elinizde node.js uygulamasını test eden ve deploy etmeden önce bir API anahtarına ihtiyaç duyan aşağıdaki gibi bir `.github/workflows/ci.yml` dosyanız var:

name: Node.js CI

on:
  push:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18.x, 20.x]
    steps:
      - uses: actions/checkout@v3
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm ci
      - run: npm test
        env:
          DATABASE_URL: ${{ secrets.DATABASE_URL }}

Bu workflow’u yerelde çalıştırmak istediğinizde doğrudan `act` komutunu vermeniz yetmez; çünkü `secrets.DATABASE_URL` boş kalacaktır ve matrix yapısı yüzünden süreç uzayacaktır. İşte tam bu noktada profesyonel parametreler devreye giriyor.

Öncelikle bir `.secrets` dosyası oluşturun:

DATABASE_URL=mongodb://localhost:27017/test_db

Şimdi sadece Node 20 versiyonunu ve sadece `test` job’ını tetiklemek, üstelik bunu yaparken de yerel secret dosyamızı beslemek için şu komutu koşturuyoruz:

act -j test --matrix node-version:20.x --secret-file .secrets

In-depth Tip: Runner Boyutu Sorunsalı

`act` ilk çalıştığında size hangi imaj boyutunu kullanmak istediğinizi sorar (Micro, Medium, Large). Varsayılan “Micro” imaj genelde hızlı iner ancak içinde `curl`, `docker`, `aws-cli` gibi temel araçları barındırmaz. Gerçekçi bir act github actions deneyimi için en azından “Medium” imajı seçmeli veya `.actrc` dosyanıza şu custom imaj eşlemesini eklemelisiniz:

-P ubuntu-latest=catthehacker/ubuntu:act-latest

GitLab CI Pipeline’larını Yerelde Simüle Etmek

GitLab tarafında işler biraz daha karmaşıktır. Resmi `gitlab-runner exec` komutu uzun süredir “deprecated” durumdadır ve `needs`, `parent-child pipelines` veya modern `artifacts` tanımlamalarını tam olarak desteklemez. SRE topluluğu bu boşluğu doldurmak için harika bir açık kaynaklı alternatif geliştirdi: gitlab-ci-local.

gitlab-ci-local Kurulumu

NodeJS tabanlı bu CLI aracını sisteminize kurmak için NPM veya Homebrew kullanabilirsiniz:

brew install firecow/gitlab-ci-local/gitlab-ci-local

Uygulama: Kompleks Bir .gitlab-ci.yml Testi

Şöyle bir pipeline yapımız olduğunu düşünelim. Uygulamayı derliyor, artifact üretiyor ve bir sonraki stage’de bu artifact’i kullanıyor:

stages:
  - build
  - test

compile-code:
  stage: build
  image: node:20-alpine
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/

run-unit-tests:
  stage: test
  image: node:20-alpine
  needs: ["compile-code"]
  script:
    - ls dist/
    - npm run test:unit

Bu pipeline’ı `gitlab-runner local` mantığıyla kendi makinenizde çalıştırmak için terminalden şu komutu vermeniz yeterlidir:

gitlab-ci-local

`gitlab-ci-local`, projenizin kök dizinindeki `.gitlab-ci.yml` dosyasını analiz eder, adımları sırasıyla çalıştırır, `needs` direktifine sadık kalır ve en önemlisi üretilen `dist/` klasörünü lokalinizdeki `.gitlab-ci-local/artifacts/` klasörüne otomatik olarak map eder. Böylece build artifact’lerinin bir sonraki job’a düzgün aktarılıp aktarılmadığını gözlerinizle görebilirsiniz.

Yerel GitLab Variable’larını Yönetmek

Gerçek CI ortamında GitLab UI üzerinden tanımladığınız “masked/protected” değişkenleri yerelde taklit etmek için `.gitlab-ci-local-variables.yml` adında bir dosya oluşturabilirsiniz:

STAGING_KUBE_TOKEN: "kube-token-12345"
DB_PASSWORD: "super-secret-password"

Bu dosya `.gitignore` listenizde olmalıdır. Araç, bu değişkenleri otomatik olarak okuyacak ve container’ların içerisine enjekte edecektir.

Docker-in-Docker (DinD) ve Soket Paylaşımı Çıkmazı

Yerel pipeline testlerinde en çok baş ağrıtan konulardan biri, pipeline adımının kendisinin de Docker ayağa kaldırmaya çalışmasıdır (örneğin, entegrasyon testleri için geçici bir DB container’ı başlatmak veya imajı `docker build` ile derlemek).

Eğer `act` kullanıyorsanız ve job’ınız içinde Docker komutları koşturacaksanız, lokalinizdeki Docker soketini container içine mount etmeniz gerekir:

act --bind-workdir -v /var/run/docker.sock:/var/run/docker.sock

Benzer şekilde, `gitlab-ci-local` kullanırken `services: – docker:dind` tanımınız varsa, aracın konfigürasyonunda yerel soketin paylaşıldığından emin olun. Bu sayede iç içe (nested) container yapısı yerine, tüm container’ların sizin host Docker daemon’ınız üzerinde “sibling” (kardeş) container’lar olarak ayağa kalkmasını sağlarsınız. Bu, hem disk alanından tasarruf sağlar hem de performansı katlar.

Özet ve Best Practice’ler

Süreci bir standarta oturtmak adına ekibinize şu kuralları aşılamanızı öneririz:

  1. Pre-commit Hook Entegrasyonu: Kritik CI script değişikliklerinde, geliştiricilerin lokalde en azından bir `act` veya `gitlab-ci-local` kuru testi yapmasını zorunlu tutun.
  2. Maksimum İmaj Önbellekleme (Caching): Lokal testlerin hızlı olması için Docker imajlarını yerelde optimize edin. Sık kullanılan base imajları (`node`, `python`, `golang` alpine versiyonları) önceden `docker pull` ile çekin.
  3. Lokal .env/.secrets Dosyalarını Asla Push Etmeyin: Güvenlik en katı kuraldır. `.gitignore` dosyanızda yerel pipeline testlerinde kullandığınız tüm taklit secret dosyalarının tanımlı olduğundan emin olun.

Geliştirme hızınızı (velocity) artırmak ve CI bütçelerini optimize etmek tamamen feedback loop süresini kısaltmaktan geçiyor. Araçlarınızı doğru yapılandırın, lokal gücü kullanın ve o commit çöplüğünü tarihe gömün.

Category: Genel | LEAVE A COMMENT