Engineering

Check changelog untuk GitHub Actions

5 menit baca

Setiap tim yang menjaga changelog secara manual pernah mengalami percakapan yang sama setelah insiden yang sama: sebuah rilis keluar tanpa entri, seseorang bertanya kenapa, dan jawaban jujurnya adalah orang yang seharusnya menulisnya sedang bergerak cepat dan langkah changelog itu hanya hidup dalam ingatan. Otomasi changelog membahas apa yang bisa diotomatisasi pipeline dengan aman dan apa yang masih butuh manusia; check changelog di CI adalah separuh lain dari masalah ini, karena mengotomatisasi penulisan tidak membantu jika tidak ada yang wajib memicunya sejak awal. GitHub Actions adalah tempat kebanyakan tim sudah menjalankan check pull request mereka, jadi di situlah check ini hidup juga.

Mengapa “kami minta orang menambahkan entri” gagal dengan pola yang bisa diprediksi?

Karena itu bersaing untuk mendapat perhatian dengan segala hal lain di pull request, dan itu satu-satunya bagian tanpa konsekuensi langsung jika dilewatkan. Test gagal dengan keras dan memblokir merge. Entri changelog yang hilang tidak memblokir apa pun, jadi ia kalah begitu seseorang terburu-buru, yang dalam praktiknya adalah kebanyakan waktu. Kebijakan yang ditegakkan oleh ingatan merosot persis pada kecepatan yang diharapkan: baik-baik saja untuk beberapa minggu pertama setelah semua orang setuju, lalu diam-diam ditinggalkan begitu orang yang peduli pergi berlibur atau pindah tim.

Apa yang sebenarnya diverifikasi check CI untuk entri changelog?

Bukan kualitas tulisannya, hanya bahwa entri itu ada dan berbentuk benar, yang merupakan cakupan tepat untuk check changelog yang berjalan di CI, bukan di kepala seseorang. Bentuk umum: check itu melihat diff PR dan mensyaratkan entah berkas baru di direktori changeset (pola yang digunakan Changesets dan alat serupa) atau baris yang diubah di berkas changelog, dan menggagalkan build jika tidak ada satu pun. Peninjauan tentang apa yang sebenarnya dikatakan entri itu tetap terjadi di tempat yang selalu terjadi, di code review, karena penilaian itu bukan urusan skrip.

Apa yang diverifikasi check CIApa yang tidak diverifikasi
Ada changeset atau baris changelog di diffApakah kalimatnya jelas
Entri merujuk paket yang benar, dalam monorepoApakah perubahan itu benar-benar layak dapat entri
Berkas valid secara sintaksis (front matter, bentuk JSON)Apakah entri jujur tentang dampaknya

Apakah setiap PR butuh itu, atau ada perubahan yang dikecualikan?

Beberapa dikecualikan, dan daftar pengecualian itulah tempat sistem seperti ini benar-benar dibangun atau ditinggalkan. Kenaikan dependency tanpa efek terlihat, perubahan hanya test, refactor internal tanpa perubahan perilaku: tak satu pun dari ini seharusnya memaksa kontributor mengarang entri changelog untuk sesuatu yang tidak dipedulikan siapa pun yang membaca changelog. Pola yang berhasil adalah label atau flag yang bisa diterapkan kontributor (no-changelog-needed) dan memenuhi check CI tanpa berkas, ditinjau oleh siapa pun yang menyetujui PR, sehingga pengecualian itu sendiri melewati pengawasan yang sama seperti entri.

Apa yang terjadi pada pengecualian sah, seperti hotfix mendesak?

Gate itu berada pada merge, bukan pada deploy: hotfix di bawah tekanan waktu nyata bisa merge dengan entri placeholder atau tiket lanjutan, asalkan check CI terpenuhi oleh niat alih-alih hanya paragraf yang selesai; beberapa tim menerima stub satu baris yang dihaluskan maintainer sebelum potongan rilis berikutnya. Yang seharusnya tidak pernah diizinkan gate adalah melewati langkah itu diam-diam, karena stub yang terlupakan adalah kegagalan lebih kecil daripada entri yang tidak pernah ada, dan stub setidaknya meninggalkan jejak yang bisa ditemukan seseorang nanti.

