Pourquoi ?

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 : 

Le format

En suivant le guide d'Angular, voici à quoi doit ressembler un message de commit :

<type>[(optional <scope>)]: <description>
<BLANK LINE>
[optional <body>]
<BLANK LINE>
[optional <footer(s)>]

Le type

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) :

Utilisation 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 (facultatif)

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.

Le résumé court (sujet du commit)

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.

Body (facultatif)

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.

Footer (facultatif)

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

Exemples

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.

Ajout d'une feature permettant d'exporter son EDT au format ical sur son téléphone

feat(@multi-backend/microservice-schedule): add ical format

Modification des appels au microservice d'authentification => ajout d'un token supplémentaire nécessaire dans le body

feat(@multi-backend/microservice-auth)!: add new access token in POST /auth url
 
BREAKING CHANGE: client needs to provide the new access token when calling the POST /auth url

Correction d'un bug sur la recherche dans l'annuaire

fix(@multi-backend/microservice-contacts) : update card result background color in dark mode

Modification de docs

docs(@multi-backend/microservice-main): update main gateway README

Comment ?

Outils nécessaires :

Installation et utilisation locale

Installation et configuration

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.

Utilisation en local

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.

Exemples de commit qui ne passe 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.

Exemple de commit qui passe

Utilisation de l'outil commitizen pour faciliter la rédaction des commits

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