Trunk-Based Development — praktyka programistyczna, w której wszystkie zmiany są scalane do jednej głównej gałęzi (trunk) bez długożyjących gałęzi feature. Według danych trunkbaseddevelopment.com, 2024, Trunk-Based Development zakłada krótkożyjące gałęzie (1–2 dni) lub bezpośrednie commity do trunk z użyciem feature toggles. To podejście łączy się z Continuous Integration i Continuous Deployment (CI/CD) oraz zmniejsza liczbę konfliktów merge.
Najważniejsze
Trunk-Based Development (TBD) — metodologia zarządzania wersjami, w której wszyscy programiści integrują swoje zmiany w jednej głównej gałęzi (trunk, main lub master) kilka razy dziennie. W przeciwieństwie do Git Flow z jego długożyjącymi gałęziami feature, TBD minimalizuje czas życia gałęzi do kilku godzin, rzadziej do 1–2 dni. Głównym celem jest uniknięcie „piekła scalania” (merge hell), gdy duża funkcja jest scalana z trunk po tygodniach rozwoju.
Według danych Google Cloud DevOps, 2024, Trunk-Based Development jest jedną z kluczowych praktyk wysokowydajnych zespołów DevOps. Badanie State of DevOps Report (Puppet, 2023) wykazało, że zespoły używające TBD o 30% szybciej odzyskują sprawność po awariach i o 50% rzadziej spotykają krytyczne defekty na produkcji. TBD jest obowiązkowy dla Continuous Deployment.
Trunk-Based Development nie oznacza, że programiści commitują bezpośrednio do trunk bez weryfikacji. W TBD używa się krótkożyjących gałęzi feature, które po utworzeniu MR i szybkim code review (w ciągu kilku godzin) są scalane z trunk. Jeśli review trwa dłużej niż jeden dzień — oznacza to, że funkcję należy podzielić na mniejsze części.
Coroczny State of DevOps Report (Puppet/DORA) śledzi praktyki wysokowydajnych zespołów. Od 2015 roku TBD znajduje się w top 3 praktyk korelujących z wysoką częstotliwością dostarczania (deploy frequency) i niskim czasem odzyskiwania (MTTR). Zespoły praktykujące TBD wdrażają kod 2–3 razy częściej i odzyskują sprawność po awariach o 30% szybciej (DORA, 2023).
Feature Toggles (flagi funkcji, feature flags) — mechanizm włączania i wyłączania funkcjonalności bez zmiany kodu. W TBD feature toggles zastępują gałęzie feature: programista commituje niedokończony kod do trunk, ale ukrywa go za warunkową flagą. Gdy funkcja jest gotowa do pokazania, flaga jest przełączana w konfiguracji bez ponownego wdrożenia.
Według danych Martin Fowler, 2024, feature toggles dzielą się na cztery typy: release toggles (zarządzanie widocznością funkcji), experiment toggles (testy A/B), ops toggles (zarządzanie parametrami operacyjnymi) i permission toggles (dostęp według ról). W projektach mobilnych release toggles są szczególnie przydatne: nowa funkcjonalność jest ukryta do daty wydania, ale kod jest już w trunk i przechodzi CI/CD.
// Feature Toggle w Android na Kotlin
object FeatureManager {
private val remoteConfig = FirebaseRemoteConfig.getInstance()
fun isEnabled(key: String): Boolean {
return remoteConfig.getBoolean(key)
}
}
// Użycie w kodzie
if (FeatureManager.isEnabled("new_checkout_flow")) {
showNewCheckoutScreen()
} else {
showOldCheckoutScreen()
}
Continuous Integration (CI) — najważniejszy komponent TBD. Każdy push do trunk (lub do tymczasowej gałęzi przed MR) uruchamia pełny pipeline: budowa, testy jednostkowe, testy integracyjne, lintery, analiza statyczna, sprawdzenie pokrycia kodu. Jeśli choć jeden etap upada — autor zmian naprawia kod przed następnym commitem. „Zepsuty trunk — zatrzymany rozwój” to główna zasada TBD.
Według danych Jez Humble, Continuous Delivery, 2024, Trunk-Based Development wymaga pipeline'u CI, który wykonuje się w 10–15 minut. Jeśli budowa trwa dłużej — programiści rzadziej commitują, co niszczy sens TBD. W projektach mobilnych Android i iOS budowa może trwać 20–30 minut, co czyni TBD mniej wygodnym. W takich przypadkach zespoły używają Short-Lived Feature Branches (gałęzie na 1 dzień) z natychmiastowym CI.
# GitHub Actions dla 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
Krótkożyjące gałęzie (short-lived branches) — kompromis między czystym TBD (commity bezpośrednio do trunk) a Git Flow. Gałąź żyje nie dłużej niż 1–2 dni, zawiera zmiany na 1–3 commity i po review (nie więcej niż 4 godziny oczekiwania) jest scalana z trunk. Jeśli funkcja wymaga więcej czasu — dzieli się ją na podzadania, każde z własną krótkożyjącą gałęzią.
Według danych TBD Documentation, 2024, zasady krótkożyjących gałęzi: gałąź tworzona jest od świeżego trunk (nie starszego niż 1 godzina), nie synchronizuje się z trunk przez merge/rebase (jeśli minęło więcej niż 4 godziny — tworzona jest nowa gałąź), MR/PR tworzony jest natychmiast po pierwszym commitcie (nawet jeśli praca nie jest zakończona — jako Draft).
Dla Trunk-Based Development ważna jest technika pre-tested commits: programista przed commitem uruchamia pipeline CI w swojej gałęzi i dopiero po zielonym statusie commit trafia do trunk. W GitLab jest to realizowane przez Merge Request pipelines z opcją „Merge when pipeline succeeds”. W GitHub — przez branch protection rules z Required status checks. Gwarantuje to, że trunk nigdy nie zawiera zepsutego kodu.
Branch by Abstraction — technika pozwalająca zastąpić lub znacząco zmienić część systemu bez tworzenia długożyjącej gałęzi feature. Zamiast rozgałęziania w Git programista tworzy abstrakcję (interfejs), pod którą działają zarówno stara, jak i nowa implementacja. Stopniowo wszyscy konsumenci są przenoszeni na nową implementację, po czym stara jest usuwana.
Według danych Branch by Abstraction, 2024, etapy Branch by Abstraction: 1) utwórz abstrakcję dla zastępowanego komponentu, 2) zaimplementuj nową wersję pod abstrakcją, 3) przełącz konsumentów na nową implementację przez konfigurację, 4) usuń starą implementację. Wszystkie kroki są commitowane do trunk małymi porcjami, z których żadna nie psuje CI/CD.
Trunk-Based Development i Git Flow — dwa przeciwstawne podejścia do zarządzania gałęziami. Git Flow używa długożyjących gałęzi i ścisłej hierarchii, TBD — jednej gałęzi i krótkich cykli integracji. Wybór między nimi zależy od rozmiaru zespołu, częstotliwości wydań i poziomu automatyzacji CI/CD.
| Parametr | Trunk-Based Development | Git Flow |
|---|---|---|
| Gałęzi | Jedna (trunk) + short-lived | Pięć typów (main, develop, feature, release, hotfix) |
| Czas życia gałęzi | Godziny–1 dzień | Dni–tygodnie |
| Gałęzie feature | Niezalecane | Główny mechanizm |
| Feature Toggles | Obowiązkowe | Opcjonalne |
| CI obowiązkowość | Absolutna | Zalecana |
| Continuous Deployment | Zgodny | Trudny |
| Złożoność | Niska | Wysoka |
Błędy TBD najczęściej wiążą się z niewystarczającym CI/CD lub słabą dyscypliną commitów. Pierwszy błąd — wdrożenie TBD bez CI, które załamuje się przy pierwszym nieudanym commitcie. Jeśli trunk nie może być naprawiony w 15 minut — zespół traci zaufanie do procesu i wraca do długich gałęzi. Drugi — zezwolenie na długożyjące gałęzie „wyłącznie dla tej funkcji”, co niszczy całą koncepcję.
Według danych Paul Hammant, 2023, trzeci błąd — słaba modułowość kodu. Trunk-Based Development wymaga, aby kod był podzielony na niezależne moduły. Jeśli zmiana w jednej klasie psuje trzy inne moduły — programiści nie mogą commitować małymi porcjami. Czwarty — ignorowanie feature toggles: próba commitowania niedokończonego kodu bez flagi prowadzi do zepsucia trunk dla całego zespołu.
Trunk-Based Development w projektach mobilnych ma specyfikę ze względu na długi czas budowy (20–30 minut dla Android i iOS) oraz rygorystyczne wymagania jakościowe. Google i Spotify używają TBD w programowaniu mobilnym, stosując short-lived branches z obowiązkowym przejściem CI przed mergem. Feature toggles są zarządzane przez Firebase Remote Config lub LaunchDarkly.
Według danych LaunchDarkly Docs, 2024, w programowaniu mobilnym TBD daje przewagę: funkcje są testowane w trunk wraz z resztą kodu przed datą wydania, co zmniejsza ryzyko problemów integracyjnych. Jeśli pipeline CI zajmuje więcej niż 15 minut — optymalne są short-lived branches na 1 dzień z automatycznym CI przy każdym pushu. Dla Apple App Store i Google Play TBD wymaga skonfigurowania staged rollouts przez feature toggles.
Do zarządzania feature toggles w TBD używane są platformy: LaunchDarkly (enterprise, pełna funkcjonalność), Firebase Remote Config (bezpłatna dla małych projektów), Split.io (open-source). Oferują one: docelowe włączanie funkcji według procentu użytkowników, testy A/B, monitorowanie użycia i automatyczne wyłączanie przy błędach. W projektach mobilnych Firebase Remote Config jest najpopularniejszym wyborem ze względu na integrację z Firebase i darmowy próg do 1000 użytkowników.
Często zadawane pytania
Trunk-Based Development (TBD) — podejście, w którym wszyscy programiści pracują w jednej głównej gałęzi (trunk) i commitują kod małymi porcjami kilka razy dziennie. Zmniejsza to konflikty merge i przyspiesza Continuous Integration.
W TBD nie ma długożyjących gałęzi feature ani osobnej gałęzi develop. Wszystkie zmiany są szybko scalane z trunk, a niedokończony kod jest ukrywany za feature toggles. Git Flow używa długich gałęzi i ścisłego procesu scalania przez release i hotfix.
Tak, feature toggles — kluczowy mechanizm TBD. Pozwalają commitować niedokończony kod do trunk bez psucia głównej gałęzi. Funkcja jest ukryta za flagą, która jest włączana po ukończeniu. Zastępuje to gałęzie feature z Git Flow.
Zacznij od CI/CD: pipeline powinien wykonywać się w 15–30 minut. Wdróż feature toggles (Firebase Remote Config, LaunchDarkly). Używaj short-lived branches na 1–2 dni z szybkim code review. Dekomponuj duże funkcje na małe podzadania.
Główne ryzyko — zepsuty trunk blokuje cały zespół. Bez szybkiego CI (10–15 minut) i dyscypliny małych commitów TBD nie działa. Wymagana jest również dobra architektura modułowa i doświadczenie w pracy z feature toggles.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również