Commitizen dan Changesets bisa dipakai bersama untuk menyelesaikan tiga masalah yang sering muncul di tim: format commit tidak konsisten, changelog manual mudah salah, dan versi package sering tidak sinkron saat rilis. Pendekatannya sederhana: Commitizen membantu developer menulis commit yang terstruktur, sementara Changesets mengelola perubahan yang layak dirilis, menentukan bump versi sesuai semver, dan menghasilkan changelog secara lebih aman.

Artikel ini fokus pada implementasi praktis. Bukan sekadar mengenalkan tool, tetapi menjelaskan bagaimana keduanya saling melengkapi dari alur kerja lokal, review pull request, hingga publish terkontrol di CI. Pendekatan ini cocok untuk package tunggal maupun monorepo, terutama jika tim ingin release yang lebih dapat diprediksi tanpa bergantung pada catatan manual.

Masalah Nyata yang Ingin Diselesaikan

Sebelum membahas setup, penting memahami kenapa dua tool ini sering dipakai bersama.

1. Pesan commit tidak konsisten

Tanpa standar, isi commit bisa terlalu umum seperti fix bug, update, atau wip. Dampaknya bukan hanya soal kerapian riwayat Git. Tim jadi sulit menelusuri perubahan, memfilter jenis perubahan, atau membuat otomasi berbasis commit.

2. Changelog manual rawan salah

Jika changelog ditulis manual menjelang release, biasanya ada perubahan yang terlewat, deskripsi kurang jelas, atau urutan perubahan tidak konsisten. Di monorepo, masalahnya lebih besar karena perubahan perlu dipetakan ke package yang tepat.

3. Versi package sering tidak sinkron

Pada project dengan lebih dari satu package, versi bisa mudah melompat, tertinggal, atau tidak selaras dengan dependency internal. Kesalahan ini sering muncul saat beberapa pull request digabung berdekatan atau saat release dilakukan terburu-buru.

Peran Commitizen dan Changesets

Commitizen: merapikan input dari developer

Commitizen membantu developer membuat pesan commit melalui prompt interaktif. Biasanya formatnya mengikuti gaya seperti Conventional Commits, misalnya:

feat(auth): tambah dukungan refresh token
fix(api): perbaiki validasi header authorization
chore(ci): rapikan workflow publish

Keuntungannya:

  • Format commit lebih konsisten antar anggota tim.
  • Riwayat perubahan lebih mudah dibaca.
  • Validasi commit bisa ditegakkan di hook atau CI.

Namun perlu dicatat: Commitizen tidak menggantikan Changesets. Commit yang rapi tidak otomatis cukup untuk menentukan package mana yang harus naik versi, apalagi di monorepo.

Changesets: sumber kebenaran untuk release

Changesets bekerja dengan membuat file metadata perubahan, biasanya di direktori .changeset/. File ini berisi:

  • package mana yang terdampak,
  • jenis bump semver: patch, minor, atau major,
  • ringkasan perubahan yang layak masuk changelog.

Saat waktunya release, Changesets dapat:

  • menghitung versi baru,
  • menyesuaikan dependency internal jika perlu,
  • menghasilkan changelog,
  • menyiapkan commit release yang konsisten.

Inilah alasan kombinasi keduanya kuat: Commitizen menertibkan histori kerja, Changesets menertibkan artefak rilis.

Alur Kerja yang Direkomendasikan

Alur berikut cocok untuk tim yang ingin memisahkan aktivitas coding dari aktivitas release.

  1. Developer membuat perubahan kode.
  2. Developer menulis commit dengan Commitizen.
  3. Jika perubahan memengaruhi perilaku package yang dirilis, developer membuat changeset.
  4. Pull request direview, termasuk validasi format commit dan keberadaan changeset bila diperlukan.
  5. Setelah merge ke branch utama, CI membuat atau memperbarui pull request release berdasarkan changeset yang terkumpul.
  6. Saat release disetujui, CI menjalankan versioning, generate changelog, dan publish.

Pemisahan ini penting karena commit tidak selalu setara dengan unit release. Satu fitur bisa terdiri dari beberapa commit, tetapi cukup satu changeset. Sebaliknya, beberapa commit kecil tetap bisa digabung dalam satu deskripsi release yang bersih.

Contoh Struktur Repository

Untuk monorepo JavaScript/TypeScript misalnya, struktur sederhananya bisa seperti ini:

repo/
├─ .changeset/
│  ├─ config.json
│  └─ calm-birds-sing.md
├─ .github/
│  └─ workflows/
│     ├─ ci.yml
│     └─ release.yml
├─ packages/
│  ├─ ui/
│  │  └─ package.json
│  └─ utils/
│     └─ package.json
├─ package.json
└─ pnpm-workspace.yaml

