Apa Itu Trunk Based Development? Panduan Platform Engineer

Summary

Trunk based development berarti semua developer menggabungkan perubahan kecil ke satu branch bersama, minimal sekali sehari, dan menjaga branch itu tetap siap rilis. Model ini bekerja karena batch kecil membuat review lebih teliti dan konflik lebih mudah dikendalikan. Syaratnya: build dan test yang cepat, test yang andal, review yang tidak lambat, dan cara aman mengirim pekerjaan belum selesai lewat feature flag. Model ini tidak cocok untuk setiap tim.

Batang pohon dengan cabang-cabang pendek yang kembali menyatu ke batangnya, gambaran trunk based development

Jam 3 pagi dan release branch tidak bisa di-merge. Empat puluh commit, sudah tiga minggu, dan menyentuh file yang sama dengan main. Rasa sakit seperti inilah alasan trunk based development ada. Lalu, apa itu trunk based development? Ini adalah model branching ketika semua developer menggabungkan perubahan kecil ke satu branch bersama, yang disebut trunk atau main, minimal sekali sehari, dan branch itu selalu dalam kondisi siap rilis.

Panduan ini ditujukan untuk platform engineer yang sudah paham Git. Isinya membahas apa yang dituntut model ini, apa yang ia lindungi dari Anda, dan di mana ia diam-diam gagal.

Apa itu trunk based development secara operasional?

Mari kita pangkas definisinya sampai tinggal batasannya. Semua developer terintegrasi ke satu branch. Branch lain hanya hidup hitungan jam, bukan minggu. Trunk harus lolos build dan test di setiap commit, sehingga kapan pun bisa dikirim ke produksi.

Halaman kapabilitas DORA memberi angka untuk ini: tidak lebih dari tiga branch aktif di repositori, merge ke trunk minimal sekali sehari, tanpa code freeze, dan siklus build serta test yang selesai dalam hitungan menit. Angka-angka itu justru intinya. Model ini adalah anggaran feedback loop, bukan preferensi gaya branching.

Meja gelap di malam hari dengan laptop yang menampilkan terminal dan notifikasi telepon yang menyala

Tim kecil kadang commit langsung ke trunk. Tim yang lebih besar memakai branch berumur pendek dan pull request untuk review serta pengecekan build, tetapi tidak pernah untuk menahan pekerjaan dari integrasi. Referensi trunkbaseddevelopment.com membahas kedua mode ini dan menyebut Google, yang menjalankan sekitar 35.000 developer di satu trunk dalam sebuah monorepo.

Mengapa branch berumur panjang gagal sesuai jadwal yang bisa diprediksi

Feature branch itu seperti pinjaman. Bunganya berupa merge conflict, dan bunga itu berbunga setiap kali ada commit baru yang masuk ke main selama Anda pergi. Makin lama branch hidup, makin besar diff-nya, dan makin besar diff, makin kecil kemungkinan ada yang membacanya dengan teliti.

Ini berdampak langsung pada change failure rate Anda. Merge 2.000 baris hanya di-skim lalu di-approve. Merge 60 baris benar-benar dibaca. Reviewer bukan malas, mereka sedang membagi perhatian yang terbatas. Batch kecil adalah satu-satunya mekanisme yang bisa menjaga kualitas review tetap konsisten ketika tim membesar.

Biaya kedua tidak terlihat sampai saat rilis. Dua branch yang masing-masing lolos CI tetap bisa saling merusak ketika digabungkan. Anda baru tahu saat integrasi, momen terburuk, dengan tenggat yang sudah menempel.

Apa yang harus ada di trunk sebelum Anda bisa mempercayainya

Pindah ke trunk tanpa praktik pendukungnya adalah cara tercepat agar tim kembali ke feature branch dalam satu kuartal. Ada empat hal yang harus tersedia lebih dulu.

Lewatkan salah satu dari ini, dan trunk menjadi tempat kerusakan menumpuk, bukan tempat kerusakan tertangkap.

Bagaimana menggabungkan pekerjaan yang belum selesai tanpa mengirimkannya?

Ini pertanyaan yang selalu diajukan para skeptis, dan jawabannya membosankan: pisahkan deploy dari release. Kode sampai ke produksi dalam kondisi gelap. Sebuah flag yang memutuskan siapa yang melihatnya.

// checkout.ts
import { flags } from "./flags";

