Combien de temps ton équipe perd-elle à décoder l'intention derrière un commentaire de review ?
"Tu devrais refactorer ceci." Est-ce bloquant ? Une suggestion ? Une remarque en passant ? Le développeur hésite, le relecteur s'agace que son feedback soit ignoré. La MR traîne. Le problème n'est pas technique: c'est un problème de communication.
Conventional Comments propose une solution simple : rendre l'implicite explicite. Un format structuré qui clarifie l'intention, la criticité et le contexte de chaque commentaire.
Dans cet article : la méthodologie, des exemples avant/après, et les métriques que nous avons observées après l'adoption par une équipe de développement.
Comprendre le problème
Comment la Merge Request est devenue incontournable
Pour comprendre les enjeux actuels, un détour par l'histoire s'impose.
Années 80–2000 : l'ère centralisée. Avec RCS puis CVS, un fichier = un verrou. Le travail séquentiel est la norme, la relecture passe par des emails et des réunions. SVN améliore les choses avec des commits atomiques, mais les branches restent lentes et douloureuses. Résultat : pas de culture de review systématique.
2005 : la révolution Git. Branches instantanées, travail 100% local, merges intelligents. Le paradigme bascule. Les feature branches explosent, le travail parallèle devient massif. Mais avec cette liberté vient un nouveau risque : la perte de cohérence du code.
2010+ : l'essor des plateformes. GitHub, GitLab, Bitbucket introduisent la Pull/Merge Request. Discussion dans le code, historique des décisions, CI automatisée, approbations formelles. La MR devient le point de passage obligé pour tout changement.
Fil rouge : Plus les branches deviennent faciles à créer, plus la relecture structurée devient critique.
Aujourd'hui, les équipes collaborent en asynchrone. Les discussions dans les merge requests sont la documentation vivante des décisions techniques. Sans le face-à-face, le ton et l'intention sont facilement mal interprétés. Les reviews servent aussi de vecteur d'apprentissage : onboarding des juniors, challenge des approches des seniors.
Le fossé de communication
Pourtant, les commentaires de review traditionnels souffrent de patterns récurrents qui sabotent leur efficacité :
Friction émotionnelle :"Ce code ne fonctionnera pas en production" sans contexte génère de l'anxiété, pas de la collaboration. Le développeur se met sur la défensive.
Ambiguïté sur la criticité :"Considère extraire cette logique" : bloquant ou optionnel ? Le développeur perd du temps sur du non-critique, ou ignore un feedback important. Frustration des deux côtés.
Discussions sans fin :Sans framework clair, une simple question escalade en thread interminable. La MR reste bloquée plusieurs jours.
Absence de reconnaissance :12 commentaires critiques, 0 éloge. Le bon travail passe inaperçu. La motivation s'érode.
Faux consensus :Pour éviter le conflit, certains approuvent avec un "LGTM" superficiel. La dette technique s'accumule en silence.
La solution : Conventional Comments
Plus d'informations sur conventionalcomments.org.
Avant :
Tu devrais extraire cette logique
Après :
suggestion (non-blocking): Extraire la logique de validation
En un coup d'œil : c'est une suggestion, elle n'est pas bloquante. Plus d'ambiguïté.
Format
<label> (decoration): <sujet>
[discussion optionnelle]Élément | Rôle | Exemple |
label | Type de commentaire |
|
decoration | Modifie la criticité (optionnel) |
|
sujet | Le point soulevé |
|
discussion | Contexte, raisonnement (optionnel) | Explication détaillée, liens, etc. |
Labels
La spécification définit plusieurs labels. Voici ceux que nous utilisons :
Label | Usage | Bloquant | Exemple |
praise | Mettre en avant des aspects positifs | Non |
|
question | Comprendre une décision | Non (attend réponse) |
|
suggestion | Proposer une amélioration | Non (auteur décide) |
|
issue | Changement nécessaire | Oui (doit être résolu) |
|
thought | Partager une idée ou réflexion | Non |
|
nitpick | Changement trivial | Non |
|
todo | Petite tâche nécessaire et triviale | Oui (doit être résolu) |
|
Décorations
Les décorations ajustent la criticité d'un label :
Décoration | Signification | Exemple |
(non-blocking) | Le merge peut se faire, l'auteur décide |
|
(if-minor) | À corriger sauf si l'effort est disproportionné |
|
Exemples concrets
Reprenons les problèmes identifiés plus haut et voyons comment Conventional Comments les résout.
Ambiguïté sur la criticité
const data = await fetchUser(userId);
if (!data) {
throw new Error('User not found');
}Avant
"Tu devrais utiliser un Result type au lieu de throw"
Après
suggestion (non-blocking): Considérer un Result type pour la gestion d'erreur
Avec un Result<T, E>, cela éviterait les try/catch et rendra les erreurs explicites
au niveau des types.
Pas nécessaire pour cette MR si le reste de la codebase utilise throw.
Référence : https://swan-io.github.io/boxed/result→ L'intention est claire : suggestion non-bloquante, le développeur décide.
Friction émotionnelle
Avant
const users = [/* ... */];
users.forEach(user => {
sendEmail(user.email, template);
});"Ce code va exploser en prod avec 10 000 users. C'est pas bon du tout!"
Après
issue: Risque de surcharge de l'API email avec des volumes importants
Avec 10k users, cette approche synchrone va timeout.
Suggestions :
- Utiliser `p-limit` pour limiter la concurrence (ex: 10 parallèles max)
- Déléguer à une queue (Amqp) pour un traitement async
Dispo si besoin d'un coup de main, j'ai déjà implémenté ça avec p-limit.→ Le problème est articulé avec des solutions, pas des reproches.
Jugement déguisé en question
async function processOrders() {
const orders = await fetchOrders();
for (const order of orders) {
await processPayment(order);
await sendConfirmation(order);
}
}Avant
"Pourquoi tu n'utilises pas Promise.all() ? As-tu bien compris l'async en JS ?"
Après
question: Raison du traitement séquentiel plutôt que parallèle ?
Je me demande s'il y a une dépendance entre processPayment et sendConfirmation.
Si elles sont indépendantes, on pourrait améliorer la perf avec `Promise.all()`.
Si c'est intentionnel (limite de débit ?), un commentaire aiderait à documenter.→ Curiosité plutôt que jugement, dialogue ouvert.
Absence de reconnaissance
Avant
Une MR reçoit 12 commentaires : 10 issues, 2 todos, 0 praise.
Après
praise: Excellente architecture avec le pattern Repository
La séparation domain/infrastructure rend ce code hautement testable.
Les interfaces sont claires et le typage strict prévient des erreurs runtime.
praise: Tests complets incluant les edge-cases
Les tests de timeout et retry sont particulièrement précieux.
issue: Fuite mémoire potentielle dans le listener WebSocket
[... autres commentaires ...]→ Équilibrer critiques et reconnaissance maintient la motivation.
Implémentation et mesure
Adopter Conventional Comments ne suffit pas: il faut des règles d'équipe et un suivi pour ancrer la pratique.
Règles d'équipe
Règle | Pourquoi |
Praise sincère obligatoire | Identifier les aspects positifs. Un faux praise érode la confiance. |
Seul l'auteur du commentaire résout | Évite les merges prématurés. Le dev répond, le relecteur valide et résout. |
Référencer le commit de correction | "Corrigé dans abc123" → le relecteur vérifie directement. |
Documenter les exceptions | Merge urgent ? Créer un ticket et le mentionner dans le thread. |
Exemple: notification après correction :
# Relecteur
issue: Variable userId non validée
# Développeur
Corrigé dans abc123 :ajout validation Zod avec z.string().uuid()
Exemple: exception documentée :
suggestion (non-blocking): Refactorer vers une architecture hexagonale
@dev : On merge pour débloquer la release, ticket TECH-456 créé.
Métriques de suivi
Trois indicateurs pour évaluer l'adoption :
Métrique | Calcul | Objectif |
Taux d'adoption | Commentaires conventionnels / Total | 80%+ après 3 mois |
Praise ratio | Praise / (Issue + Nitpick) | Min 0.2 (1 pour 5 critiques) |
Temps de résolution | Date merge − Date création | Réduction de 20-30% |
Évolution attendue : Praise en hausse, Issues en baisse, Questions stables.
Automatisation
Le suivi manuel est fastidieux. J'ai créé un outil CLI pour automatiser la collecte depuis l'API GitLab.
Exemple d'output :
╔════════════════════════════════════════════════╗
║ ⏱ MR Resolution Time ║
╚════════════════════════════════════════════════╝
▲
12d┤
11d┤
10d┤
9d┤
9d┤━━━━━━━┓
8d┤ ┃
7d┤ ┃
6d┤ ┃
d 5d┤ ┃ ┏┓
a 5d┤ ┃ ┃┃ ┏━━┓ ┏━━━━━┓
y 4d┤ ┃ ┏━┓ ┃┃ ┃ ┃ ┏━━━━━┓ ┃ ┃
s 3d┤ ┃ ┏━━━━━┛ ┃ ┃┗━━━━━━━━━┛ ┃ ┃ ┃ ┃ ┃ ┏━━━━┓
2d┤ ┃ ┏┛ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃
2d┤ ┃ ┃ ┗━┛ ┗━━━┓ ┃ ┃ ┏┓ ┃ ┃ ┃ ┃
19h┤ ┗━━┛ ┗━━┓ ┃ ┗━┛┗━┛ ┗━━━━━┛ ┃
0 ┤ ┗━┛ ┗━
└┬───────┬──┬┬─────┬─┬─┬┬─┬───────┬──┬───┬──┬─┬─────┬─┬┬─┬─────┬─┬──┬┬────┬▶
11-10 11-1711-20 11-26 12-0112-04 12-0812-11 12-1512-18 12-22
date (utc)
Lissage de la courbe grâce à l'application d'un Exponentially Weighted Moving Average (EWMA)
▲
6d┤
6d┤━━━━━━━┓
5d┤ ┃
5d┤ ┃
d 4d┤ ┗━━┓
a 4d┤ ┃
y 4d┤ ┗━━━━━━━━┓ ┏━━┓ ┏━━┓
s 3d┤ ┗━┛ ┗━━━━━━━┛ ┗━━━┓
3d┤ ┃
2d┤ ┗━━┓ ┏━━━━━┓ ┏━━━━━┓
2d┤ ┗━┛ ┗━━┓ ┃ ┗━┓ ┏━━━━┓
2d┤ ┗━┛ ┗━━━┛ ┗━
1d┤
19h┤
9h┤
0 ┤
└┬───────┬──┬┬─────┬─┬─┬┬─┬───────┬──┬───┬──┬─┬─────┬─┬┬─┬─────┬─┬──┬┬────┬▶
11-10 11-1711-20 11-26 12-0112-04 12-0812-11 12-1512-18 12-22
date (utc)
╔════════════════════════════════════════════════╗
║ 💬 MR Comments Distribution ║
╚════════════════════════════════════════════════╝
Global Statistics
─────────────────
┌─────────────────────┬────────┐
│ (index) │ Value │
├─────────────────────┼────────┤
│ Total MRs │ 58 │
│ Total Comments │ 966 │
│ Average Comments/MR │ 16.7 │
│ Min Comments/MR │ 3 │
│ Max Comments/MR │ 80 │
│ Median Comments/MR │ 9.5 │
└─────────────────────┴────────┘
L'évolution du nombre de commentaires par MR dans le temps (toujours en appliquant un EWMA pour lisser la courbe)
▲
c 51 ┤
o 47 ┤
m 44 ┤━━━━━━━┓
m 41 ┤ ┃
e 37 ┤ ┃
n 34 ┤ ┗━━┓
t 30 ┤ ┃
s 27 ┤ ┗┓
/ 24 ┤ ┗━━━━━━━┓
M 20 ┤ ┗━┓
R 17 ┤ ┗━━┓ ┏━━━━━━┓
14 ┤ ┗━━━━━━━┛ ┗━━┓ ┏━━━━━━━━━━━━━━━━━━━━━┓
10 ┤ ┗━┛ ┗━━━━━━━
7 ┤
3 ┤
0 ┤
└┬───────┬──┬┬─────┬─┬─┬┬─┬───────┬──┬───┬──┬─┬─────┬─┬┬─┬─────┬─┬──┬┬────┬▶
11-10 11-1711-20 11-26 12-0112-04 12-0812-11 12-1512-18 12-22
date (utc)
╔════════════════════════════════════════════════╗
║ 📋 Conventional Comments Analysis ║
╚════════════════════════════════════════════════╝
Global Overview
───────────────
┌─────────────────────────┬─────────┐
│ (index) │ Value │
├─────────────────────────┼─────────┤
│ Total Comments │ 966 │
│ Conventional Comments │ 736 │
│ Unconventional Comments │ 230 │
│ Adoption Rate │ 76.2% │
└─────────────────────────┴─────────┘
Label Distribution
──────────────────
┌────────────┬────────────┐
│ (index) │ Percentage │
├────────────┼────────────┤
│ Praise │ 1.4% │
│ Question │ 54.6% │
│ Suggestion │ 14.9% │
│ Issue │ 21.3% │
│ Nitpick │ 7.9% │
└────────────┴────────────┘
Praise Ratio
────────────
┌──────────────────────────────────┬────────┐
│ (index) │ Value │
├──────────────────────────────────┼────────┤
│ Praise Count │ 10 │
│ Critique Count (issue + nitpick) │ 215 │
│ Ratio (praise/critique) │ 4.7% │
└──────────────────────────────────┴────────┘Interprétation :
Adoption 76% → majorité de l'équipe utilise le format
Praise ratio 4.7% → 10 praises pour 215 critiques, marge de progression
Questions 54% → ratio élevé, peut s'expliquer par un contexte d'onboarding ou de montée en compétence
ℹ️ Tip: Filtrer les bots (dependabot, renovate, ...) pour analyser uniquement les reviews humaines.
Défis et limites
La méthode n'est pas sans écueils. Quelques pièges à éviter :
Formalisme vide
Le label ne remplace pas l'explication. issue: Variable mal nommée sans contexte reste inutile.
→ Toujours expliquer le "pourquoi" : userData serait plus explicite que data pour le contexte business.
Praise générique
praise: Joli remplit la règle mais sape son esprit. Un praise vague érode la confiance.
→ Être spécifique : praise: Excellent usage du pattern Builder pour le UserDTO
Abus de non-blocking
Si 90% des commentaires sont (non-blocking), la review n'apporte plus de valeur.
→ Oser bloquer quand c'est justifié.
Résistance initiale
Le format peut sembler bureaucratique au début.
→ Montrer par l'exemple plutôt qu'imposer. Les bénéfices visibles dans les reviews des autres encouragent l'adoption.
Conclusion
Selon moi, le problème principale n'est pas technique: c'est un problème de communication. Conventional Comments ne réinvente pas la review, il rend l'implicite explicite.
Pour les développeurs :fini de deviner si un commentaire bloque le merge. Pour les relecteurs :un cadre pour structurer le feedback sans paraître condescendant. Pour les équipes :moins de friction, plus d'apprentissage.
Ce n'est pas une solution miracle. Le format ne remplace pas l'empathie ni le jugement. Mais c'est un premier pas concret vers des reviews plus efficaces et plus humaines.
Pour commencer : essayez sur votre prochaine MR. Un suggestion (non-blocking): ou un praise: sincère. Observez la réaction.
Ressources
Cet article s'inspire d'une implémentation réelle de Conventional Comments dans une équipe de développement fullstack. Tous les exemples sont basés sur des situations réellement rencontrées, avec des détails d'identification modifiés.