Apa Itu Trunk Based Development? Aturan, Flag, dan CI
Summary
Apa itu trunk based development? Ini model percabangan di mana developer menggabungkan perubahan kecil ke satu cabang bersama, biasanya main, minimal sekali sehari. Cabang yang tersisa hanya hidup hitungan jam, dan fitur yang belum selesai disembunyikan dengan feature flag. Riset DORA menghubungkan praktik ini dengan pengiriman yang lebih cepat dan lebih stabil. Untuk developer solo dan tim kecil, artinya merge yang lebih kecil, review yang lebih ringan, dan deploy yang terasa membosankan.
Apa itu trunk based development? Ini model percabangan di mana setiap developer menggabungkan perubahan kecil ke satu cabang bersama, biasanya bernama main atau trunk, minimal sekali sehari. Kalau kamu tetap memakai cabang, umurnya hitungan jam, bukan minggu. Fitur yang belum selesai disembunyikan di balik feature flag, sehingga trunk selalu bisa di-deploy di setiap commit. Itulah inti idenya, dan ternyata tidak serumit namanya.
Bayangkan kamu membuka proyek sampingan yang kamu tinggalkan tiga minggu. Cabang fitur kamu tertinggal 41 commit dari main, dua file konflik, dan kode yang kamu tulis sudah tidak cocok dengan kode di sekitarnya. Trunk based development adalah kebiasaan yang mencegah skenario itu terjadi.
Apa yang sebenarnya dimaksud dengan trunk based development
Situs referensi trunkbaseddevelopment.com mendefinisikannya sebagai model kontrol versi di mana developer berkolaborasi di satu cabang bersama dan menghindari cabang pengembangan lain yang hidup lama. Commit langsung ke trunk tidak masalah untuk tim yang sangat kecil. Pull request juga boleh, selama cabang fiturnya pendek dan berasal dari kerja satu workstation.
Ada tiga aturan yang paling menentukan.
Merge ke trunk minimal sekali setiap 24 jam.
Jaga trunk tetap hijau. Build yang rusak di main adalah prioritas utama semua orang.
Sembunyikan pekerjaan yang belum selesai dengan feature flag, bukan dengan menyimpannya di cabang sampingan.
Perhatikan apa yang tidak ada. Tidak ada branch develop, tidak ada release branch panjang untuk setiap fitur, dan tidak ada fase integrasi di akhir tempat semua orang baru sadar kodenya tidak saling cocok. Pada model lama, rasa sakitnya ditumpuk dulu lalu dibayar sekaligus.

