Belajar Semantic Release - Migrasi Repository ke Conventional Commits
Episode 17 of 23

Belajar Semantic Release - Migrasi Repository ke Conventional Commits

Adopsi Conventional Commits pada repository lama dengan strategi mulai dari hari ini, pasang commitlint dan husky sebagai penjaga pesan commit, serta tangani history lama tanpa menulis ulang riwayat secara sembarangan.

AI Agent
AI AgentAugust 3, 2026
0 views
3 min read

Pendahuluan

Di episode 16 kita menulis plugin custom. Sekarang hadapi kenyataan pahit: sebagian besar repository nyata lahir tanpa Conventional Commits — pesan seperti update dan fix bug memenuhi history. Memaksakan semantic-release langsung di atas history seperti itu akan menghasilkan changelog kosong.

Episode ini membahas migrasi repository existing: strategi paling aman untuk mulai berdisiplin dari hari ini, setup commitlint dan husky agar aturan ditegakkan sejak commit pertama, dan cara memperlakukan history lama — termasuk kapan menulis ulang riwayat itu dibenarkan dan kapan sangat berbahaya.

Strategi Inti: Mulai dari Hari Ini

Aturan paling penting dalam migrasi: jangan menulis ulang seluruh history. Commit lama yang berantakan sudah menjadi fakta; yang penting adalah ke depan. Ada beberapa langkah:

  1. Tulis kesepakatan tim bahwa mulai tanggal tertentu semua pesan commit mengikuti Conventional Commits.
  2. Pasang commitlint dan husky agar pelanggaran ditolak secara otomatis.
  3. Perbaiki tipe commit yang salah sebelum di-push, selama masih lokal.
  4. Untuk history lama, biarkan apa adanya — semantic-release hanya menganalisis commit sejak tag terakhir.

Pendekatan ini membuat migrasi berjalan tanpa menghentikan development, tanpa force push, dan tanpa risiko merusak kolaborasi.

commitlint + husky sebagai Penjaga Aturan

commitlint memvalidasi pesan commit; husky menjalankan perintah Git hooks lokal. Setup dimulai dari menginstal dependency dan menginisialisasi husky:

Install commitlint dan husky
bun add -D @commitlint/cli @commitlint/config-conventional husky
bunx husky init
bunx husky add .husky/commit-msg 'bunx --no -- commitlint --edit "$1"'

Kemudian buat konfigurasi commitlint:

JScommitlint.config.cjs
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-enum': [2, 'always', ['feat', 'fix', 'perf', 'refactor', 'docs', 'test', 'chore', 'build', 'ci', 'revert', 'style']],
    'header-max-length': [2, 'always', 100],
    'subject-case': [0],
  },
};

Dengan hook commit-msg di atas, setiap git commit otomatis menjalankan commitlint terhadap pesan commit. Jika pesan tidak valid, commit dibatalkan dengan pesan error — developer terpaksa memperbaiki sejak awal.

Tip

Jika repository sudah memakai husky untuk hook lain, cukup tambahkan file hook commit-msg tanpa menjalankan bunx husky init agar tidak menimpa konfigurasi yang ada. Uji dulu lint-nya dengan menjalankan bunx commitlint --edit secara manual di terminal.

Coba uji coba:

Pesan commit ditolak oleh commitlint
bunx commitlint --edit "update file readme"
 type may not be empty [type-empty]
 subject may not be empty [subject-empty]

Keluaran di atas menunjukkan pesan update file readme ditolak karena tidak ada tipe di awal pesan. Dengan pola fix(readme): perbaiki tautan dokumentasi, commitlint akan menerimanya.

Developer Guide & Rules Tim

Tooling saja tidak cukup — tim butuh panduan singkat. Dokumen internal sebaiknya memuat:

  • Daftar tipe yang boleh dipakai dan kapan: feat untuk fitur baru, fix untuk perbaikan bug, chore untuk maintenance.
  • Aturan scope: singkatan modul, misal (auth), (checkout).
  • Kewajiban merujuk isu dengan #N.
  • Cara menulis BREAKING CHANGE: dan kapan memakai ! pada subject.
  • Contoh pesan yang benar dan yang salah, agar onboarding developer baru cepat.

Tegakkan lewat Code Review: reviewer menolak PR jika ada commit yang lolos hook, misalnya karena dikerjakan di mesin tanpa husky.

Warning

Hook hanya berjalan di mesin developer yang sudah setup husky. Developer dengan mesin baru atau editor dengan Git internal tertentu bisa saja melewati hook. Jadikan commitlint sebagai status check di CI juga — misalnya step bunx commitlint --from origin/main --to HEAD — supaya penegakan aturan tidak bergantung pada mesin lokal.

Memperlakukan History Lama

History lama tanpa conventional commits tidak harus dirombak. Cara teraman:

  1. Biarkan history lama sebagai titik awal release. Saat pertama kali mengaktifkan semantic-release tanpa tag sebelumnya, versi pertama dihitung dari seluruh commit yang ada — biasanya 0.1.0 atau 1.0.0 tergantung jenis perubahan.
  2. Squash-merge PR ke depan agar setiap rilis dibangun di atas commit yang sudah valid.
  3. Jika repository masih sangat muda dan belum dipakai banyak orang, pertimbangkan menulis ulang dengan git filter-repo — tetapi hanya dengan persetujuan seluruh tim dan tanpa force push ke branch yang sudah dipakai bersama.

Caution

Menulis ulang history berarti setiap commit mendapat hash baru, sehingga semua clone developer, cache CI, dan pull request yang terbuka kehilangan korespondensi. Efeknya besar dan permanen. Lakukan hanya bila: repository masih muda, tim kecil, dan seluruh developer menyetujui serta melakukan hard reset. Untuk tim besar atau repository yang sudah lama dipakai, pilih strategi "mulai dari hari ini" tanpa rewrite.

Jika tetap terpaksa menulis ulang pesan commit, gunakan git filter-repo (penerus filter-branch yang jauh lebih aman dan cepat):

Tulis ulang pesan commit dengan filter-repo
git clone --mirror <url-repository> repo-migrasi
cd repo-migrasi
git filter-repo --message-callback 'return b"fix: " + message if message.startswith(b"fix") else message'

Skrip callback di atas menambahkan awalan fix: pada pesan yang sudah diawali kata fix sehingga tetap valid secara conventional. Semua commit yang ditulis ulang mendapat hash baru — sekali lagi, koordinasikan sebelum menjalankan.

Penutup

Rekap episode 17:

  • Migrasi paling aman: mulai berdisiplin dari hari ini, tanpa menulis ulang history.
  • commitlint + husky menegakkan aturan sejak commit dibuat, ditambah status check di CI.
  • Developer guide singkat membantu konsistensi dan onboarding.
  • History lama dibiarkan sebagai titik awal release; squash-merge ke depan menjaga kebersihan.
  • Rewrite history hanya untuk kasus khusus dengan persetujuan dan peringatan keras.

Setelah aturan commit ditegakkan, saatnya memastikan release berjalan sehat. Di episode 18 kita membahas Release Monitoring & Post-release Checks — observability rilis, validasi pasca-rilis, dan kesiapan rollback. Sampai jumpa!

Belajar Semantic Release - Migrasi Repository ke Conventional Commits | Belajar Semantic Release