Git workflow
Branches, conventional commits, PRs, review, merge
Conventional commits, branches courtes, PRs petites, review systématique. Pas de push direct sur
main.
Branches
Convention de nommage
Toujours en kebab-case, préfixées par leur type :
feat/<description-courte>
fix/<description-courte>
chore/<description-courte>
refactor/<description-courte>
docs/<description-courte>
test/<description-courte>Exemples :
feat/catalog-drag-drop
fix/magic-token-revocation
refactor/members-service-split
docs/conventions-section
chore/upgrade-elysiaBranches longues
| Branche | Rôle |
|---|---|
main | Production. Protégée. Tag de release à partir d'ici. |
develop | Intégration. Auto-déployée sur preprod. |
Les feature branches partent de develop, sont rebasées dessus, puis mergées via PR.
Cycle de vie d'une feature
Commits
Conventional Commits
Format obligatoire :
<type>(<scope>): <description courte impérative>
[body optionnel]
[footer optionnel]Types autorisés
| Type | Quand |
|---|---|
feat | Nouvelle feature utilisateur |
fix | Correction de bug |
refactor | Refacto sans changement de comportement |
perf | Amélioration de perf |
docs | Documentation seule |
test | Tests seuls |
chore | Outils, dépendances, config |
style | Formatage, espace blanc (rare avec Biome) |
build | Build system, CI |
revert | Revert d'un commit précédent |
Scopes
Le scope correspond au module métier ou à la zone touchée :
feat(members): add tag suggestion endpoint
fix(requests): correct status transition validation
refactor(ai): split chat orchestration into smaller files
chore(deps): bump elysia to 1.4
docs(conventions): add file thresholds pageScopes multiples possibles si transversal :
feat(members,search): expose new room capacity filterDescription
- Impérative, présent : "add" pas "added" pas "adding"
- Courte, < 70 caractères
- Pas de point final
- Minuscule au début (sauf noms propres)
Body
Quand utile, séparé par une ligne vide. Explique le pourquoi, pas le quoi.
feat(catalog): add drag-drop reordering for members
Le drag-drop remplace les boutons up/down qui devenaient ingérables
au-delà de 6 lieux par catalogue. Implémenté avec dnd-kit pour la
compatibilité tactile (iPad utilisé sur le terrain).
Closes #142Footer
Pour référencer un ticket ou un breaking change :
BREAKING CHANGE: l'endpoint /requests/:id retourne maintenant {data, meta} au lieu de l'objet brut
Closes #142
Refs #98Exemples bons et mauvais
# ✅ Bon
git commit -m "feat(search): add semantic query parameter to members search"
git commit -m "fix(auth): handle revoked magic token returning 401 instead of 500"
git commit -m "refactor(ai): extract tool execution into dedicated module"
# ❌ Mauvais
git commit -m "WIP"
git commit -m "stuff"
git commit -m "fixed bug"
git commit -m "Fix the thing that was broken in the previous commit"
git commit -m "feat: a lot of changes for the new feature including some refactoring and..."Pull requests
Taille
Petites PRs > grosses PRs. Cible idéale : 200-400 lignes modifiées. Au-delà de 800 lignes, splitter sauf si techniquement impossible.
Une PR de 2000 lignes ne sera pas reviewée correctement. Tout le monde scanne et approuve sans rien voir.
Titre
Suit le même format que les commits :
feat(members): add tag suggestion endpoint
fix(requests): correct status transition validationDescription
Template à respecter :
## Contexte
Pourquoi cette PR existe. Quel problème elle résout. Lien vers le ticket.
## Changements
- Liste des changements principaux
- Un point par changement notable
## Tests
- [ ] Tests unitaires ajoutés / mis à jour
- [ ] Tests d'intégration ajoutés / mis à jour
- [ ] Vérifié manuellement en local
## Captures (si UI)
[screenshots / vidéos]
## À noter pour le reviewer
- Points qui méritent une attention particulière
- Choix techniques discutables
- Dette laissée volontairement (avec ticket associé)Labels
| Label | Quand |
|---|---|
feat / fix / chore / etc. | Type de change |
breaking-change | Casse une API publique |
needs-migration | Nécessite une migration DB |
needs-env-update | Nécessite une nouvelle variable d'env |
do-not-merge | Bloquant côté auteur |
wip | Pas encore prête à être reviewée |
Auto-merge
Une PR n'est mergée automatiquement que si :
- ✅ CI verte (tests, lint, types, build)
- ✅ Au moins 1 review approuvée
- ✅ Pas de conflits avec
develop - ✅ Pas de label
do-not-mergeouwip
Code review
Obligations du reviewer
- Lire tout le diff, pas juste les fichiers que tu connais
- Vérifier les tests (existence, pertinence)
- Challenger les abstractions (cf. Factorisation)
- Vérifier les seuils de fichiers (cf. Seuils de fichiers)
- Vérifier les conventions de nommage
- Tester en local si la PR touche un flow critique
Obligations de l'auteur
- Faire passer la CI avant de demander review
- Répondre à tous les commentaires (résoudre ou discuter)
- Re-demander review après changement significatif
- Squash en un commit propre avant merge (sauf si historique fin justifié)
Format des commentaires
Préfixer pour clarifier l'intention :
| Préfixe | Signification |
|---|---|
nit: | Détail mineur, pas bloquant |
question: | Demande d'explication, pas un changement requis |
suggestion: | Idée d'amélioration, à discuter |
bloquant: | Doit être corrigé avant merge |
discussion: | Sujet plus large à débattre |
Exemples :
nit: typo "occurence" → "occurrence"
question: pourquoi as-tu choisi un cron de 5 min plutôt que LISTEN/NOTIFY ?
suggestion: cette logique pourrait vivre dans le service plutôt que dans la route
bloquant: le filtre user_id manque → fuite d'accès cross-tenantMerge strategy
Squash and merge par défaut. Le commit final reprend le titre + description de la PR.
Avantages :
- L'historique de
mainreste lisible - Chaque commit sur
maincorrespond à une PR atomique - Faire
git log --oneline mainreste pertinent
Exception : les PRs de migration ou de refactoring multi-étapes peuvent garder leurs commits intermédiaires si chaque commit est cohérent. Décision au cas par cas.
Releases
Versioning
SemVer : MAJOR.MINOR.PATCH.
MAJOR: breaking change visible utilisateur ou API publiqueMINOR: nouvelle feature, rétro-compatiblePATCH: bug fix, rétro-compatible
Tag
Au merge sur main, un tag est créé :
git tag v1.4.2
git push origin v1.4.2Le tag déclenche le déploiement prod via Dokploy (webhook).
Changelog
Auto-généré depuis les conventional commits via git-cliff ou équivalent. Pas de maintien manuel.
Hooks pre-commit
Configurés via lefthook ou husky :
pre-commit:
parallel: true
commands:
biome:
glob: '*.{ts,tsx,js,jsx,json}'
run: bunx biome check --apply {staged_files}
types:
run: bun run check-types
thresholds:
run: bun run scripts/check-thresholds.ts
commit-msg:
commands:
conventional:
run: bunx commitlint --edit {1}Si la CI échoue, le commit est refusé. Pas de --no-verify sauf urgence documentée.
Voir aussi
- Code style, formatage et patterns
- Architecture modulaire, où ranger les changements
- Environnements, pipeline de déploiement