Skip to main content

3. Les conventionnal commit

Dans un projet, l'historique Git est essentiel pour comprendre l'évolution du code. Mais sans convention, les messages de commit peuvent être chaotiques :

git log --oneline

a3f2b1c fix bug
b4e5c2d update
c5f6d3e changes
d6g7e4f oops
e7h8f5g final fix
f8i9g6h really final fix this time

Problèmes :

  • Impossible de comprendre ce qui a été modifié
  • Difficile de générer un changelog
  • Compliqué de trouver quand un bug a été introduit
  • Pas de distinction entre features, fixes, et refactoring

Conventional Commits

Conventional Commits est une convention de nommage pour les messages de commit. Elle définit un format strict et standardisé.

Format

<type>(<scope>): <subject>

<body>

<footer>

Exemple :

feat(auth): add login endpoint

Implement JWT authentication with email and password.
Add input validation and password hashing with bcrypt.

Closes #42

Types de commit

TypeDescriptionExemple
featNouvelle fonctionnalitéfeat(user): add profile page
fixCorrection de bugfix(api): handle null user response
docsModification de documentationdocs(readme): update installation steps
styleChangement de style (formatage, espaces, etc.)style: format with prettier
refactorRefactorisation du code (ni feature ni fix)refactor(auth): simplify token logic
testAjout ou modification de teststest(user): add unit tests for service
choreTâches diverses (config, dépendances, etc.)chore: update dependencies
perfAmélioration de performanceperf(db): optimize query with indexes
ciModification de la CI/CDci: add GitHub Actions workflow
buildModification du système de buildbuild: update webpack config
revertAnnulation d'un commit précédentrevert: revert commit a3f2b1c

Scope (optionnel)

Le scope indique la partie du projet concernée :

  • auth : authentification
  • user : utilisateur
  • api : API
  • db : base de données
  • ui : interface utilisateur

Exemples :

feat(auth): add login endpoint
fix(db): resolve connection pool leak
docs(api): update swagger documentation

Subject

Le subject décrit brièvement la modification :

  • Utiliser l'impératif (add et non added ou adds)
  • Pas de majuscule au début
  • Pas de point final
  • Maximum 50 caractères

Bon : add user authentication Mauvais : Added user authentication.

Body (optionnel)

Le body explique pourquoi et comment :

  • Détaille le contexte de la modification
  • Explique les choix techniques
  • Ligne vide obligatoire après le subject

Exemple :

feat(auth): add JWT authentication

Implement JWT-based authentication to replace session-based auth.
This allows stateless authentication and better scalability.

- Add JWT generation and validation
- Update middleware to check tokens
- Add refresh token mechanism

Le footer contient des métadonnées :

  • Références à des issues (Closes #42, Fixes #123)
  • Breaking changes (BREAKING CHANGE: ...)

Exemple :

feat(api): change user endpoint response format

BREAKING CHANGE: User endpoint now returns { data: {...} } instead of {...}

Closes #156

Exemples complets

Nouvelle fonctionnalité

feat(auth): add password reset functionality

Implement password reset flow with email verification.
Users receive a reset link valid for 1 hour.

Closes #78

Correction de bug

fix(api): handle undefined email in registration

Add validation to check if email exists before accessing properties.
Prevents server crash when email is undefined.

Fixes #134

Documentation

docs(readme): add environment variables section

Document all required environment variables with examples.

Refactorisation

refactor(user): extract validation logic to service

Move validation from controller to dedicated service.
Improves code reusability and testability.

Automatisation avec Commitlint

Pour forcer l'utilisation de Conventional Commits, nous allons utiliser Commitlint.

Installation

npm install -D @commitlint/cli @commitlint/config-conventional

Configuration

Créez un fichier commitlint.config.js à la racine :

export default {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
[
'feat',
'fix',
'docs',
'style',
'refactor',
'test',
'chore',
'perf',
'ci',
'build',
'revert',
],
],
'subject-case': [2, 'never', ['upper-case', 'pascal-case']],
'subject-empty': [2, 'never'],
'type-empty': [2, 'never'],
},
}

Husky & Git Hooks

Git Hooks

Les Git Hooks sont des scripts qui s'exécutent à des moments spécifiques du cycle de vie de Git. Ils permettent d'automatiser des tâches et d'appliquer des règles avant d'effectuer certaines actions, comme un commit ou un push.

Voici une liste non exhaustive des hooks Git les plus courants :

  • pre-commit : s'exécute avant un commit
  • commit-msg : s'exécute après la saisie du message de commit
  • pre-push : s'exécute avant un push

Husky

Pour exécuter Commitlint automatiquement avant chaque commit, nous utilisons Husky.

Installation :

npm install -D husky
npx husky init

Configuration du hook :

Créez le fichier .husky/commit-msg :

npx --no -- commitlint --edit $1

Rendez-le exécutable :

chmod +x .husky/commit-msg

Test du commit

Essayez de faire un commit avec un mauvais message :

git commit -m "bad commit message"

Résultat :

⧗   input: bad commit message
✖ subject may not be empty [subject-empty]
✖ type may not be empty [type-empty]

✖ found 2 problems, 0 warnings

Le commit est rejeté !

Maintenant avec un bon message :

git commit -m "feat(auth): add login endpoint"

Résultat :

✔   found 0 problems, 0 warnings

Le commit passe !