Trunk-Based Development — практика за разработка, при която всички промени се сливат в един единствен основен клон (trunk) без дългоживеещи feature-клонове. Според trunkbaseddevelopment.com, 2024, Trunk-Based Development предполага краткоживеещи клонове (1–2 дни) или директни commits в 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 не означава, че разработчиците правят commit директно в 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-клоновете: разработчикът прави commit на незавършен код в 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: сборка, модулни тестове, интеграционни тестове, линтери, статичен анализ, проверка на покритието на кода. Ако поне един етап се провали — авторът на промените поправя кода преди следващия commit. „Счупен trunk — спряна разработка" е основното правило на TBD.
Според Jez Humble, Continuous Delivery, 2024, Trunk-Based Development изисква CI pipeline, който се изпълнява за 10–15 минути. Ако сборката отнеме повече време — разработчиците правят commit по-рядко, което унищожава смисъла на 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 (директни commits в trunk) и Git Flow. Клонът живее не повече от 1–2 дни, съдържа промени за 1–3 commits и след проверка (не повече от 4 часа чакане) се слива в trunk. Ако функцията изисква повече време — тя се разделя на подзадачи, всяка със свой краткоживеещ клон.
Според TBD Documentation, 2024, правила за краткоживеещи клонове: клонът се създава от пресен trunk (не по-стар от 1 час), не се синхронизира с trunk чрез merge/rebase (ако са изминали повече от 4 часа — се създава нов клон), MR/PR се създава веднага след първия commit (дори ако работата не е завършена — като Draft).
За Trunk-Based Development е важна техниката pre-tested commits: разработчикът преди commit стартира CI pipeline в своя клон и едва след зелен статус commit-ът попада в 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) изтрийте старата имплементация. Всички стъпки се commit-ват в 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 или слаба дисциплина на commits. Първата грешка — въвеждане на TBD без CI, което се чупи при първия неуспешен commit. Ако trunk не може да бъде поправен за 15 минути — екипът губи доверие в процеса и се връща към дълги клонове. Втората — разрешаване на дългоживеещи клонове „изключително за тази функция", което унищожава цялата концепция.
Според Paul Hammant, 2023, третата грешка — лоша модулност на кода. Trunk-Based Development изисква кодът да бъде разделен на независими модули. Ако промяна в един клас чупи три други модула — разработчиците не могат да правят commit на малки порции. Четвъртата — игнориране на feature toggles: опит за commit на незавършен код без флаг води до счупване на 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) и правят commit на код на малки порции няколко пъти на ден. Това намалява merge-конфликтите и ускорява Continuous Integration.
В TBD няма дългоживеещи feature-клонове и отделен develop-клон. Всички промени бързо се сливат в trunk, а незавършеният код се скрива зад feature toggles. Git Flow използва дълги клонове и строг процес на сливане чрез release и hotfix.
Да, feature toggles — ключов механизъм на TBD. Те позволяват да се прави commit на незавършен код в trunk без счупване на основния клон. Функцията е скрита зад флаг, който се включва при готовност. Това замества feature-клоновете на Git Flow.
Започнете с CI/CD: pipeline трябва да се изпълнява за 15–30 минути. Въведете feature toggles (Firebase Remote Config, LaunchDarkly). Използвайте short-lived branches от 1–2 дни с бърза проверка на кода. Разделете големите функции на малки подзадачи.
Основният риск — счупен trunk блокира целия екип. Без бърз CI (10–15 минути) и дисциплина на малките commits TBD не работи. Също така се изисква качествена модулна архитектура и опит с работата с feature toggles.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също