Untuk single package, strukturnya lebih sederhana, tetapi prinsipnya sama: ada direktori .changeset, konfigurasi commit, dan pipeline CI yang memisahkan validasi dari publish.

Setup Dasar Commitizen

Tujuan setup awal adalah membuat developer terbiasa melakukan commit lewat prompt, bukan mengetik pesan bebas.

Instalasi dan konfigurasi dasar

Pada project Node.js, Commitizen umumnya dipasang sebagai dependency pengembangan. Konfigurasinya bisa diletakkan di package.json atau file konfigurasi terpisah, tergantung adapter yang dipakai.

{
  "scripts": {
    "commit": "cz"
  },
  "config": {
    "commitizen": {
      "path": "cz-conventional-changelog"
    }
  }
}

Dengan ini, developer dapat menjalankan:

npm run commit

Prompt akan menanyakan tipe perubahan, scope, dan deskripsi singkat. Jika tim ingin standar yang lebih ketat, gunakan validasi commit melalui commitlint atau pemeriksaan serupa di hook dan CI.

Validasi commit sebagai guardrail

Masalah umum pada Commitizen adalah tidak semua orang akan selalu menjalankan npm run commit. Karena itu, prompt interaktif sebaiknya dianggap sebagai helper, bukan satu-satunya pengaman.

Tambahkan validasi agar commit yang tidak sesuai format ditolak, minimal pada:

  • hook lokal, agar feedback cepat,
  • CI pull request, agar aturan tetap berlaku meski hook dilewati.

Secara konseptual, alurnya seperti ini:

  • developer commit lewat Commitizen,
  • hook memeriksa pola commit,
  • CI memeriksa ulang commit dalam PR.

Ini penting karena hook lokal bisa dinonaktifkan, tetapi CI menjadi sumber validasi terakhir.

Catatan: jangan jadikan format commit sebagai satu-satunya indikator semver. Commit feat tidak selalu berarti package harus minor. Penentuan versi rilis tetap lebih aman dilakukan oleh changeset.

Setup Dasar Changesets

Inisialisasi

Setelah Changesets diinisialisasi, akan ada direktori .changeset/ yang berisi konfigurasi dan file-file perubahan. Saat developer selesai mengerjakan perubahan yang perlu dirilis, jalankan perintah pembuatan changeset lalu pilih package yang terdampak dan tipe bump versinya.

Contoh isi file changeset:

---
"@acme/ui": minor
"@acme/utils": patch
---

Menambahkan komponen Button dengan varian baru dan memperbaiki helper formatting tanggal.

Bagian atas menentukan dampak versi per package. Bagian bawah adalah ringkasan yang nantinya berguna untuk changelog dan review.

Kapan harus membuat changeset?

Aturan praktis yang paling aman:

  • Buat changeset jika perubahan memengaruhi kode yang akan dirilis ke pengguna package.
  • Tidak perlu changeset untuk perubahan internal murni, seperti refactor tanpa dampak publik, pembaruan CI, atau perbaikan dokumentasi, kecuali tim memang ingin melacaknya dalam release.

Supaya tidak membingungkan, tim sebaiknya menulis kebijakan sederhana di CONTRIBUTING.md.

Membedakan patch, minor, dan major

Kesalahan umum bukan pada tool, tetapi pada interpretasi semver.

  • patch: perbaikan bug atau perubahan aman yang tidak mengubah kontrak publik.
  • minor: penambahan fitur yang kompatibel ke belakang.
  • major: perubahan yang memutus kompatibilitas.

Jika ragu antara patch dan minor, lihat dari sudut pandang konsumen package, bukan dari besarnya pekerjaan. Perubahan kecil sekalipun bisa menjadi major jika memaksa pengguna mengubah kode mereka.

Menggabungkan Keduanya dalam Alur Harian

Alur lokal developer

  1. Kerjakan perubahan kode.
  2. Jalankan test dan lint.
  3. Buat commit dengan Commitizen.
  4. Jika perubahan perlu dirilis, buat changeset.
  5. Masukkan file changeset ke commit atau commit terpisah.

Beberapa tim lebih suka changeset dibuat dalam commit terpisah agar review lebih jelas. Yang penting, file changeset ikut masuk pull request yang sama dengan perubahan kodenya.

Review pull request

Saat review, periksa tiga hal:

  • apakah commit cukup rapi untuk ditelusuri,
  • apakah changeset ada jika memang perlu release,
  • apakah bump semver sesuai dampak perubahan.

