Trunk-Based Development — пракса развоја у којој се све промене спајају у јединствену главну грану (trunk) без дуготрајних feature-грана. Према trunkbaseddevelopment.com, 2024, Trunk-Based Development подразумева краткотрајне гране (1–2 дана) или директне комите у trunk уз коришћење feature toggles. Овај приступ се комбинује са Continuous Integration и Continuous Deployment (CI/CD) и смањује број merge-конфликата.
Главне тачке
Trunk-Based Development (TBD) — методологија управљања верзијама у којој сви програмери интегришу своје промене у једну главну грану (trunk, main или master) неколико пута дневно. За разлику од Git Flow са његовим дуготрајним feature-гранама, TBD минимизује животни век грана на неколико сати, ређе на 1–2 дана. Главни циљ је избегавање „пакла спајања" (merge hell), када се велика функција спаја са trunk након недеља развоја.
Према Google Cloud DevOps, 2024, Trunk-Based Development је једна од кључних пракси високо продуктивних DevOps тимова. Истраживање State of DevOps Report (Puppet, 2023) показало је да се тимови који користе TBD 30% брже опорављају од отказа и 50% ређе сусрећу критичне дефекте у продукцији. TBD је обавезан за Continuous Deployment.
Trunk-Based Development не значи да програмери комитују директно у trunk без провере. У TBD се користе краткотрајне feature-гране које се након креирања MR и брзе ревизије кода (у року од неколико сати) спајају у trunk. Ако ревизија траје дуже од једног дана — то значи да функцију треба поделити на мање делове.
Годишњи State of DevOps Report (Puppet/DORA) прати праксе високо продуктивних тимова. Од 2015. године TBD се налази у топ 3 пракси које корелирају са високом учесталошћу испоруке (deploy frequency) и ниским временом опоравка (MTTR). Тимови који примењују TBD постављају код 2–3 пута чешће и опорављају се од отказа 30% брже (DORA, 2023).
Feature Toggles (заставице функција, feature flags) — механизам укључивања и искључивања функционалности без промене кода. У TBD, feature toggles замењују feature-гране: програмер комитује недовршени код у trunk, али га скрива иза условне заставице. Када је функција спремна за приказ, заставица се пребацује у конфигурацији без поновног постављања.
Према Martin Fowler, 2024, feature toggles се деле на четири типа: release toggles (управљање видљивошћу функције), experiment toggles (A/B тестирање), ops toggles (управљање оперативним параметрима) и permission toggles (приступ по улогама). У мобилним пројектима, release toggles су посебно корисни: нова функционалност је скривена до датума издања, али је код већ у trunk-у и пролази CI/CD.
// Feature Toggle у Android-у на Kotlin-у
object FeatureManager {
private val remoteConfig = FirebaseRemoteConfig.getInstance()
fun isEnabled(key: String): Boolean {
return remoteConfig.getBoolean(key)
}
}
// Коришћење у коду
if (FeatureManager.isEnabled("new_checkout_flow")) {
showNewCheckoutScreen()
} else {
showOldCheckoutScreen()
}
Continuous Integration (CI) — најважнија компонента TBD. Сваки push у trunk (или у привремену грану пре MR) покреће потпуни pipeline: изградња, јединични тестови, интеграциони тестови, линтери, статичка анализа, провера покривености кода. Ако макар једна фаза падне — аутор промена поправља код пре следећег комита. „Покварени trunk — заустављен развој" је главно правило TBD.
Према Jez Humble, Continuous Delivery, 2024, Trunk-Based Development захтева CI pipeline који се извршава за 10–15 минута. Ако изградња траје дуже — програмери ређе комитују, што уништава смисао TBD. У мобилним пројектима Android и iOS, изградња може трајати 20–30 минута, што чини TBD мање погодним. У таквим случајевима, тимови користе Short-Lived Feature Branches (гране од 1 дана) са тренутним CI.
# GitHub Actions за TBD (Android)
name: CI - TBD Check
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run tests
run: ./gradlew testDebugUnitTest
- name: Static analysis
run: ./gradlew ktlintCheck detekt
Краткотрајне гране (short-lived branches) — компромис између чистог TBD (директни комити у trunk) и Git Flow. Грана живи не дуже од 1–2 дана, садржи промене од 1–3 комита и након ревизије (не више од 4 сата чекања) се спаја у trunk. Ако функција захтева више времена — дели се на подзадатке, сваки са својом краткотрајном граном.
Према TBD Documentation, 2024, правила краткотрајних грана: грана се креира од свежег trunk-а (не старијег од 1 сата), не синхронизује се са trunk-ом путем merge/rebase (ако је прошло више од 4 сата — креира се нова грана), MR/PR се креира одмах након првог комита (чак и ако посао није завршен — као Draft).
За Trunk-Based Development је важна техника pre-tested commits: програмер пре комита покреће CI pipeline у својој грани и тек након зеленог статуса комит стиже у trunk. У GitLab-у се ово имплементира кроз Merge Request pipelines са опцијом „Merge when pipeline succeeds". У GitHub-у — кроз branch protection rules са Required status checks. Ово гарантује да trunk никада не садржи покварени код.
Branch by Abstraction — техника која омогућава замену или значајну измену дела система без креирања дуготрајне feature-гране. Уместо гранања у Git-у, програмер креира апстракцију (интерфејс) под којом раде и стара и нова имплементација. Постепено се сви потрошачи преводе на нову имплементацију, након чега се стара брише.
Према Branch by Abstraction, 2024, кораци Branch by Abstraction: 1) креирајте апстракцију за замењену компоненту, 2) имплементирајте нову верзију под апстракцијом, 3) пребаците потрошаче на нову имплементацију путем конфигурације, 4) обришите стару имплементацију. Сви кораци се комитују у trunk у малим порцијама, од којих ниједна не ломи CI/CD.
Trunk-Based Development и Git Flow — два супротна приступа управљању гранама. Git Flow користи дуготрајне гране и строгу хијерархију, TBD — једну грану и кратке циклусе интеграције. Избор између њих зависи од величине тима, учесталости издања и нивоа CI/CD аутоматизације.
| Параметар | Trunk-Based Development | Git Flow |
|---|---|---|
| Грана | Једна (trunk) + short-lived | Пет типова (main, develop, feature, release, hotfix) |
| Животни век гране | Сати–1 дан | Дани–недеље |
| Feature-гране | Не препоручују се | Главни механизам |
| Feature Toggles | Обавезни | Опционални |
| Обавезност CI | Апсолутна | Пожељна |
| Continuous Deployment | Компатибилан | Тешко |
| Сложеност | Ниска | Висока |
Грешке TBD су најчешће повезане са недовољним CI/CD или слабом дисциплином комита. Прва грешка — увођење TBD без CI, које се ломи при првом неуспешном комиту. Ако trunk не може да се поправи за 15 минута — тим губи поверење у процес и враћа се дугим гранама. Друга — дозвољавање дуготрајних грана „искључиво за ову функцију", што уништава цео концепт.
Према Paul Hammant, 2023, трећа грешка — слаба модуларност кода. Trunk-Based Development захтева да код буде подељен на независне модуле. Ако промена у једној класи ломи три друга модула — програмери не могу да комитују у малим порцијама. Четврта — игнорисање feature toggles: покушај комитовања недовршеног кода без заставице доводи до ломљења trunk-а за цео тим.
Trunk-Based Development у мобилним пројектима има специфичности због дуге изградње (20–30 минута за Android и iOS) и строгих захтева за квалитетом. Google и Spotify користе TBD у мобилном развоју, примењујући short-lived branches са обавезним проласком CI пре спајања. Feature toggles се управљају путем Firebase Remote Config или LaunchDarkly.
Према LaunchDarkly Docs, 2024, у мобилном развоју TBD даје предност: функције се тестирају у trunk-у заједно са остатком кода до датума издања, што смањује ризик од интеграционих проблема. Ако CI pipeline траје више од 15 минута — оптималне су short-lived branches од 1 дана са аутоматским CI при сваком push-у. За Apple App Store и Google Play, TBD захтева подешавање staged rollouts-а путем feature toggles.
За управљање feature toggles у TBD користе се платформе: LaunchDarkly (enterprise, пуна функционалност), Firebase Remote Config (бесплатно за мале пројекте), Split.io (open-source). Оне пружају: циљано укључивање функција по проценту корисника, A/B тестирање, праћење коришћења и аутоматско искључивање при грешкама. У мобилним пројектима, Firebase Remote Config је најпопуларнији избор због интеграције са Firebase и бесплатног прага до 1000 корисника.
Често постављана питања
Trunk-Based Development (TBD) — приступ у којем сви програмери раде у једној главној грани (trunk) и комитују код у малим порцијама неколико пута дневно. То смањује merge-конфликте и убрзава Continuous Integration.
У TBD нема дуготрајних feature-грана ни посебне develop-гране. Све промене се брзо спајају у trunk, а недовршени код се скрива иза feature toggles. Git Flow користи дуге гране и строг процес спајања кроз release и hotfix.
Да, feature toggles — кључни механизам TBD. Они омогућавају комитовање недовршеног кода у trunk без ломљења главне гране. Функција је скривена иза заставице која се укључује када је спремна. Ово замењује feature-гране Git Flow-а.
Почните са CI/CD: pipeline треба да се извршава за 15–30 минута. Уведите feature toggles (Firebase Remote Config, LaunchDarkly). Користите short-lived branches од 1–2 дана са брзом ревизијом кода. Декомпонујте велике функције на мале подзадатке.
Главни ризик — покварени trunk блокира цео тим. Без брзог CI (10–15 минута) и дисциплине малих комита TBD не ради. Такође је потребна квалитетна модуларна архитектура и искуство у раду са feature toggles.
Закључак
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође