Workflow Git : définir les conventions d’un projet
Par Maxime Bréhin • Publié le 2 octobre 2017
• 5 min
Précédemment dans « Workflow Git »…
- Objectifs et principes généraux
- Développer des fonctionnalités en parallèle
- Livrer et maintenir des versions publiques
- Corriger des bugs
- Définir les conventions d’un projet (cet article)
Définir les conventions d’un projet
La définition ou l’utilisation de conventions au sein d’une équipe, d’une entreprise ou d’une communauté favorise la pérénité des projets qui y adhèrent.
Les bénéfices sont multiples :
- On uniformise les travaux effectués ;
- On favorise la lecture et l’analyse de l’historique du projet ;
- On fournit un socle pour automatiser certaines tâches ;
- On réduit le coût d’entrée/d’apprentissage du contexte projet pour un acteur connaissant ces conventions ;
- On optimise la création et la gestion de nouveaux projets basés sur des règles existantes ;
Faciliter la lecture de l’historique
Commits
Le bon nommage des messages de commits est souvent un signe de qualité de la gestion du projet et du bon découpage des tâches.
Le but est de définir un schéma logique d’écriture de ces messages, car Git n’impose aucune contrainte.
On trouve de nombreuses initiatives qui proposent des normalisations.
L’une des plus connues est probablement le conventional changelog.
Elle consiste à fournir en première ligne une description concise de la tâche couverte par le commit, puis des informations complémentaires dans les paragraphes suivants.
On facilite ainsi la lecture du log d’une part, la génération automatique du changelog (ou release notes) d’autre part, en listant la première ligne de chaque message d’un point A de l’historique à un point B (en général ces points sont définis par des tags).
Voici un squelette d’exemple de message de commit conventionnel :
<type de tâche>(<périmètre>): message court
Description complémentaire/complète
Référence/action sur un ticket définissant cette tâche
On obtient alors des historiques faciles à analyser :
> git log --graph --oneline -12
* 3855f12 fix(ci): restrict Jest to app/assets tests (void vendor/bundle stuff)
* c872d19 fix(tests): restore working JS tests
* d57ef3b chore(docs): Annotated source with groc for JS code
* 9600601 feat(uploads): finalized React components for dialog-based uploading
* 74b72c1 infra(uploads): add `extraClass` to `<Button/>` and `<SubmitButton/>`
* 9399973 chore(js): expose admin L10n to React
* aa96ea2 chore(uploads): add Semantic UI’s dimmer/modal modules
* 2be485f chore(uploads): upgrade react-s3-uploader to prune factory warnings
* 5eb190d chore(console): Add awesome_print. Require it in your `.pryrc` for `ap`
* 18109a4 test(uploads): add missing test coverage for recent devs
* f73eb02 feat(uploads): upload creation (and last-minute S3 rename) action
* d43d8f7 feat(uploads): S3 upload forms now handle abort-and-remove behaviors
On peut alors imaginer créer un aperçu des changements effectués sur le projet (release notes) en regroupant les commits par thématique :
New features
-------------
# Uploads
- S3 upload forms now handle abort-and-remove behaviors
- Upload creation (and last-minute S3 rename) action
…
Patches
-------
- Restore working JS tests
- Restrict Jest to app/assets tests (void vendor/bundle stuff)
…
Chore updates
-------------
- Add awesome_print. Require it in your `.pryrc` for `ap`
…
Des outils tels que commitizen et commitlint peuvent vous assister dans la construction de vos messages de commit.
Branches
Nous avons déjà marqué notre souhait de d’identifier les sous-ensembles de développement en utilisant des branches.
Au même titre que pour les commits, l’organisation et la lecture de celles-ci sera facilitée si leurs noms sont conventionnels.
Voici un exemple de convention basé sur le GitLab flow :
- Branche de développement principale :
master
. - Branche de pré-production pour tests fonctionnels et intégration :
pre-production
. - Autres branches :
<contexte>/(<périmètre>/)<fonction>
(périmètre optionnel) - Branches de fonctionnalités créées depuis
master
: contextefeat
. - Exemple
feat/ux/a11y
: périmètre « expérience utilisateur », fonction « accessibilité ». - Branches de correctifs créées depuis
production
: contextehotfix
. - Exemple
hotfix/42-form-submit
: ici un numéro de ticket est utilisé avec un nom décrivant la fonction impactée (le périmètre n’est pas nécessaire).
ATTENTION : l’utilisation du délimiteur « / » dans les noms de branches ne vous permettra pas avec Git d’utiliser les noms intermédiaires.
Par exemple si vous créez une branche feat/ux/a11y
, vous ne pourrez pas créer de branche feat/ux
. Préférez alors un autre séparateur : feat-ux
, feat-ux-a11y
.
Versions logicielles
Les ensembles d’évolutions d’un projet peuvent être identifiés à l’aide des tags (de préférence annotés).
Nous avions vu précédemment le Semantic Versioning qui est une convention très répandue.
Ces noms identifiables permettent dès lors des automatisations telles que la génération automatique d’un changelog entre deux versions majeures ou mineures.
Style de code
L’uniformisation d’un projet passe également par des choix stylistiques et structurels au sein des fichiers sources, ainsi que leurs règles de nommage.
Et comme on ne réinvente pas la roue, on peut utiliser des conventions de style déjà existantes :
- Coding Style de Mozilla
- Google style guides
- et bien d’autres…
Vous pouvez également encourager l’utilisation d’outils pour analyser le code, voire automatiser ces analyses :
- Linters : analyse statique de code (ex : StandardJS, BuddyJS, Prettier, JsBeautifier pour JavaScript)
- Code quality : algorithmes, fuites mémoires… (ex : SonarQube, Code Climate, Snyk, Plato, Stylelint)
Gestion de projet
Le cycle de vie d’un projet implique de définir des objectifs fragmentables en tâches qui seront affectées aux différents intervenants.
La définition des tâches constituant un projet peut aujourd’hui être directement intégrée dans les interfaces de serveur Git (GitHub, GitLab, Bitbucket). On crée alors un ticket ou issue pour chaque tâche.
Certains systèmes vont même au-delà de la simple définition de tickets en offrant des interfaces de gestion de projet avancées (échéances/milestones, dates butoirs, étiquettes/labels, kanban board…). Ceci évite la multiplication des logiciels et des éventuelles passerelles entre ceux-ci.
Qu’ils soient intégrés ou non dans votre serveur Git, vos tickets peuvent suivre des conventions de nommage, de rédaction, d’organisation (labelling).
On peut imaginer un découpage pour normaliser l’écriture des demandes (issues) :
- Demande de nouvelle fonctionnalité (ex: étiquette
Fonctionnalité
) - Demande de correctif (ex : étiquette
Bug
)
Il en va de même pour les pull requests.
Exemple : utilisation du préfixe WIP
pour les pull requests dont le travail n’est pas encore terminé (jetez un œil à la gestion GitLab des « WIP » merge requests).
Selon le serveur Git que vous utiliserez vous aurez parfois la possibilité d’éditer des gabarits d’issues et/ou de pull requests :
- GitHub : issue and pull request template
- GitLab : issues and merge requests templates
Documentation
L’organisation des fichiers participant à la documentation de vos projets aidera à l’immersion d’un nouvel acteur en lui permettant de retrouver facilement les informations utiles.
Des conventions existent pour certains noms de fichiers. Ceux-ci son souvent suggérés dans les interfaces des serveurs Git qui proposent parfois des gabarits automatiques.
Voici les exemples d’aides de GitLab :
README.md
Les fichiers README.md
peuvent être placés dans les différents répertoires de vos projets et apporter des informations utiles sur la fonction du projet ou d’un sous-ensemble.
Dans la plupart des interfaces de serveur Git, il est automatiquement affiché comme page de présentation du projet ou du sous-dossier.
INSTALL.md
Lorsque cela s’avère nécessaire, la procédure d’installation du projet doit être documentée. On peut la séparer de la présentation du projet dans un fichier INSTALL.md
qui sera référencé depuis le README.md
.
CONVENTIONS.md
On y retrouve la liste des conventions du projet :
- Historique Git : nommage des commits, des branches et tags ;
- Coding Style : syntaxes à réspecter par langage ;
- Gestion de projet : nommage des issues et pull requests.
Ce contenu est souvent présent dans le fichier CONTRIBUTING.md
et ne nécessite alors pas la présence du fichier CONVENTIONS.md
.
CONTRIBUTING.md
Il s’agit des règles à suivre pour contribuer au projet. Il pourrait aussi bien s’appeler WORKFLOW.md
ou PROCESS.md
(que l’on trouve parfois en complément).
On retrouve très souvent ce fichier dans le monde de l’open-source. Les mainteneurs d’un projet y décrivent les règles à suivre pour participer au projet de manière à ne pas devoir les répéter systématiquement.
Cela peut tout à fait être transposé dans un projet privé.
On peut y insérer un lien vers les conventions, puisqu’elles font partie intégrante des règles d’un projet, et pourquoi pas un lien vers cette série d’articles 😁 .
Quelques exemples de procédures de contribution :
- GitLab contribution guidelines
- Node.js contribution guidelines
- Rails contribution guidelines
- Atom contribution guidelines
CHANGELOG.md
Ce fichier décrit les évolutions successives d’un projet (entre versions).
Il existe des systèmes permettant d’automatiser la génération des release notes :
LICENSE.md
On retrouve ce fichier principalement dans l’open source puisqu’il décrit les droits d’exploitation du projet. Il n’a pas d’intérêt dans un projet privé.
Certains serveur Git intégrent les différents gabarits de licences open-source.
Et maintenant ?
Si vous êtes arrivés à la fin de notre série d’articles sur les workflows, vous êtes parés pour mettre en place vos propres workflows 🙌 .
Ne vous inquiétez pas de la complexité, soyez progressifs et demandez-vous quelle prochaine étape vous apportera le plus de confort et de qualité 🤔 .
À lire ou à relire :
- Objectifs et principes généraux
- Développer des fonctionnalités en parallèle
- Livrer et maintenir des versions publiques
- Corriger des bugs
- Définir les conventions d’un projet (cet article)