Ini membantu mencegah dua masalah yang sering lolos review: fitur besar ditandai sebagai patch, atau bugfix pada package penting tidak disertai changeset sama sekali.

Versioning dan generate changelog

Setelah beberapa PR masuk ke branch utama, Changesets dapat dijalankan untuk:

  • menaikkan versi package berdasarkan changeset yang terkumpul,
  • memperbarui file changelog,
  • menyesuaikan dependency internal di monorepo,
  • menghapus changeset yang sudah diproses.

Biasanya proses ini menghasilkan commit release yang berisi perubahan versi dan changelog. Commit ini sebaiknya dibuat secara otomatis di CI atau melalui release PR, bukan secara manual oleh developer biasa.

Contoh Konfigurasi Dasar

Script yang berguna di package.json

{
  "scripts": {
    "commit": "cz",
    "changeset": "changeset",
    "version-packages": "changeset version",
    "release": "changeset publish"
  }
}

Nama script bisa berbeda, tetapi pemisahannya sebaiknya jelas:

  • commit untuk membantu penulisan commit,
  • changeset untuk membuat metadata release,
  • version-packages untuk menghitung versi dan changelog,
  • release untuk publish.

Contoh konfigurasi Changesets

{
  "$schema": "https://unpkg.com/@changesets/config/schema.json",
  "changelog": true,
  "commit": false,
  "access": "restricted",
  "baseBranch": "main",
  "updateInternalDependencies": "patch",
  "ignore": []
}

Makna umumnya:

  • baseBranch menentukan branch utama yang dijadikan acuan.
  • updateInternalDependencies membantu sinkronisasi dependency internal saat versi package berubah.
  • access relevan saat publish package ke registry.

Nilai detail dapat disesuaikan dengan kebutuhan repository. Jika tidak yakin, lebih baik mulai dari konfigurasi default yang sederhana daripada terlalu banyak kustomisasi sejak awal.

Integrasi CI dan GitHub Actions secara Konseptual

Workflow CI sebaiknya dibagi minimal menjadi dua jalur: validasi dan release.

1. Workflow validasi pull request

Tujuannya memastikan kualitas sebelum merge:

  • install dependency,
  • jalankan lint dan test,
  • validasi format commit bila diperlukan,
  • cek apakah PR yang mengubah package publik memiliki changeset.

Pemeriksaan changeset bisa dibuat ketat atau longgar. Untuk tim kecil, cukup beri aturan bahwa perubahan pada direktori package harus menyertakan changeset, kecuali diberi label khusus seperti no-release.

2. Workflow release di branch utama

Setelah merge ke main, CI dapat menjalankan langkah berikut:

  1. mendeteksi changeset yang belum diproses,
  2. membuat atau memperbarui release PR berisi bump versi dan changelog,
  3. setelah PR release digabung, menjalankan publish ke registry,
  4. membuat tag Git yang sesuai.

Pola release PR lebih aman daripada publish langsung setiap merge, karena memberi titik kontrol tambahan. Tim bisa meninjau changelog dan versi yang akan dirilis sebelum benar-benar dipublikasikan.

Praktik yang aman: gunakan token publish yang hanya tersedia pada workflow release, bukan pada semua workflow CI. Ini mengurangi risiko package terpublikasi dari pipeline yang tidak semestinya.

Strategi Branch dan Guardrail agar Release Tidak Dobel

Pilih satu branch rilis utama

Untuk kebanyakan tim, gunakan satu branch utama seperti main sebagai sumber release. Hindari menjalankan publish dari beberapa branch kecuali memang punya strategi release channel yang jelas, misalnya stable dan next.

Gunakan release PR sebagai titik sinkronisasi

Release PR membantu mencegah:

  • release dobel, karena hanya satu PR release yang aktif pada satu waktu,
  • lompat versi, karena perhitungan dilakukan dari changeset yang belum diproses,
  • changelog kacau, karena semua perubahan release digabung secara terstruktur.

Jangan publish dari laptop developer

Ini guardrail sederhana tetapi sering diabaikan. Publish manual dari lokal berisiko karena:

  • state dependency lokal bisa berbeda dari CI,
  • tag Git bisa tertinggal,
  • versi lokal mungkin belum sinkron dengan branch utama terbaru.

Lebih aman jika publish hanya bisa dilakukan dari CI setelah release PR disetujui.

Hindari dua sumber kebenaran versi

Jika memakai Changesets, jangan campur dengan proses version bump manual yang bebas. Misalnya, hindari kebiasaan:

  • mengubah package.json versi secara manual di feature branch,
  • menulis changelog manual untuk package yang sama,
  • menjalankan tool release lain yang juga menaikkan versi.