export async function renderCheckout(user: User) {
  if (await flags.isEnabled("new-payment-flow", { userId: user.id })) {
    return renderNewPaymentFlow(user); // sudah di-merge ke trunk, nonaktif secara default
  }
  return renderLegacyCheckout(user);
}

Alur baru di-merge pada hari pertama, di balik flag yang nonaktif. Anda menyalakannya untuk pengguna internal, lalu 1 persen, lalu 10 persen, dengan gerbang SLO di setiap langkah. Jika error rate melewati anggaran, flag dimatikan dan perubahan efektif dibatalkan tanpa deploy. Tim yang mengevaluasi layanan flag terkelola sering memulai dengan LaunchDarkly, meski pola ini bisa dipakai dengan penyedia mana pun atau config store buatan sendiri.

Teknik kedua adalah branch by abstraction, untuk refactor besar. Anda memperkenalkan sebuah interface, mengarahkan pemanggil lewat interface itu, membangun implementasi baru di baliknya, lalu menukarnya ketika siap. Tidak ada branch berumur panjang, tidak ada merge big-bang.

Deretan saklar dinding, sebagian menyala dan sebagian mati, seperti feature flag

Biaya yang jujur: flag adalah utang dengan masa paruh

Tidak ada yang mau membahas ini di konferensi. Setiap flag yang Anda tambahkan adalah kondisional di produksi yang harus dihapus oleh seseorang. Kami pernah melihat tim berisi 80 engineer membawa beberapa ratus flag usang, masing-masing menjadi cabang di kode yang tidak bisa diuji secara menyeluruh oleh siapa pun.

Perlakukan flag sebagai sesuatu yang berumur pendek, dan jadikan itu kontrak. Beri setiap flag seorang pemilik dan tanggal kedaluwarsa saat dibuat. Pasang alert untuk flag yang melewati masa berlakunya. Hapus jalur kode mati di pull request yang sama dengan penghapusan flag.

Risiko kombinatorialnya juga nyata. Sepuluh flag boolean independen menghasilkan 1.024 kemungkinan konfigurasi, dan Anda tidak akan pernah menguji semuanya. Jaga interaksi antarflag tetap sedikit, dan pisahkan release flag dari toggle operasional jangka panjang seperti kill switch.

Strategi rilis dan observabilitas di atas trunk

Ada dua cara umum untuk memotong rilis dari trunk, dan keduanya tidak membutuhkan branch berumur panjang.

Pilihan Anda bergantung pada detection time. Jika Anda bisa menyadari deploy yang buruk dalam lima menit dan membatalkannya dalam dua menit, perbaiki ke depan. Jika mean time to detect Anda satu jam, release branch memberi Anda pijakan.

Jalur-jalur kecil yang menyatu ke satu jalur rel utama

Trunk based development menaikkan frekuensi deploy, dan itu menaikkan jumlah momen ketika sesuatu bisa rusak. Model ini hanya berhasil jika Anda bisa melihat regresi dalam hitungan menit setelah merge. Artinya error rate, persentil latensi, dan saturasi yang terikat pada rilis tertentu, bukan dashboard yang baru dicek seseorang hari Senin.

Tes sederhananya: setelah merge, bisakah Anda menjawab "apakah perubahan ini menggeser p99 atau error rate?" tanpa membuka lima tab? Jika tidak, Anda belum siap untuk merge sepuluh kali sehari.

Apa pun stack yang Anda pakai, syaratnya sama. Penanda deploy di grafik, alert burn-rate SLO, dan jalur revert yang bisa dijalankan oleh orang yang lelah pada jam 3 pagi tanpa perlu berpikir panjang.

Sinyal yang sama juga harus tersedia di jalur deploy Anda, termasuk pemeriksaan kesehatan setelah setiap rollout.

Trunk based development vs GitFlow vs GitHub Flow

Ketiganya sering tercampur, jadi pisahkan dengan satu properti: berapa lama pekerjaan tetap berada di luar branch bersama.

Jika tim Anda sudah memakai GitHub Flow dengan branch yang hidup kurang dari dua hari, Anda lebih dekat ke trunk daripada yang Anda kira. Celahnya biasanya ada pada disiplin flag dan latensi review, bukan pada tooling.

