GitHub Actions için bir changelog kontrolü
4 dk okuma
Changelog’u elle tutan her ekip aynı olaydan sonra aynı konuşmayı yapmıştır: bir sürüm kayıtsız çıkmıştır, biri neden diye sorar, ve dürüst cevap onu yazacak kişinin hızlı gittiği ve changelog adımının sadece hafızada yaşadığıdır. Changelog otomasyonu bir pipeline’ın güvenle otomatikleştirebileceği ve hâlâ bir kişiye ihtiyaç duyanı ele alır; CI’da bir changelog kontrolü bu sorunun diğer yarısıdır, çünkü yazmayı otomatikleştirmek kimse onu tetiklemekle yükümlü değilse yardımcı olmaz. Çoğu ekip pull request kontrollerini zaten GitHub Actions’ta çalıştırır, bu yüzden bu kontrol de orada yaşar.
“İnsanlardan bir kayıt eklemelerini rica ediyoruz” neden öngörülebilir bir örüntüyle başarısız olur?
Çünkü bir pull request’te her şeyle dikkat için rekabet eder, ve atlamanın anında sonucu olmayan tek parçasıdır. Testler gürültülü başarısız olur ve merge’ü engeller. Eksik bir changelog kaydı hiçbir şeyi engellemez, bu yüzden biri acele ettiği anda kaybeder, ki pratikte bu çoğu zamandır. Hafızayla zorunlu kılınan bir politika beklenecek hızda tam olarak bozulur: herkesin kabul etmesinden sonraki ilk birkaç hafta iyidir, sonra umursayan kişi tatile gidince veya ekip değiştirince sessizce terk edilir.
Bir changelog kaydı için bir CI kontrolü gerçekte neyi doğrular?
Yazının kalitesini değil, sadece bir kaydın var olduğunu ve doğru biçimlendirildiğini, ki bu bir kişinin kafasında değil CI’da çalışan bir changelog kontrolü için doğru kapsamdır. Yaygın bir şekil: kontrol PR’ın diff’ine bakar ve ya bir changeset dizininde yeni bir dosya (Changesets ve benzer araçların kullandığı desen) ya da bir changelog dosyasında değiştirilmiş bir satır ister, ve ikisi de yoksa build’i başarısız kılar. Kaydın gerçekte ne söylediğinin incelemesi hep olduğu yerde olmaya devam eder, code review’da, çünkü o yargı bir script’e ait değildir.
| CI kontrolü neyi doğrular | Neyi doğrulamaz |
|---|---|
| Diff’te bir changeset veya changelog satırı var | İfadenin açık olup olmadığı |
| Kayıt, bir monorepo’da doğru paketi referans alıyor | Değişikliğin gerçekten bir kayıt hak edip etmediği |
| Dosya sözdizimsel olarak geçerli (frontmatter, JSON şekli) | Kaydın etki hakkında dürüst olup olmadığı |
Her PR’ın buna ihtiyacı var mı, yoksa bazı değişiklikler muaf mı?
Bazıları muaftır, ve muafiyet listesi bu sistemlerin gerçekten kurulduğu veya terk edildiği
yerdir. Görünür etkisi olmayan bir bağımlılık güncellemesi, sadece test değişikliği, davranış
değişikliği olmayan dahili bir refactor: hiçbiri bir katkıda bulunanı changelog’u okuyan kimsenin
umursamadığı bir şey için changelog kaydı uydurmaya zorlamamalı. İşe yarayan desen, bir katkıda
bulunanın uygulayabileceği (no-changelog-needed) ve dosyasız CI kontrolünü karşılayan, PR’ı
onaylayan kişi tarafından incelenen bir etiket veya bayraktır, böylece muafiyetin kendisi bir
kaydın geçeceği aynı incelemeden geçer.
Acil bir hotfix gibi meşru istisnalara ne olur?
Gate merge’e aittir, deploy’a değil: gerçek zaman baskısı altındaki bir hotfix, CI kontrolü bitmiş bir paragraf yerine niyetle karşılansa yeter ki, bir yer tutucu kayıt veya takip bileti ile merge edebilir; bazı ekipler bir bakımcının sonraki sürüm kesiminden önce cilalayacağı tek satırlık bir stub kabul eder. Gate’in asla izin vermemesi gereken şey adımı sessizce atlamaktır, çünkü unutulan bir stub hiç var olmamış bir kayıttan daha küçük bir başarısızlıktır, ve bir stub en azından birinin daha sonra bulabileceği bir iz bırakır.
# .github/workflows/changelog-check.yml
on:
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled]
jobs:
changelog:
if: >-
!contains(github.event.pull_request.labels.*.name,
'no-changelog-needed')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # diff için temel dal gerekir
- name: Require changelog entry
run: |
base="origin/${{ github.base_ref }}"
if ! git diff --name-only "$base"...HEAD \
| grep -q '^\.changeset/'; then
echo "No changeset. Add one, or have a maintainer"
echo "apply the no-changelog-needed label."
exit 1
fi
Bu bir monorepo’da aynı şekilde çalışır mı?
Bir parça daha gerektirir: kaydın hangi paket için olduğu. Monorepo changelog’ları tek bir repo çapında dosyanın paketler bağımsız olarak yayınlanmaya başladığında neden çalışmayı bıraktığını ele alır; CI kontrolü aynı gereksinimi devralır; bir paket adlandırmayan bir changeset, doğru changelog’un güncelleneceğine dair yararlı bir kanıt değildir, sadece diff’in bir yerinde bir dosyanın değiştiğinin kanıtıdır. Bunun için kurulmuş araçlar (Changesets JavaScript ekosisteminde yaygın olandır), changeset oluşturulduğu anda katkıda bulunandan etkilenen paketi ve bir semver bump’ını seçmesini ister, böylece CI kontrolü her iki parçayı da sonradan çıkarmak yerine bedava alır.
Kontrolün kendisinin gerçek PR’ları engellemeye başlamadan önce doğru olduğu nereden bilinir?
Önce, kullanıp atacağınız bir dala karşı bir deneme pull request’i açın: biri changeset’li, biri
changeset’siz, ve biri muafiyet etiketini taşıyan, ve kontrol başkasının işine uygulanmadan önce
üçünün de beklediğiniz sonucu aldığını doğrulayın. Bir koşul tersten yazıldığı için her PR’ı
geçiren, fail-open bir changelog kontrolü, hiç kontrol olmamasından daha kötüdür, çünkü var
olmayan bir kapsama gibi görünür. Aynı dosya üzerinde workflow_dispatch, birkaç yakın zamanda
merge edilmiş PR’a karşı elle çalıştırılınca, canlı bir pull request’e hiç ihtiyaç duymadan bu
hataların çoğunu yakalar.
Aynı fikir GitHub Actions dışında da işler mi?
Şekil aynen taşınır, sadece sözdizimi değişir. GitLab CI aynı kuralı bir GitHub Actions if’i
yerine $CI_MERGE_REQUEST_LABELS’ı kontrol eden bir job rules bloğu olarak ifade eder, ve
zorunlu bir merge request onayı muafiyet inceleme adımının yerini alabilir. Bu makalenin tarif
ettiği kontrol GitHub Actions’tır, çünkü onu okuyan çoğu ekip zaten o platformdadır, ama altta
yatan gereksinim, rica edilen bir gelenek değil makine tarafından kontrol edilen bir gate, CI’ın
bir merge’den önce çalıştığı her yerde aynıdır.
FAQ
CI kontrolü merge’ü engellemeli mi, yoksa sadece uyarmalı mı? Engellemeli. Bir uyarı işlevsel olarak nazikçe rica etmekle aynıdır, ki bu zaten başarısız oldu. Muafiyet etiketi tam olarak gerçek bir sadece-uyarı durumunun aynı katı gate’ten yine de meşru bir yolu olması için var.
Bir muafiyet etiketinin doğru uygulanıp uygulanmadığını kim inceler? Pull request’i onaylayan kişi, zaten yaptığı incelemenin bir parçası olarak. Etiket asla kendiliğinden uygulanıp incelenmeden kalmamalı, yoksa gate’in kapatmak için tasarlandığı aynı sessiz kaçamak haline gelir.
Bunu CI’da zorunlu kılmak bir changelog otomasyon pipeline’ına olan ihtiyacın yerini alır mı? Hayır, onu besler. Changelog otomasyonu yapılandırılmış kayıtları bir sayfaya, akışa ve e-postaya dönüştürmeyi ele alır; CI kontrolü bu yapılandırılmış kayıtların ilk etapta otomatikleştirilmek için var olmasını garanti eden şeydir.
Önce inşa etmeye değer bunun en küçük versiyonu nedir? Belirlenmiş bir changelog dizini altında hiçbir dosya değişmediyse başarısız olan, bir muafiyet etiketiyle tek bir kontrol. Paket bazlı yönlendirme ve bir monorepo için semver çıkarımı daha sonra gelebilir; temel alışkanlık, bir kayıt var ya da biri açıkça gerekmediğini söyledi, ilk günden itibaren sahip olmaya değer olandır.
Bu yazıdaki teknik iddialar bağımsız olarak kontrol edilmedi. Yanlış bir şey varsa bize söyle, düzeltelim.