Trunk-Based Development — روش توسعهای است که در آن تمام تغییرات بدون شاخههای طولانیمدت feature در یک شاخه اصلی واحد (trunk) ادغام میشوند. به گفته trunkbaseddevelopment.com, 2024، Trunk-Based Development شامل شاخههای کوتاهمدت (1–2 روز) یا commitهای مستقیم به 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 commit میکنند. در 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 commit میکند اما آن را پشت یک پرچم شرطی پنهان میکند. وقتی ویژگی آماده نمایش شد، پرچم بدون استقرار مجدد در پیکربندی تغییر میکند.
به گفته 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 به pipeline CI نیاز دارد که در 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 خالص (commitهای مستقیم به trunk) و Git Flow. شاخه بیش از 1–2 روز عمر نمیکند، شامل تغییرات 1–3 commit است و پس از بررسی (بیش از 4 ساعت انتظار) در trunk ادغام میشود. اگر ویژگی به زمان بیشتری نیاز دارد — به زیروظایفی تقسیم میشود که هر کدام شاخه کوتاهمدت خود را دارند.
به گفته TBD Documentation, 2024، قوانین شاخههای کوتاهمدت: شاخه از trunk تازه ایجاد میشود (نه قدیمیتر از 1 ساعت)، از طریق merge/rebase با trunk همگامسازی نمیشود (اگر بیش از 4 ساعت گذشته باشد — شاخه جدیدی ایجاد میشود)، MR/PR بلافاصله پس از اولین commit ایجاد میشود (حتی اگر کار کامل نشده باشد — به عنوان Draft).
برای Trunk-Based Development تکنیک pre-tested commits مهم است: توسعهدهنده قبل از commit pipeline CI را در شاخه خود راهاندازی میکند و فقط پس از وضعیت سبز 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) پیادهسازی قدیمی را حذف کنید. تمام مراحل به صورت قطعات کوچک به trunk commit میشوند که هیچکدام 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 ناکافی یا انضباط ضعیف commit مرتبط هستند. اولین اشتباه — پیادهسازی 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 قبل از merge به کار میبرند. Feature toggles از طریق Firebase Remote Config یا LaunchDarkly مدیریت میشوند.
به گفته LaunchDarkly Docs, 2024، در توسعه موبایل TBD مزیت میدهد: ویژگیها در trunk همراه با بقیه کد قبل از تاریخ انتشار تست میشوند که خطر مشکلات یکپارچگی را کاهش میدهد. اگر pipeline CI بیش از 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 هستند. آنها اجازه میدهند کد ناتمام بدون شکستن شاخه اصلی به trunk commit شود. ویژگی پشت یک پرچم پنهان میشود که هنگام آماده شدن فعال میشود. این جایگزین شاخههای feature در Git Flow میشود.
با CI/CD شروع کنید: pipeline باید در 15–30 دقیقه اجرا شود. Feature toggles (Firebase Remote Config, LaunchDarkly) را پیادهسازی کنید. از short-lived branches 1–2 روزه با بررسی سریع کد استفاده کنید. ویژگیهای بزرگ را به زیروظایف کوچک تقسیم کنید.
خطر اصلی — trunk شکسته کل تیم را مسدود میکند. بدون CI سریع (10–15 دقیقه) و انضباط commitهای کوچک، TBD کار نمیکند. همچنین معماری ماژولار با کیفیت و تجربه کار با feature toggles مورد نیاز است.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید