Trunk-Based Development คือแนวปฏิบัติการพัฒนาที่การเปลี่ยนแปลงทั้งหมดถูกรวมเข้ากับสาขาหลักเดียว (trunk) โดยไม่มีสาขาคุณลักษณะที่มีอายุยาวนาน ตามข้อมูลจาก trunkbaseddevelopment.com, 2024 Trunk-Based Development เกี่ยวข้องกับสาขาระยะสั้น (1–2 วัน) หรือคอมมิตโดยตรงไปยัง trunk โดยใช้ feature toggles แนวทางนี้ทำงานร่วมกับ Continuous Integration และ Continuous Deployment (CI/CD) และลดจำนวนความขัดแย้งในการรวม
ประเด็นสำคัญ
Trunk-Based Development (TBD) คือวิธีการจัดการเวอร์ชันที่นักพัฒนาทุกคนรวมการเปลี่ยนแปลงของตนเข้ากับสาขาหลักเดียว (trunk, main หรือ master) หลายครั้งต่อวัน แตกต่างจาก Git Flow ที่มีสาขาคุณลักษณะอายุยาวนาน 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 ใช้สาขาคุณลักษณะระยะสั้นซึ่งหลังจากสร้าง 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 แทนที่สาขาคุณลักษณะ: นักพัฒนาคอมมิตโค้ดที่ยังไม่เสร็จไปยัง 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) จะเรียกใช้ไปป์ไลน์ที่สมบูรณ์: บิวด์, การทดสอบหน่วย, การทดสอบการรวม, ลินเตอร์, การวิเคราะห์แบบคงที่, การตรวจสอบความครอบคลุมโค้ด หากอย่างน้อยหนึ่งขั้นตอนล้มเหลว ผู้เขียนจะแก้ไขโค้ดก่อนคอมมิตถัดไป “trunk เสียหาย — หยุดการพัฒนา” เป็นกฎหลักของ TBD
ตามข้อมูลจาก Jez Humble, Continuous Delivery, 2024 Trunk-Based Development ต้องการไปป์ไลน์ CI ที่เสร็จภายใน 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 ในสาขาของตนก่อนคอมมิต และหลังจากสถานะเป็นสีเขียวเท่านั้น คอมมิตจึงจะถึง trunk ใน GitLab สิ่งนี้ถูกนำไปใช้ผ่าน Merge Request pipelines ด้วยตัวเลือก “Merge when pipeline succeeds” ใน GitHub — ผ่าน branch protection rules ที่มี Required status checks สิ่งนี้รับประกันว่า trunk จะไม่มีโค้ดที่เสียหาย
Branch by Abstraction เป็นเทคนิคที่ช่วยให้สามารถแทนที่หรือเปลี่ยนแปลงส่วนหนึ่งของระบบอย่างมีนัยสำคัญโดยไม่ต้องสร้างสาขาคุณลักษณะที่มีอายุยาวนาน แทนที่จะแตกสาขาใน 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 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 ในการพัฒนามือถือ โดยใช้สาขาระยะสั้นกับการผ่าน CI ที่จำเป็นก่อนการรวม Feature toggles ถูกจัดการผ่าน Firebase Remote Config หรือ LaunchDarkly
ตามข้อมูลจาก LaunchDarkly Docs, 2024 ในการพัฒนามือถือ TBD ให้ข้อได้เปรียบ: คุณลักษณะถูกทดสอบใน trunk พร้อมกับโค้ดที่เหลือก่อนวันที่เผยแพร่ ซึ่งลดความเสี่ยงของปัญหาการรวม หากไปป์ไลน์ CI ใช้เวลามากกว่า 15 นาที สาขาระยะสั้น 1 วันพร้อม CI อัตโนมัติในทุก push จะเหมาะสมที่สุด สำหรับ Apple App Store และ Google Play TBD ต้องการการตั้งค่าการปรับใช้แบบเป็นขั้นตอนผ่าน feature toggles
สำหรับการจัดการ feature toggles ใน TBD ใช้แพลตฟอร์ม: LaunchDarkly (ระดับองค์กร, ครบครัน), Firebase Remote Config (ฟรีสำหรับโปรเจกต์ขนาดเล็ก), Split.io (โอเพนซอร์ส) พวกเขาให้: การเปิดใช้งานคุณลักษณะตามเป้าหมายตามเปอร์เซ็นต์ผู้ใช้, การทดสอบ A/B, การตรวจสอบการใช้งาน และการปิดใช้งานอัตโนมัติเมื่อเกิดข้อผิดพลาด ในโปรเจกต์มือถือ Firebase Remote Config เป็นตัวเลือกที่ได้รับความนิยมมากที่สุดเนื่องจากการรวมกับ Firebase และเกณฑ์ฟรีสูงสุด 1,000 ผู้ใช้
คำถามที่พบบ่อย
Trunk-Based Development (TBD) เป็นแนวทางที่นักพัฒนาทุกคนทำงานในสาขาหลักเดียว (trunk) และคอมมิตโค้ดในส่วนย่อยๆ หลายครั้งต่อวัน สิ่งนี้ลดความขัดแย้งในการรวมและเร่ง Continuous Integration
ใน TBD ไม่มีสาขาคุณลักษณะอายุยาวนานและไม่มีสาขา develop แยกต่างหาก การเปลี่ยนแปลงทั้งหมดถูกรวมเข้ากับ trunk อย่างรวดเร็ว และโค้ดที่ยังไม่เสร็จถูกซ่อนไว้หลัง feature toggles Git Flow ใช้สาขายาวและกระบวนการรวมที่เข้มงวดผ่าน release และ hotfix
ใช่, feature toggles เป็นกลไกสำคัญของ TBD พวกมันอนุญาตให้คอมมิตโค้ดที่ยังไม่เสร็จไปยัง trunk โดยไม่ทำให้สาขาหลักเสียหาย คุณลักษณะถูกซ่อนไว้หลังธงที่เปิดใช้งานเมื่อพร้อม สิ่งนี้แทนที่สาขาคุณลักษณะของ Git Flow
เริ่มต้นด้วย CI/CD: ไปป์ไลน์ควรเสร็จภายใน 15–30 นาที นำ feature toggles ไปใช้ (Firebase Remote Config, LaunchDarkly) ใช้สาขาระยะสั้น 1–2 วันพร้อมการตรวจสอบโค้ดที่รวดเร็ว แบ่งคุณลักษณะขนาดใหญ่ออกเป็นงานย่อยเล็กๆ
ความเสี่ยงหลัก คือ trunk ที่เสียหายจะบล็อกทั้งทีม หากไม่มี CI ที่รวดเร็ว (10–15 นาที) และวินัยในการคอมมิตเล็กๆ TBD จะไม่ทำงาน นอกจากนี้ยังต้องการสถาปัตยกรรมแบบโมดูลที่มีคุณภาพและประสบการณ์กับ feature toggles
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม