03 - Conventional commits et changelogs automatiques
Ce que tu vas apprendre
- La convention Conventional Commits et ses types
- Comment générer un changelog automatiquement
- Comment forcer le format avec des outils
Prerequisites
- 00 - Introduction
- Avoir un projet avec des commits (meme basiques)
Le problème des messages de commit
Ouvre le git log de n'importe quel projet ou personne n'a pose de convention. Tu vas trouver des trucs comme :
bashgit log --oneline
# a1b2c3d fix
# e4f5g6h wip
# i7j8k9l update
# m0n1o2p ca marche maintenant
# q3r4s5t modif header
# u6v7w8x test
Inutile. "fix" quoi ? "update" de quoi ? "wip" sur quelle feature ? Quand tu cherches le commit qui a introduit un bug (avec bisect par exemple), un historique pareil te rend aveugle.
J'ai eu un collegue qui mettait "." comme message de commit. Litteralement un point. Son argument : "le diff montre ce qui a change". Techniquement vrai. Humainement desastreux.
La convention Conventional Commits
Conventional Commits est une spec simple. Le format :
type(scope): description
[body optionnel]
[footer optionnel]
Les types principaux :
feat: nouvelle fonctionnalité (visible par l'utilisateur)fix: correction de bugchore: maintenance (deps, config, CI)docs: documentationrefactor: refactoring sans changement de comportementtest: ajout ou modification de testsstyle: formatage, points-virgules manquants (pas de changement de logique)perf: amelioration de performanceci: changements dans la config CI/CD
Le scope est optionnel mais utile. C'est la partie du projet concernee :
bashgit commit -m "feat(search): add autocomplete to search bar"
git commit -m "fix(auth): handle expired JWT token"
git commit -m "chore(deps): update vite to 6.2.0"
git commit -m "refactor(api): split user controller into separate files"
git commit -m "ci(deploy): add staging environment to pipeline"
Ce dernier exemple colle bien avec une pipeline GitLab CI.
Les breaking changes
Quand tu introduis un changement non retrocompatible, deux options :
bash# Option 1 : point d'exclamation apres le type
git commit -m "feat!: change API response format to JSON:API"
# Option 2 : footer BREAKING CHANGE
git commit -m "feat(api): change response format
BREAKING CHANGE: all endpoints now return JSON:API format instead of plain JSON"
Les outils de changelog detectent ces markers et les mettent en avant. Tes utilisateurs (ou tes collegues) savent qu'il faut adapter leur code.
Pourquoi ca change tout
Quatre raisons concrètes.
L'historique devient lisible. Un git log --oneline raconte une histoire :
bashgit log --oneline
# a1b2c3d feat(search): add autocomplete
# e4f5g6h fix(search): debounce input to avoid API spam
# i7j8k9l refactor(api): extract search service
# m0n1o2p chore(deps): update bun to 1.2.4
# q3r4s5t feat(auth): add password reset flow
Tu peux générer un changelog automatiquement. Des outils comme standard-version ou release-please parsent tes commits et generent un CHANGELOG.md avec les features, les fixes et les breaking changes par version. C'est du versionning semantique automatique : un feat bumpe la version mineure, un fix bumpe le patch, un breaking change bumpe la majeure.
Le filtrage devient possible. Tu veux voir tous les bugfixes du mois dernier ?
bashgit log --oneline --grep="^fix" --since="2026-03-01"
Et les merge requests sur GitLab sont plus faciles a reviewer. Le titre de la MR reprend le message du commit. Un reviewer sait en une seconde ce qu'il va lire.
Les outils pour enforcer la convention
La convention ne tient que si elle est enforcee. Sinon, au bout de deux semaines, tout le monde revient aux "fix truc". J'ai vu ca trop souvent.
commitlint vérifié le format du message de commit. Tu l'installes comme hook (on en parle en détail dans l'article sur les hooks) :
bashbun add -D @commitlint/cli @commitlint/config-conventional
json// commitlint.config.js (ou .commitlintrc.json)
{
"extends": ["@commitlint/config-conventional"]
}
Ensuite, avec un hook commit-msg :
bashecho "feat: add search" | bunx commitlint # passe
echo "added search" | bunx commitlint # echoue
echo "Fix: login" | bunx commitlint # echoue (majuscule)
commitizen fournit un prompt interactif si tes juniors ne retiennent pas les types :
bashbun add -D commitizen cz-conventional-changelog
json// package.json
{
"config": {
"commitizen": {
"path": "cz-conventional-changelog"
}
}
}
bashbunx cz
# ? Select the type of change: feat
# ? Scope: search
# ? Short description: add autocomplete to search bar
# Commit: feat(search): add autocomplete to search bar
Perso, je n'utilise pas commitizen. Je tape mes messages directement. Mais pour des juniors qui debutent avec la convention, ca aide les premières semaines.
Le pattern Co-Authored-By
Si tu utilises une IA pour t'aider a coder (et en 2026, qui ne le fait pas), tu peux crediter dans le footer du commit :
bashgit commit -m "feat(search): add fuzzy matching
Co-Authored-By: Claude <noreply@anthropic.com>"
C'est une convention GitHub/GitLab reconnue. Ca apparaît dans l'interface web. C'est une bonne pratique de transparence, pas une obligation. Mais je l'impose dans mon équipe pour savoir quels commits ont ete ecrits avec assistance IA.
Mes regles d'équipe
Voici ce que j'impose sur mes projets :
- Tout commit suit le format
type(scope): description - Le scope est obligatoire si le projet a plus de trois dossiers fonctionnels
- La description commence par une minuscule, en anglais, sans point final
- commitlint est installe et vérifié via hook
commit-msg - Avant de merger une MR, on squash les "fix typo" avec un rebase interactif
Si paltemps.fr a un historique propre, c'est grâce à ces regles. Pas grâce à de la discipline individuelle. La discipline individuelle, ca ne tient pas. Les outils, si.
Article précédent : 02 - Rebase vs merge Article suivant : 04 - Stash, cherry-pick et bisect