CI/CD PİPELİNE NEDİR? BUİLD-TEST-DEPLOY AKIŞI VE OTOMASYON PRATİKLERİ
Bir ürünün üretime çıkış anı çoğu ekipte hâlâ “kritik gece operasyonu” hissi yaratabiliyor: kim hangi komutu çalıştırdı, hangi ayar değişti, hangi test atlandı… İşte CI/CD pipeline bu belirsizliği ortadan kaldıran, yazılımın derlenmesinden dağıtıma kadar olan akışı ölçülebilir ve tekrarlanabilir hâle getiren bir otomasyon omurgasıdır.
Pipeline’ı doğru kurguladığınızda, her değişiklik aynı adımlardan geçer; testler tutarlı şekilde koşar; hatalı bir dağıtımın etkisi küçülür; geri dönüş (rollback) planı “dokümanda duran” değil, pratikte çalışan bir mekanizma olur. Üstelik bu yaklaşım sadece hız kazandırmaz; kalite, güvenlik ve denetlenebilirlik için de güçlü bir temel oluşturur.
Bu yazıda build-test-deploy akışını uçtan uca ele alacağız: aşamaların amacı, gerçek hayatta sık görülen pratikler, güvenli dağıtım stratejileri ve örnek konfigürasyonlar. Daha kapsamlı bir yol haritası arıyorsanız CI/CD & DevOps eğitimi sayfasındaki modüller de iyi bir tamamlayıcı olabilir.

CI/CD Pipeline ne demek, neden “pipeline” diyoruz?
Pipeline, birbirini takip eden ve çoğu zaman koşullara bağlı çalışan otomasyon adımlarının zinciridir. Amaç; bir commit’in ya da merge’in, önceden tanımlı kontrol noktalarından geçerek güvenle sürüme dönüşmesi. “Boru hattı” benzetmesi buradan gelir: girişte kaynak kod vardır, çıkışta dağıtıma hazır bir paket (artifact), imaj (container) ya da versiyonlanmış bir çıktı.
Sürekli Entegrasyon: hızlı geri bildirim, küçük risk
Sürekli entegrasyon (CI), geliştiricilerin değişiklikleri sık aralıklarla ana dala entegre etmesini ve her entegrasyonun otomatik doğrulanmasını hedefler. Buradaki kritik nokta hızdır: derleme ve temel testler kısa sürede sonuçlanırsa, hatayı kaynağında yakalarsınız. Bu yaklaşım “büyük birleşimlerin” doğurduğu sürpriz maliyetleri azaltır.
Sürekli Teslimat/Dağıtım: üretime giden yolun standardı
Sürekli teslimat (CD) çoğu ekipte “dağıtıma hazır hâlde tutmak” anlamına gelir; üretime çıkış genellikle bir onay adımıyla tetiklenir. Sürekli dağıtım ise uygun koşullar sağlandığında değişikliklerin otomatik olarak üretime kadar ilerlemesidir. Burada asıl değer, dağıtımı bir “olay” olmaktan çıkarıp sıradanlaştırmasıdır.
Build aşaması: tekrarlanabilir çıktılar ve artifact disiplini
Build adımı sadece “compile” değildir; bağımlılıkların yönetimi, sürüm bilgisinin üretilmesi, paketleme ve en önemlisi aynı girdiden aynı çıktıyı üretme garantisiyle ilgilidir. Bir pipeline’ın güvenilirliği, build çıktısının deterministik olmasına dayanır.
Bağımlılık önbelleği, versiyonlama ve reproducible build
Build süresini düşürmek için önbellek (cache) doğru yerde kullanılır: paket yöneticisi cache’i (npm, Maven, NuGet) ve derleme çıktıları. Ancak cache’in yanlış kullanımı “bende çalışıyor” sorununu geri getirir. Bu yüzden kilit dosyaları (lockfile) ve sabit sürümleme kural hâline gelmelidir. Versiyonlama tarafında semantik versiyonlama ya da commit tabanlı sürümleme tercih edilebilir; önemli olan sürümün build sırasında otomatik ve izlenebilir üretilmesidir.
Artifact yönetimi: tek kaynak, çok ortam
Build sonunda çıkan artifact’in (jar, dll, docker image, zip paket) bir kere üretilip farklı ortamlara aynı şekilde taşınması, “ortama göre build” yaklaşımının risklerini azaltır. Ortam farklılıkları build’de değil, konfigürasyonda yönetilir. Bu yaklaşım, üretimde gördüğünüz davranışın test ortamındakiyle aynı olmasını kolaylaştırır.
Test aşaması: sadece “geçti/geçmedi” değil, kalite kapısı
Test aşaması, pipeline’ın omurgasıdır. Burada hedef; mümkün olduğunca erken, mümkün olduğunca doğru sinyal üretmek. Her şeyi en başta koşmak yerine, testleri katmanlamak yaygın bir pratik: hızlı unit testler önde; daha yavaş entegrasyon ve uçtan uca testler sonra.
Unit, entegrasyon, E2E: hangi test nerede koşmalı?
Unit testler kısa sürede sonuç verir ve geliştiriciye doğrudan geri bildirim sağlar. Entegrasyon testleri servisler arası sözleşmelerin ve veri erişiminin doğruluğunu ölçer. Uçtan uca (E2E) testler kullanıcı senaryolarını kapsar ama pahalıdır; bu yüzden kritik akışlarla sınırlı tutulması çoğu ekipte daha sürdürülebilir sonuç verir. Pipeline, bu katmanların sırasını ve koşulunu şeffaflaştırır.
Kalite kapıları: coverage, statik analiz ve “fail fast” yaklaşımı
Kalite kapısı dediğimiz şey, belirli eşikler sağlanmadan bir sonraki aşamaya geçilmemesidir. Kod kapsamı (coverage), lint kuralları, statik analiz (ör. olası null hataları, kompleksite), bağımlılık güvenliği gibi sinyaller bir araya getirilir. Burada hedef “mükemmellik” değil, ekipçe kabul edilen minimum standardın otomasyonla korunmasıdır. Böylece tartışmalar kişisel tercihlerden çıkıp somut metriklere taşınır.
Deploy aşaması: build-test biter, asıl oyun başlar
Dağıtım, çoğu zaman en yüksek riskin olduğu yerdir; çünkü gerçek trafik ve gerçek veriler devreye girer. Pipeline, deploy’u standartlaştırarak bu riski yönetilebilir hâle getirir. Burada temel prensip, üretime giden adımların da kod gibi versiyonlanmasıdır: “deploy runbook” değil, “deploy as code”.
Blue-green, canary ve kademeli dağıtım stratejileri
Blue-green yaklaşımında iki üretim ortamı (mavi/yeşil) arasında trafik anahtarlanır; yeni sürüm ayrı ortamda ayağa kalkar, doğrulanır ve sonra trafik yönlendirilir. Canary yaklaşımı ise trafiğin küçük bir yüzdesini yeni sürüme vererek riskin etkisini sınırlamaya odaklanır. Kademeli dağıtım (progressive delivery) stratejileri, ölçüm ve otomasyonla birleştiğinde “güvenle hızlanma” sağlar.

