De base, un usage de GIT passe par des messages de commit clairs et concis, afin que les dev s'y retrouvent facilement en parcourant l'historique.
Cependant, à l'usage le maintien des commits peut s'avérer fastidieux et on peut rapidement s'y perdre dès lors que le projet devient volumineux.
Pour remédier à ce problème, des guides ont été pensés proposant des normes à respecter, imposant ainsi un style uniforme aux messages de commit.
L'un des guides les plus connus et souvent adopté est celui d'Angular : https://github.com/angular/angular/blob/main/CONTRIBUTING.md#commit
Les avantages d'adopter une norme de commit :
En suivant le guide d'Angular, voici à quoi doit ressembler un message de commit :
|
Le type indique le contexte du commit. Il donne l'information sur le type de changement opéré. Est-ce qu'il s'agit d'une nouvelle feature, un bugfix, de la mise à jour de doc, ... ?
Voici la liste des types disponibles (selon la convention) :
build
: changements qui affectent le système de build ou des dépendances externes (principalement ajout / suppression de dépendances npm, makefiles, ...)chore
: fait référence à des tâches de maintenance, des travaux internes ou des actions qui ne modifient pas directement le code source, mais qui restent nécessaires pour maintenir et améliorer le projet (le plus souvent, utilisé pour la création d'une nouvelle release : chore(release): publish new release
)ci
: changements concernant les fichiers et scripts d'intégration ou de configuration (Gitlab-CI, Docker, Jenkins, ...)docs
: rédaction ou mise à jour de la documentationfeat
: ajout d'une nouvelle fonctionnalité (entre en corrélation avec MINOR
en gestion sémantique de version)fix
: correction d'un bug (entre en corrélation avec PATCH
en gestion sémantique de version)perf
: changements qui visent à améliorer les performancesrefactor
: changement dans le code qui n'est ni une correction de bug ou l'ajout d'une nouvelle fonctionnalité. Utilisé principalement lors de la réorganisation du code sans modifier sa fonctionnalitérevert
: annule un commit précédentstyle
: changements qui n'affectent pas le sens du code (espace, formatage, points-virgules manquants, ...)test
: ajout de tests manquants ou correction des existantsUtilisation du symbole !
: Lorsque le type (ou scope) est suffixé d'un ! on indique que les changements introduisent une rupture de compatibilité (généralement au niveau de l'API).
On peut également indiquer BREAKING CHANGE:
dans le footer du commit
Ces changements entrent en corrélation avec MAJOR
en gestion sémantique de version.
Le scope sert généralement à indiqué le package / module impacté par le commit.
Par exemple, si les changements ont un impact sur le microservice auth
le scope sera alors (auth)
tel qu'il est déclaré dans le fichier package.json
.
Il doit s'agit d'une description succinte des changements. En général, il ne doit pas dépasser 52 caractères.
Il convient d'utiliser de préférence l'anglais (discutable suivant la portée du projet), et à l'impératif présent (add, change, update, remove au lieu de changed, removed ou bien changes, removes, ...).
Exemple : remove unnecessary variable toto in controller
Suivant les bonnes pratiques d'Angular, il convient également de ne pas mettre de majuscule au premier mot du message, ni de point à la fin.
Permet d'expliquer plus en détail la raison des changements. De même que pour le sujet, on utiliser l'impératif présent.
La description dans le body ne doit pas dépasser 72 caractères.
Permet d'indiquer la présence d'un BREAKING CHANGE:
et on y référence aussi parfois le ticket d'erreur associé.
Github fournit une liste de mots-clés qui peuvent être utilisés en footer pour lier le commit à une issue ou un PR :
Exemple : Resolves: #10
Multi étant actuellement une architecture monorepo (client + backend avec µservices indépendants), on peut envisager une convention de nommage supplémentaire indiquant qui, du client ou du backend, est impacté par les modifications.
|
|
|
|
Outils nécessaires :
On veut une utilisation globale du linter sur le projet, on installera donc la dépendance au niveau du package.json
à a racine (cf. centralisation des fichiers package.json
via les workspaces).
Depuis un terminal, dans dev/
:
npm install --save-dev @commitlint/config-conventional @commitlint/cli |
Créer ensuite un fichier de configuration .commitlintrc.json
au même endroit avec la conf suivante :
{ "extends": ["@commitlint/config-conventional"], "rules": { "body-case": [2, "always", "sentence-case"], "body-max-line-length": [1, "always", 72], "header-max-length": [1, "always", 52], "type-enum": [2, "always", [ "build", "chore", "ci", "docs", "feat", "fix", "perf", "refactor", "revert", "security", "style", "test" ] ] } } |
Installer ensuite Husky. Cet outil va permettre de créer des hooks sur les commits GIT, et donc va nous permettre de valider le message du commit via commitlint avant que le projet ne soit commité.
Toujours au même endroit, depuis le terminal :
npm install --save-dev husky |
Ensuite pour activer les hooks, il faut se rendre à l'endroit où se trouve le dossier de config .git/
soit tout en haut de notre projet (au dessus de dev/
).
Depuis un terminal, se rendre donc à la racine du projet, et exécuter la commande :
npx husky install |
Un nouveau dossier .husky/
devrait alors apparaître.
On va alors lui indiquer la commande commitlint à exécuter au moment d'un commit en ajoutant un hook commit-msg :
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit ${1} --config $(dirname -- "$0")/../dev/.commitlintrc.json' |
Un fichier commit-msg
devrait apparaître dans le dossier .husky/
contenant la commande commitlint à exécuter à chaque commit.
A présent, dès lors que le message de votre commit ne répondra pas au nommage conventionnel, commitlint vous retournera une erreur et le commit ne passera pas.
Ici, le commit ne passe pas car le type (build, ci, fix, feat...) n'est pas précisé.
Ici, le type précisé (docker:) n'est pas autorisé par la liste des types définis par la convention de Angular.
Ici le commit ne passe pas car le sujet du message ne doit pas commencer par une majuscule.
Installer commitizen sur le projet
$ npm install --save-dev commitizen |
Ensuite, initialiser commitizen sur le projet, dans dev/
$ npx commitizen init cz-conventional-changelog --save-dev --save-exact |
Modifier la conf de commitizen. Éditer le fichier package.json
à la racine :
{ ... "devDependencies": { "cz-conventional-changelog": "^3.3.0" }, "config": { "commitizen": { "path": "./dev/node_modules/cz-conventional-changelog" } } } |
Une fois les modifications apportées au code et ajouté à GIT, il suffit d'exécuter la commande suivante :
$ npx cz |