Semantic versioning dan changelog Anda
5 menit baca
Semantic versioning memberi tahu pemanggil seberapa sakit sebuah rilis bisa dirasakannya sebelum
membaca satu entri changelog pun. Naik dari 2.4.1 ke 2.5.0 berarti: kapabilitas baru, tak ada
yang rusak. Naik dari 2.5.0 ke 3.0.0 berarti: baca entri ini sebelum update. Changelog dan
nomor versi seharusnya menyatakan hal yang sama dalam dua format, dan sebagian besar friksi
antara keduanya muncul justru saat keduanya tak sepakat, yang lebih sering terjadi dari yang
disarankan spesifikasinya.
Apa sebenarnya yang dijanjikan tiap angka dalam sebuah versi?
Semantic versioning mendefinisikan tiga angka, MAJOR.MINOR.PATCH,
masing-masing dengan aturan ketat tentang apa yang memicunya. Lompatan MAJOR berarti perubahan
yang tak kompatibel: sesuatu yang bisa disadari integrasi yang benar dan sudah ada, dan karenanya
harus berubah. Lompatan MINOR berarti fungsionalitas baru yang kompatibel ke belakang: tak ada
yang lama rusak, sesuatu yang baru tersedia. Lompatan PATCH berarti perbaikan yang kompatibel ke
belakang: perilaku menjadi lebih dekat dengan yang didokumentasikan, dan siapa pun yang sengaja
bergantung pada perilaku lama seharusnya tak menyadari apa pun.
| Lompatan | Arti | Entri seharusnya terbaca seperti |
|---|---|---|
MAJOR (1.x.x -> 2.0.0) | Perubahan tak kompatibel | “Perlu tindakan sebelum update” |
MINOR (1.2.x -> 1.3.0) | Kapabilitas baru yang kompatibel | “Tersedia sekarang, tak ada lagi yang berubah” |
PATCH (1.2.3 -> 1.2.4) | Perbaikan yang kompatibel | “Sekarang berperilaku sesuai dokumentasi” |
Tabel ini juga uji terbalik: jika sebuah entri tak terbaca seperti barisnya, entah nomor versinya salah, atau entri itu terlalu kecil atau terlalu besar dalam menjual apa yang sebenarnya terjadi.
Apa yang dihitung sebagai tak kompatibel untuk tujuan versioning?
Uji yang sama yang menentukan apakah sesuatu termasuk dalam changelog API: apakah pemanggil yang benar, ditulis melawan perilaku lama dan tak tersentuh sejak itu, bisa berperilaku berbeda karena perubahan ini. Apa itu perubahan tak kompatibel, dan cara merilisnya membahas keputusan itu secara lengkap, termasuk kasus yang terlihat tak kompatibel padahal bukan, dan yang terlihat kecil padahal bukan. Singkatnya untuk tujuan versioning: jika jawabannya ya, lompatannya MAJOR terlepas dari berapa banyak kode yang sebenarnya disentuh perubahan itu secara internal. Nomor versi mengikuti konsekuensi bagi pemanggil, bukan usaha tim.
Bagaimana seharusnya entri changelog cocok dengan lompatan versi?
Satu entri, satu kategori lompatan, dinyatakan sejak awal. Pola dari tabel berlanjut langsung: entri tak kompatibel berada di bawah versi yang memperkenalkannya, diformulasikan dulu sebagai peringatan lalu sebagai deskripsi. Entri aditif berada di bawah versi MINOR-nya, diformulasikan sebagai ketersediaan. Perbaikan berada di bawah versi PATCH-nya, diformulasikan sebagai koreksi. Mencampur kategori dalam satu entri, seperti melipat perubahan tak kompatibel ke paragraf yang sama dengan perbaikan yang tak berhubungan, adalah cara pembaca melewatkan justru satu hal yang paling penting.
## 3.0.0 (2026-09-07)
### Changed
- **BREAKING:** `GET /reports` sekarang mengembalikan jumlah sebagai
integer dalam satuan mata uang terkecil (sen) alih-alih desimal.
Perbarui kode yang membaca `amount` secara langsung.
## 2.9.0 (2026-09-01)
### Added
- Laporan sekarang bisa difilter berdasarkan `status`.
## 2.8.4 (2026-08-28)
### Fixed
- `GET /reports?status=` mengembalikan halaman kosong alih-alih 400
untuk status yang tidak dikenal.
Dibaca dari atas ke bawah, nomor versi dan label bagian mengatakan hal yang sama dua kali, dan itulah tujuannya: pembaca yang hanya memindai judul mendapat pembacaan risiko yang benar sebelum membuka satu baris pun.
Apakah aturan breaking change berlaku sama sebelum 1.0.0?
Tidak, dan di sinilah sebagian besar kebingungan tentang “apakah itu sungguh breaking” berasal.
SemVer eksplisit menyatakan versi mayor nol, 0.y.z, untuk pengembangan awal: apa pun bisa berubah
kapan saja, dan API publik tidak boleh dianggap stabil. Lompatan 0.4.0 ke 0.5.0 bisa membawa
breaking change tanpa melanggar spec, karena jaminan versi mayor baru berlaku begitu proyek
merilis 1.0.0. Entri changelog tetap berutang kejujuran yang sama tentang apa yang rusak; yang
berubah hanyalah nomor versi itu sendiri bukan sinyal yang bisa diandalkan sebelum 1.0.0 tiba.
Bagaimana jika produk Anda tak merilis versi diskrit?
Kebanyakan produk SaaS melakukan deploy berkelanjutan dan tak pernah menampilkan nomor versi ke pemanggil, yang tak menghilangkan kebutuhan akan disiplin ini, hanya angka yang biasanya membawanya. Entri changelog harus melakukan semua pekerjaan sendiri: menyatakan dengan jelas apakah perubahan itu tak kompatibel, aditif, atau perbaikan, dengan tiga kata yang sama yang dipakai semantic versioning, bahkan tanpa kolom versi untuk menempelkannya. Beberapa tim menjaga versi yang murni internal hanya untuk menjangkarkan entri changelog ke sesuatu yang bisa ditautkan, tanpa pernah menunjukkannya langsung ke pemanggil.
Bagaimana ini berlaku khusus untuk changelog API?
Lebih ketat daripada hampir di mana pun, karena pemanggil API adalah kode, bukan orang yang bisa
mengangkat bahu menghadapi perubahan tak terduga. Changelog API: apa yang dipublikasikan dan siapa yang membacanya
membahas bentuk lengkap dokumen itu; disiplin versioning di sini adalah yang menjaga kejujuran
bagian breaking dan aditifnya. API yang menawarkan beberapa versi sekaligus, seperti v1 dan
v2 disajikan bersamaan selama jendela migrasi, secara efektif menerapkan semantic versioning
pada skala seluruh antarmuka alih-alih satu paket, dan kosakata tiga kata yang sama masih
berlaku untuk setiap entri.
Apa yang dikatakan Keep a Changelog tentang versioning?
Ia terhubung langsung dengan nama ke semantic versioning dan merekomendasikan kosakata kategori yang sama yang dipakai artikel ini: Added, Changed, Deprecated, Removed, Fixed, Security. Keep a Changelog, dalam praktik membahas cara mengadopsi spesifikasi itu, termasuk di mana tim biasanya menyimpang. Tumpang tindihnya bukan kebetulan: kedua spesifikasi mencoba memecahkan masalah yang sama dari ujung yang berlawanan, satu menstandarkan nomor versi dan yang lain entri yang menjelaskannya.
FAQ
Apakah setiap entri changelog butuh nomor versi? Jika produk merilis versi, ya, karena angka itu memungkinkan pembaca langsung melompat ke “seberapa ini memengaruhi saya” tanpa membaca entrinya dulu. Jika produk deploy berkelanjutan tanpa kolom versi, formulasi entri harus membawa sinyal itu sendiri.
Apa bedanya lompatan MAJOR dengan entri perubahan tak kompatibel? Keduanya seharusnya peristiwa yang sama dijelaskan dengan dua cara. Nomor versi adalah sinyal yang bisa dibaca mesin (tooling pemanggil bisa bereaksi terhadapnya); entri changelog adalah penjelasan yang bisa dibaca manusia tentang apa yang berubah secara konkret.
Bisakah rilis PATCH bersifat tak kompatibel? Secara definisi seharusnya tidak. Jika ternyata tetap dirilis, jangan edit atau beri tag ulang versi yang sudah dipublikasikan: SemVer FAQ menyarankan merilis versi baru yang memulihkan kompatibilitas, atau MAJOR baru jika kerusakannya tetap ada, dan mendokumentasikan versi bermasalah itu agar pengguna tahu harus melewatinya.
Apakah perubahan yang murni internal butuh lompatan versi? Tidak. Semantic versioning mengikuti antarmuka publik. Refactor tanpa efek yang bisa diamati bagi pemanggil tak butuh lompatan atau entri changelog, meskipun secara internal itu pekerjaan engineering yang signifikan.
Klaim teknis dalam artikel ini belum ditinjau secara independen. Jika ada yang keliru, beri tahu kami dan kami akan memperbaikinya.