Konfigürasyon yönetimi: feature flag, secrets ve ortam değişkenleri
Dağıtım başarısının büyük kısmı konfigürasyon disiplinine bağlıdır. Feature flag’ler, davranış değişikliklerini kod dağıtımından ayırır; geri dönüş senaryolarını hızlandırır. Secrets (anahtarlar, token’lar) kaynak kodda asla tutulmaz; gizli yönetim sistemleriyle (Vault, cloud secret manager) merkezi şekilde yönetilir. Pipeline, bu verileri sadece gerekli scope’ta ve en az ayrıcalık prensibiyle kullanır.
Güvenlik ve uyumluluk: pipeline’a sonradan eklenen “ekstra adım” değil
Güvenlik kontrolleri, en sonda yapılan bir “checklist” olduğunda gecikme ve sürpriz üretir. Oysa modern CI/CD yaklaşımında güvenlik; build, test ve deploy adımlarına entegre edilerek sürekli bir doğrulama hâline gelir. Böylece hem hızlı ilerlersiniz hem de risk görünür olur.
SAST, bağımlılık taraması ve imaj güvenliği
Statik uygulama güvenlik testi (SAST) kodu çalıştırmadan riskli desenleri yakalamaya odaklanır. Bağımlılık taraması (dependency scanning) ise üçüncü parti kütüphanelerdeki açıkları görünür kılar. Container kullanıyorsanız imaj taraması ayrıca önem kazanır: base image seçimi, paketlerin güncelliği, gereksiz araçların çıkarılması gibi noktalar doğrudan saldırı yüzeyini etkiler.
İmzalama, provenance ve denetlenebilirlik
Üretime giden artifact’in nerede üretildiği, hangi commit’e karşılık geldiği ve kim tarafından onaylandığı izlenebilir olmalıdır. Artifact imzalama ve provenance (kaynak doğrulama) yaklaşımları, özellikle regülasyon gerektiren sektörlerde önemli avantaj sağlar. Pipeline logları, onay adımları ve sürüm etiketleri bu denetim izini tamamlar.
Gözlemlenebilirlik ve rollback: “dağıttık bitti” değil, “izle ve doğrula”
Dağıtımdan sonraki birkaç dakika, en kritik penceredir. İyi kurgulanmış bir pipeline, dağıtımı tamamladığında otomatik doğrulama adımlarını devreye alır: sağlık kontrolleri (health checks), temel iş metrikleri, hata oranları, gecikme (latency) ve kaynak kullanımı gibi sinyaller bir arada değerlendirilir.
Monitoring sinyalleri: teknik metrik + iş metriği birlikteliği
Yalnızca CPU ya da bellek izlemek çoğu zaman yeterli değildir. Hata oranı, p95 gecikme, kuyruk uzunluğu gibi teknik metriklerin yanında “sipariş oluşturma başarısı” ya da “ödeme onayı” gibi iş metrikleri de izlenmelidir. Canary dağıtım stratejilerinde karar verme mekanizması bu sinyaller üzerinden çalışır; eşikler aşıldığında otomatik durdurma ve geri dönüş tetiklenebilir.

