Git & GitHub

Trunk-Based Development

13 min Lesson 26 of 35

Trunk-Based Development

Trunk-Based Development (TBD) is a version control workflow where developers collaborate on code in a single branch called "trunk" (or "main"), resisting the urge to create long-lived feature branches. This approach promotes continuous integration and enables rapid deployment.

What is Trunk-Based Development?

In Trunk-Based Development, all developers work on the main branch (trunk) and commit their changes frequently. Feature branches, if used at all, are short-lived (typically less than 24 hours) and merged back to trunk quickly.

Key Principle: Trunk-Based Development emphasizes "integrate early, integrate often" to reduce merge conflicts and enable continuous delivery.

Core Characteristics

1. Single Main Branch: - All code merges into trunk/main - Trunk is always in a releasable state - No long-lived feature branches 2. Short-Lived Feature Branches: - Branches live for hours, not days/weeks - Created for specific tasks - Merged quickly via pull requests 3. Frequent Commits: - Developers commit multiple times per day - Small, incremental changes - Continuous integration with trunk 4. Feature Flags: - Incomplete features hidden behind flags - Allows merging incomplete code safely - Enable/disable features at runtime

The Trunk-Based Development Workflow

Here's how developers work in TBD:

# 1. Pull latest changes from trunk git checkout main git pull origin main # 2. Create a short-lived feature branch git checkout -b feature/add-login-validation # 3. Make small, focused changes # Edit files... git add . git commit -m "Add email validation to login form" # 4. Push and create pull request (within hours) git push origin feature/add-login-validation # 5. After review, merge to main and delete branch # Via GitHub UI or: git checkout main git merge feature/add-login-validation git branch -d feature/add-login-validation git push origin --delete feature/add-login-validation # 6. Pull merged changes git pull origin main
Best Practice: Feature branches should be merged within one working day. If your branch lives longer, you're not practicing true Trunk-Based Development.

Feature Flags for Incomplete Work

Feature flags allow you to merge incomplete code to trunk without exposing it to users:

Example: PHP Feature Flag // config/features.php return [ 'new_dashboard' => env('FEATURE_NEW_DASHBOARD', false), 'ai_recommendations' => env('FEATURE_AI_RECS', false), ]; // In your code if (config('features.new_dashboard')) { return view('dashboard.new'); } else { return view('dashboard.legacy'); } // .env file FEATURE_NEW_DASHBOARD=false # Hidden in production FEATURE_AI_RECS=true # Enabled in production
Benefit: Feature flags decouple deployment from feature release. Deploy code anytime, release features when ready.

Release Branches in TBD

While feature branches are short-lived, release branches are used for production releases:

Release Branch Strategy: # Create release branch from main git checkout main git checkout -b release/v2.1.0 # Bug fixes for this release go here git commit -m "Fix critical login bug for v2.1.0" # Tag the release git tag -a v2.1.0 -m "Release version 2.1.0" git push origin release/v2.1.0 git push origin v2.1.0 # Cherry-pick bug fixes back to main git checkout main git cherry-pick <commit-hash> # Release branch stays for hotfixes

Advantages of Trunk-Based Development

✓ Reduced Merge Conflicts: - Frequent integration means smaller diffs - Conflicts discovered and resolved early ✓ Faster Feedback: - Changes reviewed and tested quickly - Issues detected within hours, not weeks ✓ Continuous Integration: - Automated tests run on every commit - Broken builds fixed immediately ✓ Simplified Workflow: - No complex branching strategies - Easier for new team members ✓ Enables Continuous Deployment: - Main branch always deployable - Release anytime with confidence ✓ Better Code Quality: - Frequent reviews catch issues early - Smaller changes easier to review

Challenges and Solutions

Challenge: Breaking Changes Solution: Use feature flags and backward compatibility Challenge: Incomplete Features Solution: Hide behind feature flags, use abstractions Challenge: Team Discipline Required Solution: Automate checks, enforce through CI/CD Challenge: Requires Strong CI/CD Solution: Invest in automated testing and deployment Challenge: Code Review Speed Solution: Keep PRs small, prioritize reviews, automate checks
Important: Trunk-Based Development requires excellent automated testing. Without comprehensive tests, frequent integration becomes risky.