Instrumentasikan metrik DORA ini sebelum mulai, atau Anda nanti akan berdebat berdasarkan perasaan. Deployment frequency dan lead time for changes bereaksi lebih dulu, karena batch yang lebih kecil mengalir lebih cepat melewati pipeline. Change failure rate dan time to restore menyusul, dan keduanya bergantung pada observabilitas serta jalur revert, bukan hanya pada model branching.

Jangan jadikan angka-angka ini rapor individu. Angka ini menggambarkan sistem. Ketika lead time naik, periksa antrean review dan durasi CI sebelum memeriksa orangnya.

Kapan trunk based development adalah pilihan yang salah, dan cara memulainya

Lewati model ini, atau setidaknya tunda, dalam beberapa kasus. Jujurlah tentang kasus mana yang sedang Anda hadapi.

Trunk based development juga bukan jaminan apa pun. Temuan DORA adalah korelasi dari data 2016 dan 2017, dengan tim yang menjalankan praktik ini menunjukkan performa pengiriman dan operasional yang lebih baik. Model ini tidak mengatakan bahwa mengganti nama branch akan memperbaiki pipeline Anda.

Jangan umumkan kebijakan dulu. Ukur, lalu persempit.

  1. Catat umur branch saat ini dan ukuran median pull request. Ini baseline Anda.

  2. Tetapkan batas, misalnya tidak ada branch yang lebih tua dari dua hari, dan tampilkan batas itu di dashboard.

  3. Perbaiki bagian CI yang paling lambat. Jika build memakan 30 menit, tidak ada hal lain yang penting dulu.

  4. Perkenalkan satu flag untuk satu fitur nyata. Kirim dalam kondisi gelap. Hapus flag itu dalam satu sprint.

  5. Hilangkan code freeze paling akhir, setelah jalur revert pernah benar-benar diuji dalam kondisi nyata.

Tinjau ulang dalam sebulan. Angka yang biasanya bergerak lebih dulu adalah ukuran pull request dan waktu sampai merge. Change failure rate butuh waktu lebih lama, dan kadang memburuk sebelum membaik, karena Anda akhirnya melihat kerusakan lebih awal.

Apa yang akan dikatakan post-mortem Anda? Itu pertanyaan yang berguna sebelum Anda mengirim perubahan. Jika insiden terakhir berawal dari merge yang tidak sempat di-review, branch yang menyimpang selama tiga minggu, atau rilis yang membungkus empat puluh perubahan, Anda sudah tahu di mana utang itu akan jatuh tempo. Lihat tiga outage terakhir Anda. Berapa banyak yang melibatkan integrasi besar dan terlambat? Jumlah itu adalah business case Anda.

Frequently asked questions

Apa perbedaan utama trunk based development dengan GitFlow?
GitFlow menyimpan pekerjaan di branch develop, feature, release, dan hotfix yang bisa hidup berminggu-minggu. Trunk based development membatasi umur branch menjadi hitungan jam, sehingga semua orang berintegrasi ke satu branch bersama setiap hari.
Seberapa sering developer harus merge ke trunk?
Minimal sekali sehari. Angka ini berasal dari kapabilitas trunk based development yang dicatat DORA, bersama batas tidak lebih dari tiga branch aktif di repositori.
Apakah trunk based development berarti semua orang commit langsung ke main?
Tidak harus. Tim kecil bisa commit langsung ke trunk, sedangkan tim yang lebih besar memakai branch berumur pendek dan pull request, selama branch itu tidak dipakai untuk menahan pekerjaan dari integrasi.
Bagaimana cara menyembunyikan fitur yang belum selesai di trunk?
Gunakan feature flag. Kode bisa di-merge dan dikirim dalam kondisi nonaktif, lalu fitur dinyalakan bertahap untuk pengguna internal, 1 persen, dan 10 persen, dengan gerbang SLO di setiap langkah.
Mengapa feature flag perlu dihapus setelah dipakai?
Flag adalah kondisional di produksi yang menentukan siapa melihat fitur. Setiap flag menambah jalur kode yang harus diuji, sehingga flag yang sudah tidak dipakai perlu dihapus bersama jalur kode mati-nya.
Kapan sebaiknya tidak memakai trunk based development?
Saat suite test memakan satu jam dan tidak bisa diparalelkan, saat artefak berversi dipakai pelanggan selama bertahun-tahun, saat tim tidak punya sistem flag, atau saat tim tidak percaya pada build.