Rollback ve roll-forward: doğru senaryo, doğru hamle
Rollback, bir önceki sürüme geri dönmektir; hızlı bir “yangın söndürme” aracıdır. Ancak her zaman en iyi seçenek değildir: veri şeması değişimleri gibi durumlarda roll-forward (hızlı düzeltme sürümü) daha güvenli olabilir. Bu yüzden pipeline’da geri dönüş stratejisi, uygulamanın mimarisiyle uyumlu tasarlanır: geriye uyumlu migration, feature flag’ler ve aşamalı aktivasyon gibi teknikler burada kritik rol oynar.
Pratik bir pipeline tasarımı: adım adım örnekler
Somut bir örnek üzerinden düşünmek, kurguyu netleştirir. Aşağıdaki örnekler “her ekip için tek doğru” değildir; ancak gerçek hayatta sık görülen bir yapıyı temsil eder: hızlı CI, katmanlı test, artifact üretimi ve kontrollü CD.
Örnek 1: GitHub Actions ile build-test ve kontrollü deploy
Bu örnekte; ana dala gelen değişiklikler için build ve test çalışır, imaj üretilir ve registry’ye gönderilir. Üretime dağıtım adımı ise ortam onayıyla tetiklenebilir şekilde kurgulanır. Template literal içinde ${} ifadesi kaçışlı yazılmıştır.
name: ci-cd
on:
push:
branches: [ "main" ]
pull_request:
jobs:
build_test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Install
run: npm ci
- name: Lint
run: npm run lint
- name: Unit tests
run: npm test -- --ci
- name: Build
run: npm run build
docker_publish:
needs: build_test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Log in to registry
run: echo "${{ secrets.GHCR_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin
- name: Build and push
run: |
docker build -t ghcr.io/acme/app:${{ github.sha }} .
docker push ghcr.io/acme/app:${{ github.sha }}Örnek 2: GitLab CI’de çok aşamalı test ve ortam bazlı kurallar
GitLab CI yaklaşımında stage mantığı net bir ayrım sağlar: build, test ve deploy. Üretim dağıtımı için manuel onay eklemek yaygındır. Örnekte değişken kullanımlarında ${} kaçışı uygulanmıştır.
stages:
- build
- test
- deploy
variables:
IMAGE_TAG: "${CI_COMMIT_SHA}"
build:
stage: build
image: docker:27
services:
- docker:27-dind
script:
- docker build -t registry.example.com/acme/app:${IMAGE_TAG} .
- docker push registry.example.com/acme/app:${IMAGE_TAG}
rules:
- if: '${CI_COMMIT_BRANCH} == "main"'
test:
stage: test
image: node:20
script:
- npm ci
- npm run lint
- npm test -- --ci
rules:
- if: '${CI_PIPELINE_SOURCE} == "merge_request_event"'
- if: '${CI_COMMIT_BRANCH} == "main"'
deploy_prod:
stage: deploy
image: alpine:3.20
script:
- echo "Deploying ${IMAGE_TAG} to production..."
when: manual
rules:
- if: '${CI_COMMIT_BRANCH} == "main"'Pipeline pratikleri: sürdürülebilir otomasyon için kontrol listesi
Tek bir pipeline dosyası yazıp bırakmak genellikle yetmez; asıl değer, zaman içinde sürdürülebilen bir standart oluşturmakla gelir. Aşağıdaki maddeler, farklı ölçeklerde ekiplerin en sık fayda gördüğü pratiklerin kısa bir özetidir.
- CI adımlarını hızlı tutmak: temel testler ve statik kontroller ilk dakikalarda sonuç verir.
- Artifact’i bir kere üretmek: aynı çıktıyı farklı ortamlara taşımak, sürprizleri azaltır.
- Kalite kapılarını netleştirmek: minimum standardı otomasyonla korumak, tartışmayı sadeleştirir.
- Secrets yönetimini merkezileştirmek: en az ayrıcalık ve kısa ömürlü kimlik bilgileri tercih edilir.
- Dağıtımı kademelendirmek: canary/blue-green ile risk küçük parçalara bölünür.
- Gözlemlenebilirliği pipeline’a bağlamak: dağıtım sonrası doğrulama adımı bir refleks hâline gelir.
- Rollback senaryolarını prova etmek: sadece dokümanda değil, pratikte çalışan süreç hedeflenir.
Sonuç: CI/CD pipeline, hız kadar güvenin de altyapısıdır
CI/CD pipeline, ekiplerin “daha hızlı çıkalım” motivasyonunu “daha güvenle çıkalım” standardına dönüştürür. Build-test-deploy akışı bir kez otomasyona bağlandığında, süreç kişilere bağımlı olmaktan çıkar; kalite sinyalleri görünür olur; dağıtım riski stratejilerle yönetilir.
İyi bir başlangıç için küçük bir hedef belirleyin: önce hızlı CI (lint + unit), sonra artifact disiplini, ardından kontrollü CD. Bu sırada güvenlik taramalarını ve izleme sinyallerini pipeline’a entegre ettikçe, üretime çıkışın stresini değil, öğrenme hızını hissedersiniz.


