Conventional Commits (Commits Conventionnels)
Composez des messages de commit suivant la spécification Conventional Commits v1.0.0 pour un historique structuré, la génération automatique de changelogs et le versionnement sémantique.
Quand Utiliser Cette Compétence
Utilisez cette compétence lorsque vous :
- Créez des messages de commit Git pour des projets structurés
- Validez le format des messages de commit par rapport à la spécification Conventional Commits
- Configurez la validation des messages de commit avec commitlint
- Mettez en place la génération de changelogs à partir de l'historique des commits
- Implémentez l'automatisation du versionnement sémantique
- Révisez des messages de commit pour la conformité à la spécification
- Formez des équipes aux normes de messages de commit
- Intégrez des outils comme semantic-release, commitizen ou git-cliff
Structure du Message
<type>[portée optionnelle] : <description>
[corps optionnel]
[pied de page optionnel]
Composants
| Composant | Requis | Description | Exemple |
|---|---|---|---|
| type | Oui | Catégorie du commit | feat, fix, docs |
| portée | Non | Section de la base de code affectée | (auth), (analyseur) |
| description | Oui | Résumé court des changements | ajouter l'authentification utilisateur |
| corps | Non | Explication détaillée | Plusieurs paragraphes avec contexte |
| pied | Non | Changements cassants, références | BREAKING CHANGE :, Refs : #123 |
Types de Commit
Types Requis (Impact SemVer)
Ces types sont imposés par la spécification Conventional Commits et affectent directement le versionnement sémantique :
flowchart LR
Fix[fix: Correction de bug<br/>pour les utilisateurs] --> PatchVer[PATCH<br/>0.0.X]
Feat[feat: Nouvelle fonctionnalité<br/>pour les utilisateurs] --> MinorVer[MINOR<br/>0.X.0]
Breaking[Tout type avec<br/>BREAKING CHANGE ou !] --> MajorVer[MAJOR<br/>X.0.0]
style PatchVer fill:#e1f5ff
style MinorVer fill:#fff4e1
style MajorVer fill:#ffe1e1
| Type | Description | SemVer | Exemple |
|---|---|---|---|
feat | Nouvelle fonctionnalité pour l'utilisateur | MINOR (0.X.0) | feat: ajouter l'authentification utilisateur |
fix | Correction de bug pour l'utilisateur | PATCH (0.0.X) | fix: empêcher le crash sur entrée vide |
Types Recommandés (Convention Angular)
Ces types proviennent de @commitlint/config-conventional basé sur les directives de commit Angular. Ils n'ont pas d'effet SemVer implicite sauf s'ils incluent BREAKING CHANGE.
| Type | Description | Exemple |
|---|---|---|
build | Modifications du système de build ou dépendances externes | build: mise à jour de webpack vers v5 |
ci | Modifications de la configuration CI | ci: ajouter Node 18 à la matrice de test |
docs | Modifications de documentation uniquement | docs: mise à jour de la référence API |
perf | Amélioration des performances | perf: réduire la taille du bundle de 20% |
refactor | Modification de code sans correction de bug ni fonctionnalité | refactor: extraire la logique de validation |
style | Modifications de style de code (espaces, formatage) | style: corriger l'indentation |
test | Ajout ou correction de tests | test: ajouter des tests unitaires pour l'analyseur |
Types Supplémentaires Courants
| Type | Description | Exemple |
|---|---|---|
chore | Modifications ne touchant ni src ni les tests | chore: mettre à jour .gitignore |
revert | Annule un commit précédent | revert: feat: ajouter auth user |
Remarque : Les équipes peuvent définir des types personnalisés au-delà de feat et fix, mais les types de la convention Angular sont largement supportés par les outils.
Règles de la Spécification
Les règles suivante constituent la spécification officielle Conventional Commits 1.0.0 selon la RFC 2119.
Type et Portée
-
Les commits DOIVENT être préfixés par un type, composé d'un nom (
feat,fix, etc.), suivi OPTIONNELLEMENT d'une portée, OPTIONNELLEMENT de!, et du deux-points et de l'espace OBLIGATOIRES en terminal. -
Le type
featDOIT être utilisé lorsqu'un commit ajoute une nouvelle fonctionnalité. -
Le type
fixDOIT être utilisé lorsqu'un commit représente une correction de bug. -
Une portée PEUT être fournie après un type. Une portée DOIT consister en un nom décrivant une section de la base de code, entouré de parenthèses, par exemple
fix(analyseur) :. -
Une description DOIT suivre immédiatement les deux-points et l'espace après le préfixe type/portée. La description est un résumé court des modifications du code, par exemple
fix: problème d'analyse de tableau lorsque plusieurs espaces étaient contenus dans la chaîne.
Corps
-
Un corps de commit plus long PEUT être fourni après la description courte, apportant des informations contextuelles supplémentaires. Le corps DOIT commencer par une ligne vide après la description.
-
Un corps de commit est libre et PEUT consister en un nombre quelconque de paragraphes séparés par des nouvelles lignes.
Pied de Page
-
Un ou plusieurs pieds de page PEUVENT être fournis une ligne vide après le corps. Chaque pied DOIT consister en un jeton mot, suivi soit d'un séparateur
:<space>, soit<space>#, suivi d'une valeur de chaîne (inspiré par la convention de queue git). -
Le jeton d'un pied DOIT utiliser
-à la place des caractères d'espace, par exempleAcked-by(cela aide à différencier la section de pied du corps en plusieurs paragraphes). Exception :BREAKING CHANGEPEUT également être utilisé comme jeton. -
La valeur d'un pied PEUT contenir des espaces et des nouvelles lignes. L'analyse DOIT se terminer lorsque la paire jeton/séparateur valide suivante est observée.
Changements Cassants
-
Les changements cassants DOIVENT être indiqués dans le préfixe type/portée d'un commit, ou comme entrée dans le pied de page.
-
S'il est inclus comme pied, un changement cassant DOIT consister en le texte en majuscules
BREAKING CHANGE, suivi de deux-points, d'un espace et d'une description, par exempleBREAKING CHANGE: les variables d'environnement ont désormais priorité sur les fichiers de configuration. -
S'il est inclus dans le préfixe type/portée, les changements cassant DOIVENT être indiqués par
!immédiatement avant:. Si!est utilisé,BREAKING CHANGE:PEUT être omis du pied, et la description du commit DOIT être utilisée pour décrire le changement cassant.
Règles Supplémentaires
-
Des types autres que
featetfixPEUVENT être utilisés dans les messages de commit, par exempledocs: mettre à jour les références de doc. -
Les unités d'information qui composent Conventional Commits NE DOIVENT PAS être traitées comme sensibles à la casse par les implémenteurs, sauf
BREAKING CHANGEqui DOIT être en majuscules. -
BREAKING-CHANGEDOIT être synonyme deBREAKING CHANGElorsqu'il est utilisé comme jeton dans un pied de page.
Meilleures Pratiques pour la Description
Basées sur les directives de message de commit Angular :
Directives pour le Résumé/Description
- Utilisez l'impératif présent : "ajoute" et non "ajouté" ou "modifications"
- Ne mettez pas de majuscule à la première lettre
- Pas de point (.) à la fin
- Gardez l'en-tête entier (type + portée + description) sous 72 caractères
Bons Exemples
feat: ajouter validation pour entrée email
fix: gérer le pointeur nul dans le service utilisateur
docs: mettre à jour les instructions d'installation
refactor: simplifier le flux d'authentification
Mauvais Exemples (À Éviter)
feat: Ajout validation pour entrée email # Passé
fix: Gère le pointeur nul dans le service utilisateur # Troisième personne
docs: Mettre à jour instructions d'installation. # Point à la fin, majuscule
FEAT: ajouter validation # Type en majuscule (incohérent)
Directives pour le Corps
- Utilisez l'impératif présent (comme pour le résumé)
- Expliquez la motivation du changement
- Incluez une comparaison du comportement précédent et nouveau si utile
- Le corps DOIT commencer par une ligne vide après la description
- Minimum recommandé : 20 caractères lorsque le corps est présent
Changements Cassants
Méthodes pour Indiquer des Changements Cassants
Trois approches équivalentes :
-
Notation en pied de page :
feat: permettre à l'objet de configuration fourni d'étendre d'autres configurations BREAKING CHANGE: la clé `extends` dans le fichier de configuration est maintenant utilisée pour étendre d'autres fichiers de configuration -
Suffixe de type avec
!:feat!: supprimer le support pour Node 6 -
Suffixe type+portée avec
!:feat(api)!: envoyer un email au client lorsqu'un produit est expédié
Règles
BREAKING CHANGEDOIT être en majusculesBREAKING-CHANGEest synonyme lorsqu'il est utilisé comme jeton de pied- Les changements cassants DOIVENT correspondre à un incrément de version MAJEUR en SemVer
Corrélation avec le Versionnement Sémantique
flowchart TD
Start([Analyser les Commits]) --> CheckBreaking{Un commit contient-il<br/>BREAKING CHANGE<br/>ou !?}
CheckBreaking -->|Oui| Major[Majeur<br/>X.0.0]
CheckBreaking -->|Non| CheckFeat{Un commit<br/>est-il feat?}
CheckFeat -->|Oui| Minor[Mineur<br/>0.X.0]
CheckFeat -->|Non| CheckFix{Un commit<br/>est-il fix?}
CheckFix -->|Oui| Patch[Correctif<br/>0.0.X]
CheckFix -->|Non| NoChange[Aucune modification de version]
Major --> End([Versionner])
Minor --> End
Patch --> End
NoChange --> End
Correspondance Type de Commit à Version
| Type de Commit | Incrément de Version |
|---|---|
fix | CORRECTIF (0.0.X) |
feat | MINEUR (0.X.0) |
BREAKING CHANGE ou ! | MAJEUR (X.0.0) |
Raison : Permet un versionnement sémantique automatisé basé sur l'historique des commits.
Modèles de Validation
Expression Régulière pour l'En-tête
^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?!?:\s.+$
Exemple de Validation en Python
import re
CONVENTIONAL_COMMIT_PATTERN = re.compile(
r"^(?P<type>feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)"
r"(?:\((?P<scope>[^)]+)\))?"
r"(?P<breaking>!)?"
r":\s"
r"(?P<description>.+)$"
)
def validate_header(header: str) -> bool:
"""Valider que l'en-tête de commit suit Conventional Commits."""
return bool(CONVENTIONAL_COMMIT_PATTERN.match(header))
def parse_header(header: str) -> dict | None:
"""Analyser l'en-tête de commit en composants."""
match = CONVENTIONAL_COMMIT_PATTERN.match(header)
if not match:
return None
return {
"type": match.group("type"),
"scope": match.group("scope"),
"breaking": bool(match.group("breaking")),
"description": match.group("description"),
}
Exemples Complets
Commits Simples
feat: ajouter l'authentification utilisateur
fix: empêcher le crash sur entrée vide
docs: corriger l'orthographe de CHANGELOG
Commits avec Portée
feat(lang): ajouter la langue polonaise
feat(analyseur): ajouter la capacité d'analyser des tableaux
fix(auth): gérer correctement l'expiration du jeton
Changements Cassants
feat: permettre à l'objet de configuration fourni d'étendre d'autres configurations
BREAKING CHANGE: la clé `extends` dans le fichier de configuration est maintenant utilisée pour étendre d'autres fichiers de configuration
feat!: envoyer un email au client lorsqu'un produit est expédié
feat(api)!: envoyer un email au client lorsqu'un produit est expédié
chore!: abandonner le support pour Node 6
BREAKING CHANGE: utiliser des fonctionnalités JavaScript non disponibles dans Node 6.
Corps Multi-Paragraphes avec Pieds de Page
fix: empêcher la concurrence des requêtes
Introduire un identifiant de requête et une référence à la dernière requête. Ignorer
les réponses entrantes autres que celles de la dernière requête.
Supprimer les timeouts qui étaient utilisés pour atténuer le problème de concurrence mais sont
désormais obsolètes.
Reviewé par : Z
Refs : #123
Commit d'Annulation
revert: ne parlons plus jamais de l'incident des nouilles
Refs : 676104e, a215868
Amélioration des Performances
perf: réduire l'allocation mémoire dans l'analyseur de 40%
Remplacer la concaténation de chaînes par le pattern StringBuilder.
Les résultats de benchmark montrent une réduction de 40% des allocations en tas.
Refs : #456
Refactorisation
refactor: extraire la logique d'authentification dans un module séparé
Déplacer les fonctions liées à l'authentification de utils.py vers auth.py.
Aucun changement fonctionnel.
Modifications Build/CI
ci: ajouter Node 18 à la matrice de test
build: mettre à jour webpack de v4 à v5
- Mettre à jour webpack.config.js pour la compatibilité v5
- Remplacer les plugins obsolètes
- Mettre à jour toutes les dépendances des loaders
Refs : #789
Modifications de Test et de Style
test: ajouter des tests unitaires pour la validation utilisateur
Couvrir les cas limites pour la validation des emails et la force des mots de passe.
style: formater le code selon la configuration prettier
chore: mettre à jour .gitignore pour exclure les fichiers IDE
Intégration avec les Outils de Validation
Configuration commitlint
Validez les commits avec commitlint en utilisant la configuration Angular :
# Installer commitlint
npm install --save-dev @commitlint/cli @commitlint/config-conventional
# Créer la configuration
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js
# Tester un message de commit
echo 'feat(api): ajouter un nouveau point de terminaison' | npx commitlint
Pour des conseils complets sur la configuration de commitlint, référez-vous aux conseils de ce document. Si votre espace de travail dispose d'un plugin commitlint installé, vous pouvez vous y référer pour des règles et exemples spécifiques au projet.
Hooks Pre-commit
Appliquez le format des messages de commit avec des hooks pre-commit. Si votre espace de travail dispose d'un plugin pre-commit installé, vous pouvez l'utiliser pour des conseils de configuration de hook ; sinon, configurez les hooks directement.
Génération de Changelog
Générez des changelogs à partir de commits conventionnels en utilisant semantic-release :
// release.config.js
module.exports = {
branches: ['main'],
plugins: [
'@semantic-release/commit-analyzer',
'@semantic-release/release-notes-generator',
'@semantic-release/changelog',
'@semantic-release/github',
],
};
// .releaserc.json
{
"branches": ["main"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@semantic-release/npm",
"@semantic-release/github"
]
}
Pour des exemples de messages de commit supplémentaires pour vos cas d'utilisation spécifiques, référez-vous aux directives de ce document.