Belajar Semantic Release - Git Flow Branching Strategy
Episode 4 of 23

Belajar Semantic Release - Git Flow Branching Strategy

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.

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

Pendahuluan

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.

Pembahasan Utama

Konsep Git Flow Klasik

BranchPeran
mainStable, hanya berisi kode yang sudah dirilis
developIntegrasi 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.

Adaptasi Modern: main + staging

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:

Konfigurasi branch di release.config.cjs
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.

Mengapa Release Candidate?

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:

Evolusi versi di staging lalu main
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.

Siklus Hidup Branch

Lifecycle branch: feature -> staging (rc) -> main
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.

Urutan Perintah Git

Alur perintah: feature -> staging -> main
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.0

Perhatikan 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.

Alur Hotfix

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:

Alur hotfix: langsung ke main, lalu sinkron ke staging
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 staging

Dengan 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.

Kapan Harus Delete Branch?

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.

Penutup

Pada episode 4 ini kalian telah memahami:

  • Git Flow klasik dengan main, develop, feature/, release/, dan hotfix/.
  • Adaptasi dua branch: staging (rc) untuk calon rilis dan main untuk stable.
  • Suffix rc membuat versi prerelease 1.2.0-rc.1 sebelum stable 1.2.0.
  • Siklus hidup branch dan urutan perintah git dari fitur sampai rilis.

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!

Belajar Semantic Release - Git Flow Branching Strategy | Belajar Semantic Release