Trunk-Based Development는 장기간 유지되는 feature 브랜치 없이 모든 변경 사항을 단일 메인 브랜치(trunk)에 병합하는 개발 방식입니다. trunkbaseddevelopment.com, 2024에 따르면, Trunk-Based Development는 단기 브랜치(1~2일) 또는 feature toggles를 사용한 trunk에 대한 직접 커밋을 포함합니다. 이 접근 방식은 Continuous Integration 및 Continuous Deployment(CI/CD)와 결합되어 병합 충돌 수를 줄입니다.
핵심 사항
Trunk-Based Development (TBD)는 모든 개발자가 하루에 여러 번 변경 사항을 단일 메인 브랜치(trunk, main 또는 master)에 통합하는 버전 관리 방법론입니다. 장기간 유지되는 feature 브랜치를 사용하는 Git Flow와 달리, TBD는 브랜치 수명을 몇 시간, 드물게는 1~2일로 최소화합니다. 주요 목표는 대규모 기능을 수 주간 개발한 후 trunk에 병합할 때 발생하는 “병합 지옥”(merge hell)을 피하는 것입니다.
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는 높은 배포 빈도(deploy frequency)와 낮은 복구 시간(MTTR)과 상관관계가 있는 상위 3가지 관행에 포함되어 있습니다. TBD를 실천하는 팀은 코드를 2~3배 더 자주 배포하고 장애 복구 시간이 30% 더 빠릅니다(DORA, 2023).
Feature Toggles(기능 플래그)는 코드를 변경하지 않고 기능을 활성화/비활성화하는 메커니즘입니다. 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를 통과합니다.
// Android Kotlin에서의 Feature Toggle
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의 가장 중요한 구성 요소입니다. trunk(또는 MR 전 임시 브랜치)에 대한 각 push는 전체 파이프라인(빌드, 단위 테스트, 통합 테스트, 린터, 정적 분석, 코드 커버리지 검사)을 트리거합니다. 하나 이상의 단계가 실패하면 작성자는 다음 커밋 전에 코드를 수정합니다. “손상된 trunk — 개발 중단”이 TBD의 주요 규칙입니다.
Jez Humble, Continuous Delivery, 2024에 따르면, Trunk-Based Development는 10~15분 내에 완료되는 CI 파이프라인이 필요합니다. 빌드 시간이 더 오래 걸리면 개발자의 커밋 빈도가 줄어들어 TBD의 의미가 사라집니다. 모바일 프로젝트에서 Android 및 iOS 빌드는 20~30분이 소요될 수 있어 TBD의 편의성이 떨어집니다. 이러한 경우 팀은 즉시 CI와 함께 Short-Lived Feature Branches(1일 브랜치)를 사용합니다.
# TBD(Android)용 GitHub Actions
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시간 이내)에서 생성되며, merge/rebase를 통해 trunk와 동기화되지 않으며(4시간 이상 경과하면 새 브랜치 생성), MR/PR은 첫 번째 커밋 직후 생성됩니다(작업이 완료되지 않은 경우에도 Draft로).
Trunk-Based Development에서는 pre-tested commits 기술이 중요합니다. 개발자는 커밋 전에 자신의 브랜치에서 CI 파이프라인을 실행하고, 상태가 녹색인 경우에만 커밋이 trunk에 도달합니다. GitLab에서는 “Merge when pipeline succeeds” 옵션이 있는 Merge Request 파이프라인을 통해 구현됩니다. GitHub에서는 Required status checks가 있는 브랜치 보호 규칙을 통해 구현됩니다. 이렇게 하면 trunk에 손상된 코드가 포함되지 않습니다.
Branch by Abstraction은 장기간 유지되는 feature 브랜치를 생성하지 않고 시스템의 일부를 교체하거나 크게 변경할 수 있는 기술입니다. Git에서 브랜치를 만드는 대신 개발자는 추상화(인터페이스)를 만들고 그 아래에서 이전 구현과 새 구현이 모두 작동합니다. 점진적으로 모든 소비자가 새 구현으로 마이그레이션된 후 이전 구현이 제거됩니다.
Branch by Abstraction, 2024에 따르면, Branch by Abstraction 단계는 다음과 같습니다: 1) 교체할 구성 요소에 대한 추상화 생성, 2) 추상화 아래에서 새 버전 구현, 3) 구성을 통해 소비자를 새 구현으로 전환, 4) 이전 구현 제거. 모든 단계는 각각 CI/CD를 손상시키지 않는 작은 부분으로 trunk에 커밋됩니다.
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 또는 약한 커밋 규율과 관련됩니다. 첫 번째 실수는 CI 없이 TBD를 도입하는 것이며, 첫 번째 실패한 커밋에서 무너집니다. trunk를 15분 이내에 수정할 수 없으면 팀은 프로세스에 대한 신뢰를 잃고 긴 브랜치로 돌아갑니다. 두 번째 실수는 “이 기능만을 위해” 장기 브랜치를 허용하는 것이며, 이는 전체 개념을 파괴합니다.
Paul Hammant, 2023에 따르면, 세 번째 실수는 코드 모듈성이 낮은 것입니다. Trunk-Based Development는 코드가 독립적인 모듈로 분할되어야 합니다. 한 클래스의 변경이 다른 세 모듈을 손상시키면 개발자는 작은 부분으로 커밋할 수 없습니다. 네 번째 실수는 feature toggles를 무시하는 것입니다. 플래그 없이 미완성 코드를 커밋하려고 하면 팀 전체의 trunk가 손상됩니다.
Trunk-Based Development는 모바일 프로젝트에서 긴 빌드 시간(Android 및 iOS의 경우 20~30분)과 엄격한 품질 요구 사항으로 인해 특수성을 가집니다. Google과 Spotify는 모바일 개발에서 TBD를 사용하며, 병합 전 필수 CI 통과와 함께 단기 브랜치를 적용합니다. Feature toggles는 Firebase Remote Config 또는 LaunchDarkly를 통해 관리됩니다.
LaunchDarkly Docs, 2024에 따르면, 모바일 개발에서 TBD는 이점을 제공합니다. 기능은 릴리스 날짜 전에 trunk에서 나머지 코드와 함께 테스트되어 통합 문제의 위험이 줄어듭니다. CI 파이프라인이 15분 이상 걸리는 경우 각 push 시 자동 CI가 있는 1일 단기 브랜치가 최적입니다. Apple App Store 및 Google Play의 경우 TBD는 feature toggles를 통한 단계적 롤아웃 설정이 필요합니다.
TBD에서 feature toggles 관리를 위해 플랫폼이 사용됩니다: LaunchDarkly(엔터프라이즈, 모든 기능), Firebase Remote Config(소규모 프로젝트 무료), Split.io(오픈 소스). 이들은 사용자 비율별 대상 기능 활성화, A/B 테스트, 사용 모니터링, 오류 시 자동 비활성화를 제공합니다. 모바일 프로젝트에서 Firebase Remote Config는 Firebase와의 통합 및 최대 1000명 사용자까지 무료 제공으로 가장 인기 있는 선택입니다.
자주 묻는 질문
Trunk-Based Development (TBD)는 모든 개발자가 단일 메인 브랜치(trunk)에서 작업하고 하루에 여러 번 작은 단위로 코드를 커밋하는 접근 방식입니다. 이는 병합 충돌을 줄이고 Continuous Integration을 가속화합니다.
TBD에서는 장기간 유지되는 feature 브랜치와 별도의 develop 브랜치가 없습니다. 모든 변경 사항이 신속하게 trunk에 병합되고 미완성 코드는 feature toggles 뒤에 숨겨집니다. Git Flow는 긴 브랜치와 release 및 hotfix를 통한 엄격한 병합 프로세스를 사용합니다.
네, feature toggles는 TBD의 핵심 메커니즘입니다. 메인 브랜치를 손상시키지 않고 미완성 코드를 trunk에 커밋할 수 있습니다. 기능은 준비되면 활성화되는 플래그 뒤에 숨겨집니다. 이는 Git Flow의 feature 브랜치를 대체합니다.
CI/CD부터 시작하세요: 파이프라인이 15~30분 내에 완료되어야 합니다. Feature toggles(Firebase Remote Config, LaunchDarkly)를 구현하세요. 빠른 코드 검토와 함께 1~2일의 단기 브랜치를 사용하세요. 대규모 기능은 작은 하위 작업으로 분해하세요.
주요 위험은 손상된 trunk가 전체 팀을 차단한다는 것입니다. 빠른 CI(10~15분)와 작은 커밋 규율 없이는 TBD가 작동하지 않습니다. 또한 고품질의 모듈식 아키텍처와 feature toggles에 대한 경험이 필요합니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.