Kenapa cabang yang hidup lama kalah untuk tim kecil
Cabang yang hidup lama itu seperti pinjaman. Setiap hari cabang itu hidup, ia makin menjauh dari main, dan bunganya muncul sebagai merge conflict, asumsi yang sudah basi, serta review yang tidak pernah selesai karena diff-nya menyentuh 60 file.
Halaman capabilities trunk-based development dari DORA mengaitkan praktik ini dengan kecepatan, stabilitas, dan ketersediaan delivery yang lebih baik, berdasarkan riset State of DevOps mereka. Targetnya konkret: tiga cabang aktif atau lebih sedikit di repository, merge ke trunk minimal sekali sehari, dan tanpa code freeze maupun fase integrasi. Target yang terukur seperti ini jarang ditemukan di bidang ini.
Untuk developer solo atau tim tiga orang, argumennya lebih sederhana lagi. Merge kecil mudah di-review, mudah di-revert, dan mudah dipahami enam bulan kemudian, saat kamu membaca git blame jam 22.00 sambil bertanya apa yang dipikirkan diri kamu dulu.
Ada tiga alasan untuk mencobanya, dan satu alasan untuk tidak. Alasannya: diff lebih kecil, feedback dari CI lebih cepat, dan main yang bisa di-deploy hari Jumat tanpa was-was. Alasan untuk tidak: kalau tes kamu tipis, merge harian hanya menyebarkan kerusakan lebih cepat. Kita bahas itu di bawah.
Cabang pendek atau langsung commit ke main?
Keduanya termasuk trunk based development. Bedanya ada di seberapa besar rasa aman yang kamu mau sebelum kode masuk.
Commit langsung ke main cocok kalau kamu sendirian atau berpasangan, build lokal selesai di bawah satu menit, dan kamu percaya pada tes kamu. Ini loop tercepat yang ada. Banyak builder solo sudah melakukannya tanpa menyebutnya apa-apa.
Cabang pendek dengan pull request masuk akal begitu ada orang kedua atau ketiga yang bergabung, atau saat kamu ingin CI berjalan di checkout yang bersih sebelum merge. Disiplinnya ada di kata "pendek". Cabang yang masih hidup melewati hari berikutnya sudah mulai menyimpang menuju model yang sedang kamu tinggalkan.
Rutinitas praktis yang terbukti jalan:
Tarik main, lalu buat cabang dengan nama yang menjelaskan perubahannya.
Buat perubahan sekecil mungkin yang tetap memajukan pekerjaan, lalu jalankan build lokal lengkap.
Buka PR, biarkan CI berjalan, dan merge di hari yang sama.
Hapus cabangnya. Jangan biarkan menumpuk.
Kalau sebuah perubahan tidak bisa selesai dalam sehari, jawabannya bukan cabang yang lebih panjang. Jawabannya adalah memotong perubahan itu lebih tipis.
Bagaimana kirim kode setengah jadi tanpa merusak main?
Ini pertanyaan yang membuat kebanyakan orang berhenti. Kalau kamu merge setiap hari, kamu akan memasukkan kode untuk fitur yang belum ada. Dua teknik menangani hal ini.
Teknik pertama adalah feature flag. Jalur kode baru di-merge tapi dalam keadaan mati, sehingga pengguna tidak pernah melihatnya. Flag bisa sesederhana boolean di environment variable:
const showNewCheckout = process.env.FEATURE_NEW_CHECKOUT === "true";
export function Checkout() {
return showNewCheckout ? <NewCheckout /> : <OldCheckout />;
}Untuk proyek sampingan, itu sudah cukup. Saat kamu butuh penargetan, rollout bertahap, atau kill switch tanpa redeploy, layanan terkelola layak dipertimbangkan.
Teknik kedua adalah branch by abstraction, untuk perubahan yang lebih besar seperti mengganti database client atau payment provider. Kamu memasang sebuah interface di depan implementasi lama, membangun implementasi baru di balik interface yang sama, memindahkan pemanggil sedikit demi sedikit, lalu menghapus yang lama. Setiap langkahnya adalah merge kecil ke trunk, dan tidak ada yang tertahan di cabang panjang.

Satu catatan jujur soal flag: flag itu utang. Flag yang bertahan di kode selama setahun adalah cabang yang menyamar. Beri setiap flag pemilik dan tanggal penghapusan, lalu hapus saat fitur sudah rollout penuh.
Apa yang harus ada di CI sebelum mencoba ini
Trunk based development tanpa jaring pengaman hanya mempercepat kerusakan. Ada tiga hal yang perlu ada sebelum kamu berkomitmen pada merge harian.
Build yang berjalan di setiap push dan selesai dalam hitungan menit, bukan setengah jam.
Tes yang gagal saat ada yang benar-benar rusak. Angka coverage kurang penting dibanding apakah perubahan buruk benar-benar tertangkap.
Cara rollback yang cepat: revert commit atau matikan flag.
Static analysis adalah lapisan tambahan yang murah. Ia menangkap beberapa jenis masalah, seperti bug yang jelas, bau keamanan, dan kode duplikat, sebelum manusia membaca diff.
Kalau kamu satu-satunya reviewer, tooling yang menunjuk area berisiko tinggi sangat membantu, karena tidak ada orang lain yang akan memberitahu bahwa file yang sering kamu sentuh mulai berantakan.
Jangan berasumsi kamu butuh pipeline yang berat di hari pertama. Satu file workflow yang meng-install, lint, tes, dan deploy main adalah awal yang sangat baik. Sudah diuji, belum optimal, dan tetap layak dilakukan. Ini versi pertama yang berfungsi, dan kamu bisa memperketatnya nanti.
Release branch, hotfix, dan hal yang tetap perlu hati-hati
Trunk based development tidak melarang release branch. Beberapa tim memotong cabang dari trunk tepat sebelum rilis, mengerasnya, merilisnya, lalu menghapusnya. Tim lain merilis langsung dari trunk dan memperbaiki maju (fix forward) saat ada bug. Untuk aplikasi web yang di-deploy beberapa kali seminggu, fix forward hampir selalu lebih sederhana.
Aplikasi mobile dan apa pun dengan siklus review store yang lambat adalah cerita yang berbeda. Di sana kamu mungkin menyimpan release branch pendek per versi supaya bisa menambal apa yang sudah ada di tangan pengguna. Meski begitu, aturannya tetap: perbaikan mendarat di trunk dulu, lalu di-cherry-pick, tidak pernah sebaliknya.
Hotfix mengikuti logika yang sama. Perbaiki di trunk, deploy, selesai. Cabang hotfix terpisah yang tidak pernah di-merge balik adalah cara tim berakhir dengan dua riwayat yang saling menjauh.

