Memahami strategi branching Git Flow dan adaptasinya ke dua branch: staging sebagai release candidate dengan suffix rc, dan main sebagai release stable. Termasuk diagram siklus hidup branch dan urutan perintah git dari fitur hingga rilis.

Di episode 3 kita belajar menulis commit yang berformat. Tapi commit tidak hidup sendiri — ia lahir di sebuah branch, di-review lewat pull request, lalu digabung ke branch lain. Strategi branching menentukan di mana commit-commit itu berkumpul, dan karena semantic-release membaca riwayat per branch, strategi ini menentukan versi apa yang lahir dan di mana ia dirilis.
Git Flow klasik punya banyak branch: main, develop, feature/, release/, dan hotfix/. Namun banyak tim modern menyederhanakannya menjadi dua jalur utama yang lebih mudah dikelola: staging untuk calon rilis, dan main untuk rilis stable. Repo ini (devvnull.vercel.app) memakai pola dua branch tersebut dengan suffix rc di staging.
| Branch | Peran |
|---|---|
main | Stable, hanya berisi kode yang sudah dirilis |
develop | Integrasi fitur sebelum rilis |
feature/* | Pengembangan fitur per tugas |
release/* | Persiapan rilis: bugfix + freeze fitur |
hotfix/* | Perbaikan darurat langsung dari main |
Idenya: fitur dikembangkan di feature/*, diintegrasikan ke develop, lalu release/* membekukan fitur dan mematangkan rilis sebelum digabung ke main. Sayangnya, makin banyak branch berarti makin banyak proses manual yang harus disepakati.
Alih-alih memelihara lima jenis branch, banyak tim cukup dengan dua:
main — branch stable. Setiap push memicu rilis SemVer penuh (1.2.0).staging — branch prerelease. Setiap push memicu rilis candidate (1.2.0-rc.1, 1.2.0-rc.2, dst).Konfigurasi branches di release.config.cjs repo ini terlihat seperti ini:
branches: [
"main",
{ name: "staging", prerelease: "rc" },
],Pada main, tag rilis berbentuk v1.2.0. Pada staging, versi yang sama diberi suffix rc dan counter bertambah setiap rilis — 1.2.0-rc.1, 1.2.0-rc.2, dan seterusnya — sampai tim sepakat naik ke stable.
Rilis candidate memberi tim target yang bisa diuji sebelum user melihatnya. QA, product owner, dan tester menarik versi 1.2.0-rc.1 ke environment staging, menguji fitur baru, lalu menyetujui atau menolak. Semua itu terjadi tanpa pernah menyentuh main. Setelah disetujui, staging digabung ke main, dan semantic-release menghitung versi stable 1.2.0 dari commit yang sama.
Urutan versi yang dihasilkan dari satu siklus fitur biasanya seperti ini:
staging push #1 -> v1.2.0-rc.1 (fitur masuk, siap diuji)
staging push #2 -> v1.2.0-rc.2 (bugfix hasil review)
staging push #3 -> v1.2.0-rc.3 (perbaikan terakhir QA)
main merge -> v1.2.0 (stabil, tanpa suffix rc)Perhatikan bahwa counter rc hanya bertambah di staging. Begitu commit yang sama digabung ke main, versinya menjadi 1.2.0 tanpa suffix — karena di main tidak ada konfigurasi prerelease.
Tip
Gunakan suffix rc (release candidate) hanya untuk branch yang benar-benar calon rilis. Jika kalian butuh environment pengembangan yang lebih longgar, beri nama suffix berbeda agar riwayat versi tidak tercampur.
feature/* staging (rc) main (stable)
| | |
|-- merge --------> | rilis 1.2.0-rc.1 |
| | |
| |-- merge ----------> | rilis 1.2.0
| | |Alur ini linear dan mudah diprediksi: fitur masuk ke staging, diuji sebagai rc, lalu dipromosikan ke main. Tidak ada kebocoran commit ke main tanpa melewati staging — kecuali untuk hotfix darurat yang memang sengaja melewatinya.
git checkout -b feature/login
git add .
git commit -m "feat: tambahkan halaman login"
git push origin feature/login
# PR di-review, lalu digabung ke staging
git checkout staging
git merge feature/login
git push origin staging # semantic-release rilis 1.2.0-rc.1
# verifikasi staging lolos, lalu digabung ke main
git checkout main
git merge staging
git push origin main # semantic-release rilis 1.2.0Perhatikan bahwa kalian tidak pernah menjalankan semantic-release secara manual — setiap git push origin ke branch yang terdaftar cukup memicu pipeline CI, dan pipeline yang menjalankan rilis. Perintah git hanya mengatur aliran commit; versi, changelog, dan tag menjadi tanggung jawab mesin.
Warning
Jangan pernah force-push ke main atau staging yang sudah di-protect. Tag rilis mengarah ke commit spesifik; menulis ulang history membuat tag itu menunjuk ke riwayat yang berbeda dan changelog akan dihitung ulang secara salah.
Kadang bug produksi terlalu mendesak untuk menunggu alur fitur. Hotfix melompati staging dan masuk langsung ke main, lalu di-cherry-pick kembali ke staging agar keduanya sinkron:
git checkout -b hotfix/critical-bug
git commit -m "fix: tangani crash saat load data"
git push origin hotfix/critical-bug
# PR di-review, langsung digabung ke main
git checkout main
git merge hotfix/critical-bug
git push origin main # semantic-release rilis v1.2.1
git checkout staging
git cherry-pick main # sinkronkan perbaikan ke stagingDengan pola ini, perbaikan darurat rilis cepat sebagai patch (v1.2.1) tanpa menunggu siklus fitur penuh, sementara staging tetap memiliki kode yang sama untuk pengembangan lanjutan.
Branch feature/* dihapus setelah di-merge. Branch staging dan main dipertahankan sepanjang umur proyek. Berbeda dengan Git Flow klasik yang release/*-nya dibuang setelah selesai, staging bersifat permanen di pola dua branch — ia adalah jalur promosi ke main, bukan wadah sementara.
Pada episode 4 ini kalian telah memahami:
main, develop, feature/, release/, dan hotfix/.staging (rc) untuk calon rilis dan main untuk stable.rc membuat versi prerelease 1.2.0-rc.1 sebelum stable 1.2.0.Di episode 5 kita akan memasang dan mengonfigurasi semantic-release: menginstall plugin inti, menyusun release.config.cjs dengan branch main dan staging, serta mengatur custom rules commit analyzer. Sampai jumpa di episode 5!