Kelola strategi rilis multi-branch dengan branch rc untuk release candidate dan main untuk stable, pahami prioritas SemVer pada suffix rc, serta susun release.config.cjs dengan beberapa entri branch sekaligus.

Di episode 14 changelog otomatis sudah berjalan. Pertanyaan berikutnya: bagaimana tim yang sedang menyiapkan rilis besar tetap bisa merilis perbaikan kecil di produksi? Jawabannya adalah multi-branch release — satu repository, beberapa saluran rilis dengan versi berbeda.
Episode ini membahas perbedaan prerelease, release candidate, dan stable release; bagaimana suffix -rc.N diurutkan menurut SemVer; serta konfigurasi release.config.cjs dan GitHub Actions untuk branch main plus staging.
| Istilah | Format versi | Tujuan |
|---|---|---|
| Prerelease | 1.4.0-alpha.1, 1.4.0-beta.1 | Uji internal, fitur belum lengkap |
| Release candidate | 1.4.0-rc.1 | Fitur lengkap, menunggu verifikasi akhir |
| Stable release | 1.4.0 | Rilis resmi untuk pengguna |
Urutan kedewasaan: alpha paling mentah, beta lebih matang, rc siap diluncurkan. Masing-masing bisa hidup di branch terpisah dan dipublish ke saluran (channel) yang berbeda.
SemVer menentukan urutan versi bukan secara alfabetis, melainkan berdasarkan komponen MAJOR.MINOR.PATCH lalu prerelease. Perhatikan pola berikut:
1.4.0-rc.1 < 1.4.0-rc.2 < 1.4.0-rc.3 < 1.4.0Semakin besar angka setelah rc., semakin tinggi prioritasnya — tetapi selalu di bawah versi stable yang sama. Artinya 1.4.0-rc.9 masih lebih rendah dari 1.4.0. Ini yang membuat pembanding versi otomatis (misal npm install) tahu bahwa rc bukan pengganti stable.
Aturan tambahan: build metadata seperti +build.5 tidak memengaruhi prioritas. Dan jika dua versi prerelease dibandingkan, urutannya mengikuti urutan pengenal: alpha < beta < rc.
Semantic-release membaca daftar branch dari kunci branches. Setiap entri bisa berupa string sederhana atau objek dengan opsi channel dan prerelease:
module.exports = {
branches: [
{ name: 'main' },
{ name: 'staging', channel: 'rc', prerelease: 'rc' },
{ name: 'beta', prerelease: 'beta' },
],
tagFormat: 'v${version}',
plugins: [
'@semantic-release/commit-analyzer',
'@semantic-release/release-notes-generator',
'@semantic-release/npm',
'@semantic-release/github',
],
};Yang terjadi di balik layar:
main → rilis 1.4.0 (stable).staging → rilis 1.4.0-rc.1, lalu -rc.2, dan seterusnya.beta → rilis 1.4.0-beta.1 di channel beta.channel menentukan dist-tag saat publish npm dan branch target GitHub Release.tagFormat menghasilkan tag seperti v1.4.0-rc.1.Saat staging akhirnya di-merge ke main, semantic-release menghitung lagi dari tag tertinggi dan menghasilkan 1.4.0 yang stabil. Selalu verifikasi konfigurasi baru dengan npx semantic-release --dry-run --no-ci sebelum membiarkan workflow berjalan otomatis.
Warning
Hanya boleh ada satu branch per nilai prerelease. Jika dua branch sama-sama memakai prerelease: 'rc', keduanya akan berebut nomor rc.N dan nomornya bisa saling menimpa. Untuk beberapa rilis paralel, gunakan nama prerelease yang berbeda seperti alpha, beta, dan rc.
Workflow release cukup dipicu oleh push ke kedua branch; semantic-release sendiri yang memutuskan jenis rilis berdasarkan branch aktif:
name: Release
on:
push:
branches: [main, staging]
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- run: npx semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}Tidak perlu kondisi tambahan untuk memilih jenis rilis — konfigurasi branches di release.config.cjs sudah menjadi sumber kebenaran tunggal. Jika suatu saat diperlukan pemfilteran eksplisit, workflow bisa membandingkan nilai github.ref dengan refs/heads/main atau refs/heads/staging, tetapi untuk studi kasus ini biarkan semantic-release yang menanganinya.
Tip
Saat dua branch rilis berdampingan, waspadai tag yang tumpang tindih. Pastikan alur promosi berurutan: fitur di-merge ke staging, diverifikasi, baru di-merge ke main. Rilis paralel dari dua branch dengan base versi sama akan menghasilkan commit history yang rumit untuk diurutkan.
Rekap episode 15:
1.4.0-rc.N selalu lebih rendah dari 1.4.0, dan rc.1 < rc.2 < ....branches di release.config.cjs mendukung beberapa entri dengan channel dan prerelease.prerelease agar nomor tidak bertabrakan.main dan staging; jenis rilis ditentukan konfigurasi.Multi-branch memberi tim dua jalur rilis sekaligus. Di episode 16 kita menyentuh Custom Release Plugins & Extensions — menulis plugin semantic-release sendiri untuk kebutuhan organisasi, memakai @semantic-release/exec, dan mengintegrasikan artifact repository atau private registry. Sampai jumpa!