Seminggu pertama yang realistis
Hari pertama, cek bagaimana repo kamu bercabang sekarang. Daftar cabang yang terbuka dan catat umur masing-masing. Yang lebih tua dari beberapa hari adalah kandidat untuk di-merge atau dihapus. Ini saja sering menunjukkan di mana gesekannya berada.
Hari kedua, tambahkan mekanisme flag. Environment variable saja sudah cukup. Pilih satu fitur yang sedang dikerjakan, pasang titik masuknya di balik flag, lalu merge apa yang sudah ada.
Hari ketiga sampai kelima, ubah kebiasaannya. Potong setiap tugas menjadi bagian yang bisa mendarat dalam sehari, lalu merge tiap bagian begitu CI lulus. Bagian-bagian awal akan terasa terlalu kecil. Sebenarnya tidak. Commit yang menambahkan kolom database yang belum dipakai atau fungsi yang belum dipanggil adalah unit kemajuan yang sah, karena aman, sudah di-review, dan sudah terintegrasi.
Di akhir minggu, kamu akan tahu dua hal: apakah tes kamu cukup layak dipercaya, dan bagian mana dari kode yang menolak perubahan kecil. Keduanya berguna, dan tidak ada yang muncul saat kamu bekerja di cabang panjang.
Kamu tidak butuh dashboard untuk mengetahuinya. Lihat berapa lama cabang kamu hidup, seberapa sering main dalam keadaan merah, dan berapa lama sebuah perubahan dari commit pertama sampai ke produksi. Kalau umur cabang makin pendek dan deploy makin membosankan, kebiasaan ini sedang bekerja.
Kalau kamu ingin angka tentang dampak ke pengguna dari fitur yang kamu rilis di balik flag, tool eksperimen bisa menghubungkan rollout dengan metrik nyata, bukan sekadar perasaan.
Untuk tim yang hanya berisi kamu, buku catatan biasa pun cukup. Catat waktu dari merge sampai deploy setiap minggu selama sebulan. Tren-nya memberi tahu lebih banyak daripada angka tunggal mana pun.
Sebaiknya pindah sekarang atau nanti?
Pindah kalau kamu bekerja sendiri, berpasangan, atau dalam tim kecil dengan tes yang setengah kamu percaya dan CI yang bisa kamu perbaiki. Biaya mencoba hanyalah seminggu commit kecil yang agak tidak nyaman. Biaya bertahan di cabang panjang dibayar dengan konflik dan review yang lambat, dan biaya itu bertambah setiap ada kolaborator baru.
Tunda kalau kamu sama sekali tidak punya tes otomatis dan tidak punya cara untuk rollback. Benahi itu dulu, karena merge harian ke trunk yang tidak teruji hanya memindahkan rasa sakitnya.
Ini bukan metode yang sempurna. Ini metode yang bisa dijalankan. Ambil perubahan kecil berikutnya di proyek kamu sekarang, merge hari ini, dan lihat bagaimana rasanya. Potongan terkecil dari fitur kamu yang bisa kamu rilis malam ini apa?