Vous en avez marre des merge conflicts monstres ? Des feature branches qui durent 3 semaines ? Des hotfixes qui cassent tout ? Il existe une alternative plus simple : le Trunk-Based Development.

Le problème avec Git Flow

Git Flow : Le standard qui ne scale pas

┌─────────┐
│ master  │────────────────────────────
└─────────┘     merge      merge
     │
┌────▼────┐
│ develop │───────────────────
└─────────┘  merge   merge
     │
┌────▼────────┐
│ feature/123 │─────────
└─────────────┘

Problèmes réels :

  1. Merge hell : Plus la branche vit, plus les conflicts sont difficiles
  2. Integration tardive : On découvre les bugs à la fin
  3. Complexité : Develop, release, hotfix, feature… 4 types de branches
  4. Slow feedback : PR mergée après plusieurs jours

Chez un client :

  • Feature branch moyenne : 8.5 jours
  • Merge conflicts : 40% des PRs
  • Time to production : 2-3 semaines

Trunk-Based Development : La solution

Principe simple

Tout le monde commit sur la même branche (trunk/main) plusieurs fois par jour.

main ───●───●───●───●───●───●───●───●───
      Dev1 Dev2 Dev1 Dev3 Dev2 Dev1 Dev4

Règles :

  1. Commits fréquents (plusieurs fois/jour)
  2. Petits changements (< 400 lignes)
  3. CI/CD obligatoire
  4. Feature flags pour code incomplet

“Mais c’est dangereux !”

Objection : “On va casser la prod !”

Réponse : Pas si vous avez :

  • Tests automatisés solides
  • CI qui bloque si tests fail
  • Feature flags
  • Monitoring proactif

Les géants de la tech le font :

  • Google : 25,000 engineers, 1 trunk
  • Facebook : Commits toutes les 15min
  • Netflix, Amazon, etc.

Migration : Notre approche progressive

Phase 1 : Réduire la durée de vie des branches

Avant :

Feature branch : 8 jours

Objectif :

Semaine 1-2 : Max 5 jours
Semaine 3-4 : Max 3 jours
Semaine 5-6 : Max 2 jours
Semaine 7+  : Max 1 jour

Comment :

  • Découper features en petites tâches
  • Review quotidiennes obligatoires
  • Alerte automatique si branch > 2 jours

Phase 2 : Short-lived branches

main ───●────────●─────────●────────
         \      /   \     /
          ●────●     ●───●
         (2h)      (4h)

Règles :

  • Max 24h de vie
  • Max 400 lignes changées
  • Merge dès que CI passe

Phase 3 : Direct commits sur main (optionnel)

Réservé aux équipes très matures :

# Direct push sur main (avec protection)
git push origin main

# CI vérifie automatiquement :
# - Tests passent
# - Coverage > 80%
# - Linting OK
# - Security scan OK

# Si KO : Auto-revert

Feature Flags : La clé du succès

Sans feature flags

// ❌ Code incomplet visible en prod
function checkout() {
  // Nouvelle feature pas finie
  if (newPaymentFlow) {
    // TODO: implémenter
  }
}

Avec feature flags

// ✅ Code en prod mais invisible
import { isEnabled } from './feature-flags';

function checkout() {
  if (isEnabled('new-payment-flow')) {
    return newPaymentFlow();
  }
  return oldPaymentFlow();
}

Avantages :

  • Merge code incomplet en toute sécurité
  • Test en prod avec % users
  • Rollback instantané (toggle flag)
  • A/B testing facile

Feature flags en pratique

// feature-flags.ts
export const flags = {
  'new-payment-flow': {
    enabled: true,
    rollout: 10,  // 10% des users
    targeting: {
      countries: ['FR', 'BE'],
      userTier: 'premium'
    }
  }
};

export function isEnabled(flag: string, context?: any): boolean {
  const config = flags[flag];
  if (!config?.enabled) return false;

  // Rollout progressif
  if (Math.random() * 100 > config.rollout) return false;

  // Targeting
  if (config.targeting) {
    return matchesTargeting(context, config.targeting);
  }

  return true;
}

Solutions existantes :

CI/CD : Configuration requise

Pipeline exemple

# .github/workflows/trunk.yml
name: Trunk CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      # Tests rapides d'abord (fail fast)
      - name: Lint
        run: npm run lint

      - name: Unit tests
        run: npm run test:unit

      - name: Integration tests
        run: npm run test:integration

      # Build
      - name: Build
        run: npm run build

      # Security
      - name: Security scan
        run: npm run security-check

      # Deploy si main
      - name: Deploy to staging
        if: github.ref == 'refs/heads/main'
        run: ./deploy.sh staging

      # Deploy prod avec feature flags
      - name: Deploy to production
        if: github.ref == 'refs/heads/main'
        run: ./deploy.sh production

