GitHub Actions Tetikleyicileri: push vs pull_request vs Merge Queue vs Release
Her git olayı farklı bir işi hak eder: push, pull_request, merge kuyruğu ve tag/release'de ne çalışmalı? Lead time'ı koruyan bir GitHub Actions yönlendirme rehberi.
Özellik commit’i push’layın, pull request açın ya da release çıkarın; birçok pipeline üçüne de aynı yanıtı verir: tam test matrisi, entegrasyon paketi ve deploy mantığının hepsi tetiklenir. Asıl sorun bu tekdüzeliktir. Her git olayı yaşam döngüsünün farklı bir noktasında gelir ve farklı bir güvenlik bağlamı taşır; bir tetikleyiciye ait olan kontrol, başka bir tetikleyicide ya israftır ya da tehlikelidir. Bunun yerine on: bloğunu bir yönlendirme tablosu gibi ele alın: kontrolü tetikleyiciye eşleyin ki PR geri bildirimi hızlı kalsın, main deploy edilebilir kalsın ve release’ler tekrar üretilebilir kalsın.
Ana eksen Compressing Time to Production yazısındakiyle aynıdır: lead time’ı korumak. Her push’ta her şeyi çalıştırmak teslimatı güvenli yapmaz; geri bildirimi yavaşlatır ve henüz incelemediğiniz koda yetki sızdırır.
Tetikleyici Yönlendirme Tablosu#
GitHub Actions’ta on: olayları birbirinin yerine geçen etiketler değildir. Her biri farklı bir yaşam döngüsü anında tetiklenir ve işe farklı bir token ile secret bağlamı verir. Önce tetikleyiciyi seçin, sonra işin ne yapacağına karar verin.
Bir push, commit push’larında ve tag push’larında tetiklenir; branches, tags veya paths ile kapsamı daraltılır (branch ve path filtreleri AND ile birleşir). Bir pull_request, bir PR açıldığında, güncellendiğinde veya yeniden açıldığında çalışır ve birleştirilmiş sonucu test eder. Merge kuyruğu, toplu bir kombinasyon için kontrol istediğinde kendi olayını, merge_group’u, gönderir. Bir release, Release nesnesinin yaşam döngüsünden tetiklenir; bu, push: tags: olayının gözlemlediği ham tag push’tan farklı bir andır. Tabloyu iki tetikleyici daha tamamlar. workflow_run bir workflow’u başka birinden zincirler (yalnızca default branch, en fazla üç seviye derinlikte). workflow_dispatch ise manuel veya API tetikleyicisidir (yalnızca default branch).
Aşağıdaki tablo aynı haritanın tablo halidir. Token ve secret sütunu çoğu ekibin atladığı kısımdır ve bir tetikleyicide ayrıcalıklı iş çalıştırmanın güvenli olup olmadığına karar veren kısımdır.
| Tetikleyici | Amaç | Tipik kontroller | Token / secret bağlamı |
|---|---|---|---|
push (özellik branch’i) | Hızlı commit başına geri bildirim | Lint, unit test, tip kontrolü | Repo token; ayardan salt-okunur yapın |
pull_request | Merge kapısı | Birleştirilmiş sonuçta zorunlu kontroller | Salt-okunur token, fork PR’larda secret yok |
push (main) | Merge sonrası entegrasyon, staging | Entegrasyon paketi, staging deploy | Repo token; güvenilir bağlam |
merge_group | Merge öncesi entegrasyon kanıtı | Tam zorunlu kontrol seti | Repo token; güvenilir bağlam |
release: published | Tekrar üretilebilir imzalı build | Build, attest, deploy | Onay arkasında yükseltilmiş yazma yetkisi |
Pull Request Kapısı#
pull_request tetikleyicisi merge kararının uygulandığı yerdir; bu yüzden zorunlu kontrolleri taşır ve ayrıcalıklı hiçbir iş taşımaz. Varsayılan olarak opened, synchronize ve reopened etkinlik türlerinde çalışır ve PR branch ucu yerine merge commit’ini (refs/pull/N/merge) checkout eder. Bu detay önemlidir: CI, branch’i tek başına değil, PR’ı base’e birleştirmenin sonucunu test eder ve PR çakışma içerdiğinde hiç çalışmaz. Gerçekten inecek olan şeyi test ediyorsunuz.
Bu tetikleyicideki bir kontrol, siz onu zorunlu yapana kadar tavsiye niteliğindedir. Bir kontrolü kapıya çeviren şey branch protection veya bir ruleset’tir; bu olmadan kırmızı bir build yine de merge olabilir. “Kapı yanlış yerde” sorununun en yaygın hali budur: kontrol çalışır, ekip ona güvenir ve başarısız olduğunda merge’i hiçbir şey durdurmaz.
Güvenlik sınırı da buradadır. Bir fork’tan açılan pull request salt-okunur bir GITHUB_TOKEN alır ve repository secret’larına erişemez. Fork için güvenli bağlam budur: güvenilmeyen katkıcı kodu cloud kimlik bilgilerinizi okuyamaz veya reponuza push yapamaz.
Warning
pull_request ve pull_request_target birbirinin yerine geçmez. pull_request_target, base-repo bağlamında yazma yetkisi olan bir token ve tam secret erişimiyle çalışır. Bunu güvenilmeyen PR head’inin checkout’uyla birleştirince GitHub Security Lab’ın belgelediği “pwn request” açığı ortaya çıkar: saldırgan kontrolündeki kod sizin secret’larınızla çalışır. Güvenilmeyen kodu build etmeniz ve secret da kullanmanız gerekiyorsa pull_request_target’a başvurmayın. Güvenilmeyen build’i pull_request üzerinde (salt-okunur, secret’sız) çalıştırın ve çıktısını artifact olarak yükleyin; sonra o artifact’i workflow_run ile tetiklenen ayrı, ayrıcalıklı bir workflow’da işleyin.
Main’e Merge Aşaması#
Main’e bir merge, main’e bir push’tur; bu yüzden on: push: branches: [main] merge sonrası entegrasyon ve staging deploy için doğal yerdir. PR kapısı merge commit’ini tek başına kanıtladı; push-to-main aşaması gerçekten inen kod üzerinde çalışır ve onu bir staging ortamına yükseltir.
Ölçek büyüdükçe PR kapısında bir boşluk ortaya çıkar: her biri tek başına geçen iki PR, birleştirildiğinde bozulabilir. Merge kuyruğu bu boşluğu kapatır. Geçici bir branch (hedef artı kuyruktaki PR’lar, main/pr-N gibi adlandırılan) oluşturur ve merge_group olayını gönderir; böylece CI, herhangi bir tek PR yerine merge sonrası kombinasyonu çalıştırır. İşin püf noktası bağlantıdır. Bir zorunlu kontrol workflow’a göre eşleşir ve zorunlu-kontrol workflow’unuz merge_group’a abone olmazsa, kontrol kuyruktaki kombinasyonda hiç raporlanmaz ve merge süresiz takılır. Çözüm on: bloğunda tek bir satırdır.
on:
pull_request:
merge_group:
Bu parça, tüm modeldeki tek olmazsa olmaz yapılandırmadır. Geri kalan her şey yönlendirme kararıdır; bu, eksik bir tetikleyicinin kuyruğu sessizce bozduğu tek yerdir. Build eşzamanlılığı kuyruk çalıştırmalarının kaçının aynı anda yürüyeceğini sınırlar. Staging deploy ise bir deployment ortamı ve bir concurrency grubu kullanarak devam eden deploy sayısını bire indirir; böylece hızlı bir kuyruk üst üste binen deploy’lar başlatmaz.
Tag ve Release İşi#
Release, yazma yetkisini bilerek yükselttiğiniz tek tetikleyicidir. release: published’a abone olun ve iş tag’de (refs/tags/<tag>) çalışır; bu, build, imzalama ve deploy için sabit, tekrar üretilebilir noktadır. published’a abone olmak hem kararlı release’leri hem de ön sürümleri kapsar; taslak trafiğini ise pipeline’ın dışında tutar.
İmzalı provenance üretmenin yeri burasıdır. GitHub Artifact Attestations, Haziran 2024’ten beri genel kullanıma açıktır; üretilen artifact’i onu üreten workflow çalıştırmasına bağlayan, Sigstore destekli bir attestation üretir; tüketici bunu gh attestation verify ile doğrular. Temel izin seti üç yetkiden oluşur: imzalama kimliğini üretmek için id-token: write, kaynağı okumak için contents: read ve attestation’ı kaydetmek için attestations: write. packages: write’i yalnızca bir container imajı da push ediyorsanız ekleyin; temel setin parçası değildir.
Note
release: published ve push: tags:, farklı anlarda tetiklenen farklı olaylardır; işin ham tag push yerine Release yaşam döngüsünden tetiklenmesi için release: published’ı tercih edin. Attestation adımında actions/attest-build-provenance, daha alt seviyeli actions/attest’in bir sarmalayıcısıdır. Sürümünü kendi pinleme politikanıza göre sabitleyin; çünkü upload, download ve attestation action’larının hepsi kendi takviminde major sürüm değiştirir.
Attestation’lar SLSA Build Level 2 şekline karşılık gelir: barındırılan bir build platformu, bir tüketicinin doğrulayabileceği imzalı provenance üretir. Bu eşlemeyi tanımlayıcı kabul edin: bilinen seviye adları SLSA v1.0’dan gelir, güncel spek v1.2’dir ve varsayılan kurulum katı bir “L3” iddiasını haklı çıkarmaz.
Build İşinin Kendisi#
Build işi tetikleyiciden bağımsızdır. Aynı derle-ve-test mantığı bir push’ta, bir PR’da veya bir release’de çalışabilir; tetikleyici ise bunun ne kadarının çalışacağına ve çalıştırmanın yük altında nasıl davranacağına karar verir. Her kontrolün anlamını değiştirmeden maliyeti şekillendirdiğiniz yer burasıdır.
İki depolama mekanizması karıştırılır ve zıt amaçlara hizmet eder. Bir cache, nadiren değişen girdileri tutar; böylece onları her çalıştırmada yeniden çekmezsiniz. Onu bir lockfile hash’i gibi bir şeyle anahtarlar ve restore-keys ile yakın bir eşleşmeye dönersiniz; ya da bir setup action’ının yönetmesine izin verirsiniz. Varsayılan cache bütçesi repo başına yaklaşık 10 GB’tır ve en az kullanılan önce silinir. Bir artifact ise tutmak veya needs ile sonraki bir işe geçirmek istediğiniz çıktıları tutar; fork için güvenli desenin kanalı budur: güvenilmeyen build yükler, ayrıcalıklı iş indirir.
Eşzamanlılık diğer kaldıraçtır ve iki mod bir arada kullanılmaz. PR’larda cancel-in-progress: true istersiniz; böylece yeni bir push, eski commit üzerinde hâlâ çalışan çalıştırmanın yerine geçer. Deploy’larda ise kuyruk modunu (queue: max, FIFO) istersiniz; bu, iptalle birleşemez çünkü production’a hâlâ dokunan bir deploy’u iptal etmemelisiniz. Matris üçüncü kaldıraçtır: her kombinasyon için bir iş çalıştırır, bu yüzden onu tetikleyiciye göre daraltın. Main ve release’lerde tam matrisi, PR’larda küçültülmüş bir matrisi çalıştırın.
| Konu | Cache | Artifact |
|---|---|---|
| Amaç | Nadiren değişen girdileri yeniden kullan | Çıktıları tut veya geçir |
| Ömür | En az kullanılan silinir | Belirli bir süre saklanır |
| Nasıl paylaşılır | Anahtarla çalıştırmalar arası geri yüklenir | needs ile geçirilir / indirilir |
| Tipik kullanım | Bağımlılıklar, build katmanları | Derlenmiş çıktı, raporlar, fork-güvenli devir |
| Tetikleyici | Eşzamanlılık modu | Neden |
|---|---|---|
pull_request | cancel-in-progress: true | En yeni commit kazanır; runner’ı serbest bırak |
| Deploy işi | queue: max (FIFO) | Devam eden production deploy’unu asla iptal etme |
Kapılar ve En Az Yetkili Token#
Tetikleyiciler işi yönlendirir, ama yönlendirme yalnızca üç mekanizmayla uygulanabilir hale gelir: branch protection veya rulesetler, deployment ortamları ve OIDC ile birlikte kullanılan en az yetkili bir token. Desen şudur: yetki tetikleyiciyle birlikte yükselir; hiçbir şey global olarak verilmez.
Branch protection ve rulesetler, PR bölümünde anlatıldığı gibi bir kontrolü zorunlu yapan şeydir. Deployment ortamları insan kapısını ekler: zorunlu onaylayıcılar (isteğe bağlı bir kuralla kişinin kendi çalıştırmasını onaylaması engellenebilir), bir çalıştırma onay beklerken “Waiting” durumu, onay penceresi geçince otomatik başarısızlık, faturalandırılmayan bir bekleme zamanlayıcısı ve hangi ref’lerin deploy edebileceğini sınırlayan branch veya tag politikaları. Bu, yukarıdaki diyagramda release deploy’unun önünde duran onaydır. Ortam koruma kuralları ile private veya internal repolardaki attestation’lar ücretli planlarla sınırlıdır; public repolarda tüm planlarda mevcuttur.
Token son parçadır. Bir permissions: bloğu bildirmek, listelenmeyen her yetkiyi none’a ayarlar; yazma okumayı kapsar ve güvenli şekil, kısıtlayıcı bir üst seviye blok artı yalnızca bir işin ihtiyacı olduğu yerde iş başına yükseltmedir. OIDC, uzun ömürlü cloud secret’larını tamamen kaldırır: permissions: id-token: write çalıştırma başına bir JWT üretir, cloud’unuz bunu bir kez yapılandırdığınız güven ilişkisine karşı doğrular ve yalnızca o işle sınırlı, süresi kendiliğinden dolan bir kimlik bilgisi döner. Dikkat edin: id-token: write yalnızca JWT’yi isteme yeteneğini verir; herhangi bir kaynağa yazma erişimi vermez.
Warning
GITHUB_TOKEN varsayılanını bir repository veya organizasyon “Workflow permissions” ayarı belirler. 2023-02-02 tarihinde veya sonrasında oluşturulan repolarda varsayılan salt-okunurdur; daha eski repolarda okuma-yazmadır. Bunu denetleyin ve varsayılanı salt-okunur yapın, sonra workflow başına yükseltin. Token’ın zaten salt-okunur olduğunu varsaymayın.
| Tetikleyici | Token kapsamı | Secret / cloud erişimi |
|---|---|---|
push (özellik) | Salt-okunur | Gerekmez |
pull_request (fork) | Salt-okunur (zorunlu) | Yok |
push (main) | Salt-okunur varsayılan, iş başına yükselt | Yalnızca staging |
release: published | contents: read, id-token: write, attestations: write | OIDC ile production, onay arkasında |
En az yetki ve OIDC mekaniği Security Without the Review Queue yazısıyla örtüşür; o yazı kapı-ve-token tarafını derinlemesine ele alır; buradaki odak ise her yetkinin hangi tetikleyiciye ait olduğudur. Client tarafı release açısı için The Client You Cannot Roll Back yazısı, gönderdiğinizi geri çağıramadığınızda release tetikleyicisinin neden ekstra ağırlık taşıdığını anlatır.
Maliyet ile Tetikleyici Arasındaki Sınır#
Üzerinde durulması gereken kısım sınırdır. Yazma yetkilerini global olarak vermeyin, çünkü izin veren bir varsayılan, fork PR’larına ve güvenilmeyen koda yetki sızdırır. Tam matrisi her push’ta çalıştırmayın, çünkü bu dakikaları yakar ve tüm modelin korumayı amaçladığı geri bildirimi yavaşlatır. Sıradaki adım bir denetim: hangi workflow’un hangi olayda çalıştığını ve her birinin hangi token kapsamını tuttuğunu listeleyin, sonra uyumsuz olan her şeyi taşıyın.
Kaynaklar#
- Events that trigger workflows - GitHub Docs (yeni sekmede açılır) - Olay başına referans ve yönlendirme haritasının kaynağı.
- Managing a merge queue - GitHub Docs (yeni sekmede açılır) -
merge_groupolayı, geçicimain/pr-Nbranch’i ve zorunluon: merge_group:bağlantısı. - About protected branches - GitHub Docs (yeni sekmede açılır) - Bir kontrolün nasıl zorunlu durum kontrolü haline geldiği.
- Preventing pwn requests - GitHub Security Lab (yeni sekmede açılır) -
pull_request_targettehlikesi ve güvenli artifact-devir deseni. - Using artifact attestations to establish provenance - GitHub Docs (yeni sekmede açılır) - Provenance izinleri ve
gh attestation verifyile doğrulama. - Artifact Attestations is generally available - GitHub Changelog (yeni sekmede açılır) - Genel kullanıma açılma duyurusu.
- SLSA • Security levels (v1.0) (yeni sekmede açılır) - Build track seviyeleri L1’den L3’e (v1.2’nin güncel spek olduğuna dikkat).
- Managing environments for deployment - GitHub Docs (yeni sekmede açılır) - Zorunlu onaylayıcılar, bekleme zamanlayıcısı ve deploy branch politikaları.
- Security hardening with OpenID Connect - GitHub Docs (yeni sekmede açılır) - OIDC ile kısa ömürlü, tek işle sınırlı cloud kimlik bilgileri.
- Control workflow concurrency - GitHub Docs (yeni sekmede açılır) -
cancel-in-progressvequeue: maxkarşılaştırması. - Authentication in a workflow (GITHUB_TOKEN) - GitHub Docs (yeni sekmede açılır) - İzin semantiği ve en az yetki varsayılanları.
- Dependency caching - GitHub Docs (yeni sekmede açılır) - Cache anahtarları, restore-keys ve repo başına üst sınır.
İlgili yazılar
Yüksek performanslı ekiplerin kod-tamam ile canlı arasındaki süreyi güvenlikten ve kaliteden ödün vermeden nasıl kısalttığı. Teknik liderler için bir karar rehberi.
ci-cd · devops · dora-metrics +2
Yüksek performanslı ekipler güvenlik incelemesini lead-time darboğazına çevirmiyor: shift-left otomasyon, risk-tabanlı kapılar, hazır yol ve bağımlılık ritmi.
ci-cd · devops · security +3
Üretim deploy'ları gerçek bir onay adımı ister: GitHub Environment, native koruma kuralları ve environment'a bağlı secret'lar; if: hilesi ya da marketplace değil.
github-actions · ci-cd · devops +2
Organizasyon düzeyinde paylaşımlı bir GitHub Actions platformu kurma rehberi: mimari kararlar, güvenlik yönetişimi, benimseme ve en maliyetli 7 hata.
github-actions · ci-cd · devops +5
AWS CDK, Lambda ve GitHub Actions kullanarak otomatik preview ortamları oluşturmayı öğrenin - sorunsuz PR test ve inceleme süreçleri için
aws-cdk · serverless · ci-cd +5