Satu sumber kebenaran akan mengurangi konflik merge dan anomali versi.

Kesalahan Umum dan Cara Debug

Commit sudah rapi, tapi release tetap salah

Penyebabnya biasanya karena tim mengandalkan commit sebagai penentu rilis. Solusinya: pastikan setiap perubahan yang layak dirilis punya changeset yang benar. Commit bagus membantu audit, tetapi bukan metadata release yang cukup.

Changeset ada, tetapi package tidak ikut naik versi

Periksa:

  • nama package di file changeset apakah cocok dengan nama di package.json,
  • package tersebut tidak masuk daftar ignore,
  • workflow versioning benar-benar berjalan pada branch yang sesuai.

Dependency internal monorepo tidak ikut sinkron

Biasanya terkait konfigurasi pembaruan dependency internal atau pola dependensi antarpaket. Pastikan hubungan antarpackage memang dideklarasikan dengan benar, lalu tinjau kebijakan update dependency internal yang dipakai oleh Changesets.

Release PR terus berubah atau konflik

Ini sering terjadi jika banyak PR masuk berurutan. Biasanya bukan bug, melainkan konsekuensi normal karena changeset baru terus terkumpul. Kurangi noise dengan:

  • menjaga release PR dibuat oleh satu workflow saja,
  • menghindari edit manual pada isi release PR,
  • merilis lebih sering agar batch perubahan tidak terlalu besar.

Trade-off dan Kapan Setup Ini Cocok

Kelebihan

  • Pesan commit lebih konsisten dan mudah dicari.
  • Penentuan semver lebih eksplisit dan dapat direview.
  • Changelog tidak bergantung pada ingatan manual.
  • Monorepo lebih mudah dikelola karena perubahan per package terdokumentasi.
  • Release lebih aman karena bisa dikontrol lewat CI dan release PR.

Kekurangan

  • Developer harus belajar dua kebiasaan baru: commit terstruktur dan membuat changeset.
  • Pull request bertambah satu file kecil yang kadang dianggap beban administratif.
  • Jika aturan terlalu ketat sejak awal, tim bisa merasa proses rilis menjadi lambat.

Cocok untuk siapa?

Setup ini cocok jika:

  • tim sering merilis package internal atau publik,
  • repository memiliki lebih dari satu package,
  • riwayat perubahan perlu mudah diaudit,
  • versi dan changelog selama ini sering tidak akurat.

Mungkin belum perlu jika project sangat kecil, jarang dirilis, dan hanya dikelola satu orang. Dalam kondisi itu, Changesets saja kadang sudah cukup, sementara Commitizen bisa ditambahkan nanti saat kolaborasi bertambah.

Checklist Adopsi Bertahap

Untuk tim kecil atau single package

  1. Terapkan Commitizen agar format commit mulai konsisten.
  2. Tambahkan validasi commit di CI.
  3. Inisialisasi Changesets.
  4. Wajibkan changeset hanya untuk perubahan yang memengaruhi release.
  5. Gunakan release PR sebelum publish otomatis penuh.

Untuk monorepo

  1. Petakan package yang benar-benar dirilis dan yang hanya internal.
  2. Tetapkan aturan kapan sebuah perubahan wajib punya changeset.
  3. Pastikan dependency internal antarpackage tertulis jelas.
  4. Aktifkan workflow release terpusat di branch utama.
  5. Larangan publish manual dari lokal.
  6. Dokumentasikan aturan semver dengan contoh nyata per package.

Checklist guardrail minimum

  • Commit terformat dan tervalidasi.
  • Changeset wajib untuk perubahan yang dirilis.
  • Satu branch utama untuk release.
  • Satu workflow release resmi.
  • Publish hanya dari CI.
  • Tidak ada version bump manual di feature branch.

Penutup

Commitizen dan Changesets untuk release semver yang konsisten bekerja paling baik jika diposisikan sesuai perannya. Commitizen merapikan cara tim mencatat pekerjaan. Changesets merapikan cara tim mengubah versi, menyusun changelog, dan menerbitkan package. Kombinasi ini bukan sekadar otomasi, tetapi cara membangun disiplin release yang bisa direview, diaudit, dan dijalankan berulang tanpa banyak kejutan.

Jika ingin mulai tanpa mengganggu ritme tim, adopsi bertahap lebih efektif daripada langsung membuat pipeline release yang kompleks. Mulailah dari format commit dan changeset pada pull request, lalu lanjutkan ke release PR dan publish terkontrol di CI. Dengan begitu, tim mendapat manfaat nyata tanpa menambah beban proses secara berlebihan.