# .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 membutuhkan branch dasar
      - 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

Bagaimana Anda tahu check itu sendiri sudah benar sebelum mulai memblokir PR sungguhan?

Buka dulu pull request percobaan terhadap branch sekali pakai: satu dengan changeset, satu tanpa, dan satu lagi membawa label pengecualian, dan pastikan ketiganya mendapat hasil yang Anda harapkan sebelum check itu berlaku bagi pekerjaan orang lain. Check changelog yang fail open, meloloskan setiap PR karena sebuah kondisi ditulis terbalik, lebih buruk daripada tidak punya check sama sekali, karena itu terlihat seperti cakupan yang sebenarnya tidak ada. workflow_dispatch pada berkas yang sama, dijalankan manual terhadap beberapa PR yang baru-baru ini di-merge, menangkap kebanyakan kesalahan semacam ini tanpa perlu pull request sungguhan sama sekali.

Apakah ide yang sama berlaku di luar GitHub Actions?

Bentuknya tetap sama, hanya sintaksnya yang berubah. GitLab CI mengekspresikan aturan yang sama sebagai blok rules job yang memeriksa $CI_MERGE_REQUEST_LABELS, bukan if ala GitHub Actions, dan persetujuan merge request yang diwajibkan bisa menggantikan langkah peninjauan pengecualian. Check yang dibahas artikel ini memakai GitHub Actions karena itu platform yang sudah dipakai kebanyakan pembacanya, tapi kebutuhan yang mendasarinya, gate yang diperiksa mesin alih-alih konvensi yang sekadar diminta, sama saja di mana pun CI berjalan sebelum merge.

Apakah ini bekerja sama di monorepo?

Butuh satu bagian lagi: paket mana entri itu untuk. Changelog monorepo membahas mengapa satu berkas untuk seluruh repo berhenti bekerja begitu paket dirilis secara independen; check CI mewarisi persyaratan yang sama; changeset yang tidak menyebutkan paket bukan bukti berguna bahwa changelog yang tepat akan diperbarui, hanya bahwa suatu berkas berubah di suatu tempat dalam diff. Alat yang dibangun untuk ini (Changesets adalah yang umum di ekosistem JavaScript) meminta kontributor memilih paket yang terpengaruh dan kenaikan semver pada saat yang sama changeset dibuat, sehingga check CI mendapat kedua bagian itu gratis alih-alih menyimpulkannya belakangan.

FAQ

Haruskah check CI memblokir merge, atau hanya memperingatkan? Memblokir. Peringatan secara fungsional identik dengan meminta dengan sopan, yang justru sudah gagal. Label pengecualian ada tepatnya agar kasus hanya-peringatan yang sah tetap punya jalur sah melalui gate ketat yang sama.

Siapa yang meninjau apakah label pengecualian diterapkan dengan benar? Siapa pun yang menyetujui pull request, sebagai bagian dari peninjauan yang sudah dilakukannya. Label seharusnya tidak pernah diterapkan sendiri tanpa peninjauan, atau ia menjadi jalan pintas diam-diam yang sama yang seharusnya ditutup gate.

Apakah mewajibkan ini di CI menggantikan kebutuhan pipeline otomasi changelog? Tidak, ia memberi makan pipeline itu. Otomasi changelog membahas mengubah entri terstruktur menjadi halaman, feed, dan email; check CI adalah yang menjamin entri terstruktur itu ada untuk diotomatisasi sejak awal.

Apa versi terkecil dari ini yang layak dibangun lebih dulu? Satu check yang gagal jika tidak ada berkas berubah di bawah direktori changelog yang ditentukan, dengan satu label pengecualian. Perutean per paket dan penyimpulan semver untuk monorepo bisa datang belakangan; kebiasaan intinya, entri ada atau seseorang secara eksplisit bilang itu tidak diperlukan, adalah yang layak dimiliki sejak hari pertama.


Klaim teknis dalam artikel ini belum ditinjau secara independen. Jika ada yang keliru, beri tahu kami dan kami akan memperbaikinya.

Terkait di changeloop: Perbandingan alat changelog, Generator changelog

changeloop
Tim di balik changelog yang menutup lingkaran. Pengguna meminta sesuatu, timmu mengirimkannya, yang meminta jadi tahu.