CI/CD Requirements for TBD

Successful Trunk-Based Development depends on robust automation:

Essential Automated Checks: 1. Automated Tests: - Unit tests (run in seconds) - Integration tests (run in minutes) - Minimum 80% code coverage 2. Linting and Formatting: - Code style checks - Static analysis - Security scanning 3. Build Verification: - Compilation checks - Dependency verification - Asset building 4. Deployment Pipeline: - Staging deployment - Smoke tests - Production deployment

Example: GitHub Actions for TBD

# .github/workflows/trunk.yml name: Trunk Integration on: push: branches: [ main ] pull_request: branches: [ main ] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Run tests run: | composer install php artisan test - name: Code quality run: | ./vendor/bin/phpstan analyse ./vendor/bin/php-cs-fixer fix --dry-run - name: Security scan run: composer audit deploy: needs: test if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - name: Deploy to staging run: ./deploy-staging.sh

When to Use Trunk-Based Development

✓ Good For: - Teams practicing continuous integration - Projects with strong automated testing - SaaS products with continuous deployment - Mature DevOps practices - High-trust, experienced teams ✗ Not Ideal For: - Teams without automated testing - Projects with infrequent releases - Open source with many external contributors - Legacy codebases without CI/CD - Teams new to Git workflows
Tip: Start with GitHub Flow if you're new to collaborative Git workflows. Graduate to Trunk-Based Development when your team has mature CI/CD practices.

TBD vs Other Workflows

Git Flow: - Multiple long-lived branches (develop, feature, release, hotfix) - More ceremony and process - Better for scheduled releases GitHub Flow: - Feature branches + main - Middle ground between Git Flow and TBD - Good for continuous deployment Trunk-Based Development: - Minimal branching (or no branches) - Maximum integration frequency - Best for elite DevOps teams

Best Practices for TBD

1. Commit Frequently: At least once per day to trunk 2. Keep PRs Small: Under 400 lines of code 3. Review Quickly: PRs reviewed within 1-2 hours 4. Fix Failures Immediately: Broken builds are top priority 5. Use Feature Flags: For incomplete features 6. Automate Everything: Tests, deployment, rollback 7. Pair Programming: Reduces need for formal reviews 8. Branch by Abstraction: For large refactoring

Practice Exercise:

Scenario: Your team wants to adopt Trunk-Based Development. You need to implement a new feature (user profile page) that will take 3 days to complete, but you want to commit to trunk daily.

Task:

  1. Design a feature flag system for the user profile feature
  2. Break the work into daily mergeable chunks
  3. Write commit messages for each day's work

Solution:

Day 1: Backend API git checkout -b feature/profile-api # Build profile data endpoint (hidden behind flag) git commit -m "Add user profile API endpoint (behind feature flag)" # Merge to main - API exists but not exposed to frontend Day 2: Frontend Structure git checkout -b feature/profile-ui # Build profile UI components (hidden behind flag) git commit -m "Add profile page UI components (feature flagged)" # Merge to main - UI exists but route not public Day 3: Integration & Polish git checkout -b feature/profile-integration # Connect frontend to backend, styling, tests git commit -m "Integrate profile page and add tests" # Merge to main - complete but still behind flag # Enable flag when ready: FEATURE_USER_PROFILE=true

Summary

In this lesson, you learned:

  • Trunk-Based Development uses a single main branch for collaboration
  • Feature branches are short-lived (less than 24 hours)
  • Feature flags enable merging incomplete code safely
  • Strong CI/CD automation is essential for TBD success
  • TBD reduces merge conflicts and enables continuous deployment
  • Best suited for mature teams with excellent testing practices
Next Up: In the next lesson, we'll explore code review best practices to ensure quality in collaborative development!