Durée : < 10 minutes (objectif : < 5min)

Protection branch main

// GitHub branch protection
{
  "branch": "main",
  "protection": {
    "required_status_checks": {
      "strict": true,
      "contexts": [
        "test",
        "lint",
        "security-scan"
      ]
    },
    "required_reviews": {
      "required_approving_review_count": 1,
      "dismiss_stale_reviews": true
    },
    "enforce_admins": true,
    "allow_force_pushes": false
  }
}

Code Review : Adapter le process

Review rapides obligatoires

Avant (Git Flow) :

  • Feature complète à review
  • 500-1000 lignes
  • Review le lendemain
  • 3-4 aller-retours

Après (Trunk-Based) :

  • Petit changement
  • < 400 lignes
  • Review dans l’heure
  • 1-2 aller-retours max

Process review optimisé

09h00 : Dev1 crée PR (150 lignes)
09h30 : Dev2 review (15min)
09h45 : Dev1 corrige commentaires
10h00 : Merge + Deploy staging
10h15 : Tests smoke OK
10h30 : Deploy production (feature flag 5%)

Temps total : 1h30 au lieu de 2 jours

Review checklist

## PR Checklist

### Size
- [ ] < 400 lignes changées
- [ ] 1 feature/fix par PR

### Tests
- [ ] Tests unitaires ajoutés
- [ ] Coverage maintenu (>80%)
- [ ] Tests d'intégration si nécessaire

### Code Quality
- [ ] Lint passe
- [ ] Pas de code commenté
- [ ] Documentation à jour

### Feature Flags
- [ ] Feature flag si code incomplet
- [ ] Rollout progressif configuré

### Backward Compatibility
- [ ] Pas de breaking change
- [ ] Migration planifiée si besoin

Métriques de succès

Chez un client (6 mois de Trunk-Based)

Developer Experience :

  • Time to merge : 2.5 jours → 4h (-94%)
  • Merge conflicts : 40% → 5% PRs
  • Lines changed/PR : 850 → 280 (-67%)

Quality :

  • Bugs production : -35%
  • Incidents : -42%
  • MTTR : 2h → 25min (-79%)

Business :

  • Time to production : 2 semaines → 1 jour (-93%)
  • Deploys/week : 3 → 42 (+1300%)
  • Developer satisfaction : 6.2 → 8.7 /10

Erreurs à éviter

Erreur 1 : Pas de feature flags

// ❌ Code incomplet pushé sans flag
function newFeature() {
  // TODO: finir demain
}

Résultat : Feature cassée en prod.

Erreur 2 : PRs trop grosses

❌ PR #123: Refonte page checkout (1200 lignes)

Solution : Découper en 4-5 PRs de 250-300 lignes chacune.

Erreur 3 : Tests insuffisants

Sans tests solides, trunk-based = chaos.

Minimum requis :

  • Coverage > 80%
  • Tests E2E sur parcours critiques
  • CI < 10 minutes

Erreur 4 : Skip code review

“On merge direct, on verra après”

Résultat : Dette technique explosive.

Solution : Review obligatoire, même pour petits changements.

Outils recommandés

Feature Flags

  • Unleash (Open Source) - Self-hosted
  • LaunchDarkly (SaaS) - Enterprise
  • Flagsmith (Hybrid) - Flexible

CI/CD

  • GitHub Actions - Simple et intégré
  • GitLab CI - Complet
  • CircleCI - Rapide

Monitoring

  • Sentry - Error tracking
  • Datadog - Observability
  • Grafana - Dashboards

Trunk-Based pour différents contextes

Startup (5-10 devs)

✅ Trunk pur (direct commits)
✅ Feature flags simples
✅ CI/CD basique mais rapide

Scale-up (20-50 devs)

✅ Short-lived branches (< 24h)
✅ Feature flags avancés (targeting, rollout)
✅ CI/CD robuste avec staging

Enterprise (100+ devs)

✅ Short-lived branches + review
✅ Feature flags enterprise (LaunchDarkly)
✅ CI/CD multi-stages
✅ Canary deployments

Conclusion

Trunk-Based Development n’est pas magique.

Prérequis :

  • Tests automatisés solides
  • CI/CD rapide (<10min)
  • Feature flags
  • Culture de feedback rapide

Mais les bénéfices sont réels :

  • Merge conflicts drastiquement réduits
  • Time to production divisé par 10
  • Qualité améliorée
  • Équipe plus heureuse

Commencez progressivement :

  1. Réduire durée de vie branches
  2. Ajouter feature flags
  3. Accélérer CI/CD
  4. Passer à short-lived branches

Et vous, prêts à simplifier votre workflow Git ?