Değişiklikler sık sık ortak dala katılır; her katılımda build ve test otomatik çalışır. Sorunlar büyümeden, daha küçük ve ucuzken yakalanır.
Bir değişikliği elle derlemek, test etmek ve sunucuya taşımak hem yavaştır hem de her seferinde insan hatasına açıktır. CI/CD, bir commit'ten üretime giden yolu otomatik ve tekrarlanabilir bir hatta (pipeline) bağlar; böylece her değişiklik aynı adımlardan geçer, hızlı geri bildirim alır ve güvenle yayına çıkar. Bu sayfada CI ile CD'nin ne anlama geldiğini, pipeline'ın hangi aşamalardan oluştuğunu, deployment'ı kesintisiz yapmanın yollarını ve bir hattın sağlığını hangi metriklerle ölçtüğünüzü birlikte adım adım ele aldık.
CI/CD, kısaltmanın iki yarısını birbirine bağlayan bir pratikler bütünüdür. Continuous Integration (CI), ekip üyelerinin değişikliklerini sık sık ortak dala katıp her seferinde otomatik build ve test çalıştırmasıdır; amaç, entegrasyon sorunlarını günler sonra değil dakikalar içinde yakalamaktır. Continuous Delivery (CD), her başarılı build'i tek bir tuşla üretime alınabilecek hazır bir sürüme dönüştürür; üretime çıkış kararı insandadır. Continuous Deployment ise bu son adımı da otomatikleştirir: testlerden geçen her değişiklik elle onay beklemeden üretime gider. Bu sayfanın odağı, bu üç pratiği taşıyan otomatik hat — yani pipeline'dır.
# bir commit hattı tetikler
push main → CI build + test # dakikalar içinde geri bildirim
CD artifact üret
staging otomatik deploy
prod onay → deploy # delivery: insan onayı
deploy # deployment: otomatik
Değişiklikler sık sık ortak dala katılır; her katılımda build ve test otomatik çalışır. Sorunlar büyümeden, daha küçük ve ucuzken yakalanır.
Her build üretime alınabilir bir sürüme dönüşür ama yayına çıkış kararı insanındır. Üretim her an "bir tuş uzaktadır".
Son adım da otomatiktir: testlerden geçen her değişiklik elle onay beklemeden üretime gider. Güçlü test ve gözlemlenebilirlik gerektirir.
Pipeline, bir commit'i alıp üretime taşıyan sıralı aşamalardan (stage) oluşur. Her aşama bir öncekinin çıktısını devralır ve herhangi biri başarısız olursa hat hemen durur (fail fast) — böylece bozuk bir değişiklik bir sonraki adıma geçemez. Erken aşamalar saniyeler süren ucuz kontrollerdir; pahalı ve yavaş testler sona bırakılır, çünkü çoğu hata zaten en başta yakalanır.
source commit / merge request # tetikleyici
build derle, bağımlılık çek
test unit → integration → e2e # ucuzdan pahalıya
package artifact / image üret # değişmez çıktı
deploy staging → production
FAIL herhangi bir aşamada → hat durur
Kaynak kod derlenir, bağımlılıklar çekilir ve çalıştırılabilir bir çıktı üretilir. İyi bir pipeline aynı kodu yalnızca bir kez build eder; sonraki aşamalar bu çıktıyı yeniden derlemeden kullanır.
Önce hızlı unit testler, sonra integration ve en sona e2e testleri. Test piramidine uygun bu sıralama, hataların çoğunu en ucuz aşamada yakalar. Ayrıntı için Yazılım & Mimari başlığına bakabilirsiniz.
Test edilen çıktı bir artifact'e (container image, paket, binary) dönüştürülür. Aynı artifact tüm ortamlarda yeniden derlenmeden ilerletilir; "staging'de çalıştı ama prod'da bozuldu" sorununu kökten azaltır.
Continuous Integration'ın özü teknik değil disipline dairdir: kod ne kadar sık ortak dala katılırsa, çakışmalar o kadar küçük ve çözülmesi kolay olur. Günlerce yaşayan uzun dallar yerine kısa ömürlü dallar ve sık merge, "integration hell" denen büyük birleştirme acılarını ortadan kaldırır. Bunun çalışması için iki koşul şart: her merge'i otomatik doğrulayan güvenilir bir test takımı ve bozulan build'i her şeyin önüne koyup hemen onaran bir ekip refleksi.
Değişiklikler küçük tutulup günde birkaç kez ortak dala katılır. Uzun yaşayan dalların yarattığı dev çakışmalar hiç oluşmaz.
Her commit testlerin tamamını tetikler. İnsan gözüne kalmayan bu güvenlik ağı, sık entegrasyonu güvenli kılan asıl şeydir.
Hata çıktığında pipeline anında durur ve ekibe haber verir. Bozuk bir değişikliğin ilerlemesine izin verilmez; geri bildirim dakikalarla ölçülür.
Ana dala merge için pipeline'ın yeşil olması ve review şartı koşulur. Yeşil olmayan kod ortak dala giremez; ana dal her zaman çalışır halde kalır.
Continuous Delivery ile Continuous Deployment arasındaki tek fark üretime çıkıştaki o son manuel onaydır. İkisinde de aynı artifact ortamlar arasında ilerletilir (promotion): dev'de üretilen çıktı staging'de doğrulanır, oradan production'a aynen taşınır — hiçbir ortam için yeniden derlenmez. Farklılık ortamlar arasındaki konfigürasyonda kalır, kodda değil.
build → app:v1.4.2 # bir kez üretilir
staging deploy app:v1.4.2 # otomatik
smoke test ✓
prod deploy app:v1.4.2 # delivery: onay sonrası
# deployment: onaysız
# aynı artifact; değişen yalnızca config & secret
Yeni sürümü kullanıcılara nasıl açtığınız, bir hatanın etkisini doğrudan belirler. Hepsini bir anda değiştirmek hızlıdır ama riskli; değişikliği kademeli açmak ise sorunu azınlık trafikteyken yakalayıp geri almanıza imkân verir. Doğru strateji, kesinti toleransınıza, trafiğinizin büyüklüğüne ve geri alma hızınıza bağlıdır.
Yeni sürüm (green) eski sürümün (blue) yanına kurulur; hazır olunca tüm trafik bir anda green'e çevrilir. Sorun çıkarsa trafik anında blue'ya geri alınır. Anlık geçiş sağlar ama iki kat kaynak ister.
Yeni sürüm önce trafiğin küçük bir dilimine (ör. %5) açılır; metrikler iyiyse pay kademeli büyütülür. Bir sorun yalnızca az sayıda kullanıcıyı etkilerken yakalanır; gözlemlenebilirlik şarttır.
Eski örnekler (instance) birer birer yenisiyle değiştirilir; hizmet hiç kesilmez. Kubernetes'in varsayılan davranışıdır ama geçiş sırasında iki sürüm bir süre yan yana çalışır.
Kod üretime gider ama özellik bir bayrakla kapalı durur; istediğiniz an, istediğiniz kullanıcıya açılır. Deployment ile release'i ayırır — kodu taşımak ile özelliği açmak iki ayrı karar olur.
Modern pipeline'lar kodla tanımlanır: hattın kendisi de versiyon kontrolünde duran bir dosyadır (pipeline-as-code). GitHub Actions, GitLab CI/CD, Jenkins ve benzeri araçlar bu tanımı alıp işi runner adı verilen çalışma örneklerinde yürütür. Hızlı ve güvenli bir hat için birkaç pratik belirleyicidir: bağımlılıkları önbelleğe almak, gizli bilgileri koda gömmeden yönetmek ve işleri paralel çalıştırmak.
on: [push]
jobs:
test:
runs-on: ubuntu-latest # runner
steps:
- checkout
- cache: deps/ # tekrar indirme
- run: build && test
secrets: [API_TOKEN] # koda gömme
Pipeline adımları runner denen örneklerde çalışır; bunlar sağlayıcının paylaşımlı makineleri ya da kendi kurduğunuz (self-hosted) makineler olabilir. Her iş temiz bir ortamda başlar, böylece sonuçlar tekrarlanabilir kalır.
Bağımlılıkları önbelleğe almak ve bağımsız işleri paralel (matrix) çalıştırmak, pipeline süresini dakikalardan saniyelere indirir. Yavaş bir hat, sık entegrasyonun en büyük düşmanıdır.
Token ve anahtarlar koda ya da log'a değil, sağlayıcının secret deposuna konur ve çalışma anında enjekte edilir. Pipeline güvenliği için Web Uygulama Güvenliği başlığındaki ilkeler burada da geçerlidir.
Bir teslim hattının sağlığı dört DORA metriğiyle ölçülür: ne sıklıkta dağıttığınız (deployment frequency), bir değişikliğin koddan üretime geçme süresi (lead time), dağıtımların ne kadarının soruna yol açtığı (change failure rate) ve bir aksaklıktan toparlanma süresi (MTTR). Hızlı ve güvenli ekipler bu dördünde birden iyidir; hız ile istikrar zıt değil, aynı disiplinin sonucudur. Hattı yavaşlatan ya da güveni aşındıran birkaç tipik tuzak vardır.
Deployment frequency, lead time for changes, change failure rate ve MTTR. İlk ikisi hızı, son ikisi istikrarı ölçer; birlikte teslim performansının tam resmini verir.
Aynı kodla bazen geçip bazen kalan testler, pipeline'a olan güveni yok eder; ekip kırmızıyı görmezden gelmeye başlar. Tespit edilip ya düzeltilmeli ya da karantinaya alınmalıdır.
Yarım saat süren bir pipeline, geri bildirimi geciktirir ve sık entegrasyonu caydırır. Cache, paralellik ve gereksiz adımları ayıklamak en yüksek getirili iyileştirmedir.
Hattın ortasında kalan elle yapılan adımlar, hem yavaşlatır hem de tekrarlanabilirliği bozar. Her manuel adım otomatikleştirilecek bir aday olarak görülmelidir.
Staging ile production birbirinden uzaklaştığında "bende çalışıyordu" sorunları başlar. Ortamları kodla (IaC) tanımlamak bu sapmayı önler; DevOps & Otomasyon başlığına bakabilirsiniz.
Geri dönüşü test edilmemiş bir pipeline, ilk ciddi aksaklıkta panikle sonuçlanır. Rollback de tıpkı deploy gibi otomatik ve denenmiş olmalıdır.
CI kodu sık sık birleştirip otomatik build ve test etmektir — odağı entegrasyonun sağlığıdır. CD ise test edilen sürümü güvenle üretime taşımaktır. CI, CD'nin ön koşuludur: güvenilir bir test ağı olmadan otomatik dağıtım tehlikelidir.
Continuous Delivery her sürümü üretime hazır tutar ama yayına çıkış için insan onayı bekler. Continuous Deployment bu onayı da kaldırır; testten geçen her şey otomatik üretime gider. Tek fark o son manuel kapıdır.
Blue-green tüm trafiği bir anda yeni sürüme çevirir; geçiş ve geri alma anlıktır. Canary trafiği kademeli açar, sorunu azınlıktayken yakalar. Blue-green hızlı geçiş, canary ise kademeli risk kontrolü sunar.
Deployment kodu bir ortama taşımaktır; release ise özelliği kullanıcıya açmaktır. Feature flag'ler bu ikisini ayırır: kod üretimde durabilir ama özellik kapalı kalabilir — taşımak ve açmak iki ayrı karar olur.
Artifact build aşamasında üretilen değişmez çıktıdır (image, paket). Release ise bir artifact'in belirli bir sürüm olarak kullanıcıya sunulan halidir. Aynı artifact farklı ortamlara dağıtılır; release o artifact'e iliştirilen sürüm kimliğidir.
GitHub Actions ve GitLab'in resmi pipeline dokümantasyonu, continuous integration ve delivery'nin kavramsal kaynakları ve teslim performansını ölçen DORA araştırması.
İyi kurulmuş bir pipeline, her değişikliği hızlı ve güvenle üretime taşır; eksik kurulmuş bir hat ise sessizce risk biriktirir. Build, test ve deployment adımlarınızı baştan sona birlikte tasarlayalım.