Belajar Semantic Release - Commit Analyzer & Release Rules
Episode 8 of 23

Belajar Semantic Release - Commit Analyzer & Release Rules

Membongkar commit analyzer, otak semantic-release yang mengubah setiap pesan commit menjadi keputusan versi. Termasuk pemetaan default preset angular, kustomisasi release rules dan parserOpts, serta urutan evaluasi aturan yang menentukan hasil akhir.

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

Pendahuluan

Di episode 3 kita mengenal format Conventional Commits seperti feat(scope): subject. Di episode 7 kita melihat bagaimana branch main dan staging menghasilkan versi berbeda. Penghubung keduanya adalah commit analyzer: komponen yang membaca pesan commit dan memutuskan apakah versi naik major, minor, patch, atau tidak sama sekali.

Kenapa commit docs(readme): perbaiki typo tidak boleh menaikkan versi? Kenapa tim lain justru ingin chore(deps) memicu patch? Episode ini menjawab keduanya — bagaimana aturan default bekerja dan bagaimana menyesuaikannya.

Pembahasan Utama

Posisi Commit Analyzer dalam Pipeline

semantic-release menjalankan plugin dalam urutan pipeline: verifyConditions, analyzeCommits, verifyRelease, generateNotes, prepare, publish, dan fail. Commit analyzer bekerja di tahap analyzeCommits: ia mengambil seluruh commit sejak tag terakhir, menguji satu per satu, lalu mengembalikan satu release type.

Hasil akhirnya adalah level perubahan tertinggi yang ditemukan. Satu feat di antara banyak fix berarti rilis minor, bukan patch.

Aturan Default: Preset Angular

Tanpa konfigurasi apa pun, semantic-release memakai preset angular dengan pemetaan berikut:

Commit typeRelease typeContoh hasil
featminor1.2.0 -> 1.3.0
fixpatch1.2.0 -> 1.2.1
perfpatch1.2.0 -> 1.2.1
revertpatch1.2.0 -> 1.2.1
breaking changemajor1.2.0 -> 2.0.0
docs, style, test, chore, build, citidak adatidak dirilis

Breaking change terdeteksi dari footer BREAKING CHANGE: atau tanda seru pada subject seperti feat!: hapus dukungan Node 16. Tanpa aturan khusus, tipe seperti docs dan chore dianggap tidak layak rilis.

Kenapa Perlu Kustomisasi

Aturan default bersifat konservatif: hanya feat dan fix yang memicu rilis. Padahal banyak tim ingin perbaikan kecil ikut dirilis:

  • build(deps): update esbuild — memperbarui tooling build sering berarti memperbaiki bug atau celah keamanan.
  • chore(deps): bump lodash — kenaikan versi dependensi juga bisa bersifat patch.

Sebaliknya, sebagian tim ingin docs tetap tidak memicu rilis agar changelog tidak penuh noise. Di sinilah releaseRules berperan: aturan custom kalian dievaluasi lebih dulu dan menimpa preset.

Urutan Evaluasi: First Match Wins

Aturan di releaseRules dievaluasi berurutan dari atas ke bawah, dan aturan pertama yang cocok langsung menentukan hasil. Taruh aturan paling spesifik lebih dulu — misalnya breaking: true harus berada di atas agar commit bertanda breaking selalu jadi major, apa pun tipenya.

parserOpts: Mengontrol Cara Commit Dibaca

Sebelum aturan diterapkan, commit dipecah dulu oleh parser. Dengan parserOpts kalian bisa menyesuaikan kata kunci note dan pola header:

Kustomisasi parserOpts
parserOpts: {
  noteKeywords: ["BREAKING CHANGE", "BREAKING-CHANGE"],
  headerPattern: /^(\w*)(?:\(([\w$.\-* ]*)\))?: (.*)$/,
  breakingHeaderPattern: /^(\w*)(?:\(([\w$.\-* ]*)\))?!: (.*)$/,
}

noteKeywords menentukan footer mana yang dianggap breaking. headerPattern dan breakingHeaderPattern mendefinisikan struktur type(scope): subject, termasuk dukungan tanda !. Kalau tim memakai format commit custom, di sinilah tempat menyesuaikannya.

Konfigurasi Lengkap

release.config.cjs
const config = {
  branches: ["main", { name: "staging", prerelease: "rc" }],
  plugins: [
    [
      "@semantic-release/commit-analyzer",
      {
        preset: "angular",
        parserOpts: {
          noteKeywords: ["BREAKING CHANGE", "BREAKING-CHANGE"],
          headerPattern: /^(\w*)(?:\(([\w$.\-* ]*)\))?: (.*)$/,
          breakingHeaderPattern: /^(\w*)(?:\(([\w$.\-* ]*)\))?!: (.*)$/,
        },
        releaseRules: [
          { breaking: true, release: "major" },
          { type: "feat", release: "minor" },
          { type: "fix", release: "patch" },
          { type: "perf", release: "patch" },
          { type: "build", release: "patch" },
          { type: "chore", release: "patch" },
          { type: "revert", release: "patch" },
          { type: "docs", release: false },
          { type: "style", release: false },
          { type: "test", release: false },
        ],
      },
    ],
    "@semantic-release/release-notes-generator",
    "@semantic-release/github",
  ],
};
 
module.exports = config;

Perubahan utama dibanding default: build dan chore kini memicu patch, sedangkan docs, style, dan test tetap tidak memicu rilis. revert tetap patch. Preset angular tetap dipakai sebagai fondasi, lalu aturan custom menimpa perilakunya.

Warning

Memetakan chore menjadi patch bisa menjebak kalian dalam release loop. Commit rilis yang dibuat @semantic-release/git bertipe chore(release): dan akan memicu rilis lagi. Solusinya: sertakan [skip ci] pada pesan commit rilis, karena semantic-release mengabaikan commit pemicu yang memuat kata kunci itu.

Menguji Hasil Pemetaan

Setelah mengubah aturan, verifikasi sebelum benar-benar rilis:

Menguji pemetaan dengan dry run
git log --oneline -5
npx semantic-release --dry-run --no-ci

Baca baris yang menyebut "next release version". Kalau commit terakhir docs dan tidak ada feat atau fix, hasilnya tidak ada rilis. Kalau ada chore(deps), versi akan naik patch — sesuai aturan yang kalian tulis.

Kesalahan Umum

KesalahanGejalaSolusi
breaking ditaruh paling bawahBreaking jadi minor/patchTaruh aturan breaking: true paling atas
Tipe commit tidak dikenalTidak ada rilisPilih preset sesuai konvensi atau tambahkan rule
chore memicu loop rilisRilis berulang terusTambahkan [skip ci] pada commit rilis
Salah tulis nama presetError saat analisis commitPastikan preset yang dipakai sudah terpasang

Penutup

Pada episode 8 ini kalian telah:

  • Memahami posisi commit analyzer di tahap analyzeCommits dalam pipeline.
  • Mengetahui pemetaan default preset angular: feat minor, fix/perf/revert patch, breaking major, lainnya tidak rilis.
  • Menyusun releaseRules dengan urutan first-match-wins dan parserOpts untuk format commit custom.
  • Menguji setiap perubahan aturan dengan npx semantic-release --dry-run --no-ci.

Di episode 9 kita akan menyusun Linting & Build Automation — gerbang kualitas sebelum rilis, supaya hanya kode yang sudah teruji yang sampai ke tangan pengguna. Sampai jumpa di episode 9!

Belajar Semantic Release - Commit Analyzer & Release Rules | Belajar Semantic Release