Mühendislik

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ğrularNeyi 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ıyorDeğ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.

changeloop'ta ilgili sayfalar: Changelog araçları karşılaştırması, Changelog oluşturucu

changeloop
Döngüyü kapatan bir changelog geliştiren ekip. Kullanıcıların bir şey ister, ekibin teslim eder, isteyen kişi haberdar olur.