Les pull requests volumineuses sont difficiles à examiner et créent des goulots d’étranglement, en particulier lorsque vous générez un volume élevé de code dans un court délai. La qualité de la revue se dégrade également à mesure que la taille des pull requests augmente. Les réviseurs peuvent parcourir rapidement le résultat, passer à côté de problèmes, ou procrastiner et laisser la pull request de côté jusqu’à ce qu’elle devienne obsolète et entraîne des conflits de merge.
Les pull requests empilées permettent de garder de grandes modifications de code faciles à relire.
Une pile est une série de demandes d’extraction dans le même référentiel où chaque demande de tirage cible la branche de la demande de tirage sous celle-ci, formant une chaîne ordonnée qui atterrit sur une branche unique, généralement votre branche principale. Au lieu d’une demande de tirage volumineuse, vous obtenez un ensemble de demandes de tirage plus petites. Étant donné que chaque demande de tirage a ses propres différences ciblées, les collègues peuvent examiner et approuver chaque couche indépendamment.
Ce tutoriel vous guide tout au long de l’utilisation des pull requests empilées pour créer une fonctionnalité en couches distinctes, chacune pouvant être revue séparément. Pour notre exemple, nous allons envisager comment ajouter l’authentification utilisateur à une application. Nous allons utiliser l’extension gh stack dans GitHub CLI.
Logiciels requis
Pour suivre ce tutoriel, vous devez installer GitHub CLI et l’extension gh stack . Vous aurez besoin des éléments suivants :
- GitHub CLI (
gh) 2.90.0 ou version ultérieure, et Git 2.20 ou version ultérieure.- Authentifiez-vous GitHub CLI avec
gh auth login.
- Authentifiez-vous GitHub CLI avec
- Dépôt GitHub vers lequel vous pouvez push.
Dans GitHub CLI, installez l’extension gh stack .
gh extension install github/gh-stack
1. Concevoir une pile avant de générer du code
Un bon stack, c’est comme construire une maison : commencez par une fondation solide, montez les murs, installez le câblage, puis terminez par les plaques de plâtre. Chaque couche est construite à partir de celle située en dessous. À la fin, un réviseur doit pouvoir lire les pull requests de bas en haut et suivre le développement de la fonctionnalité.
- Divisez la fonctionnalité en couches. Chaque couche doit être une modification distincte et cohérente qui peut être examinée indépendamment.
- Conservez chaque couche suffisamment petite pour que sa pull request se lise rapidement. Si une couche semble nécessiter une longue description pour être examinée, elle est probablement trop volumineuse.
- Décidez vous-même des limites. Vous possédez la forme de l’empilement.
- Triez les couches par dépendance. Les changements fondamentaux vont en bas. Tout ce qui dépend d’eux augmente. Pour l’authentification, il peut s’agir des points suivants :
- Couche 1 : modèle de données et migration
- Couche 2 : points de terminaison CRUD
- Couche 3 : middleware JWT et guards
- Couche 4 : tests unitaires et d’intégration
2. Créez d’abord la couche inférieure
Démarrez la pile avec la fondation. Tout ce qui précède dépend de la bonne configuration de cette couche.
- Créez la stack et créez la première couche en fonction de votre plan. Créez-le avec
gh stack init BRANCH-NAME-1, envisagez d’utiliser un préfixe pour conserver des noms de branche bien organisés. - Passez en revue le changement vous-même avant de continuer. Une erreur dans la couche inférieure se propage à chaque branche au-dessus de celle-ci, donc vérifiez-la avant de continuer.
3. Empilez chaque nouvelle couche de code au-dessus
Avec la base en place, générez le reste de la fonctionnalité une couche à la fois.
- Ajoutez la couche suivante et implémentez-la dans le contexte des couches ci-dessous. Ajoutez une branche au sommet de la pile avec
gh stack add BRANCH-NAME-NEXTet validez le travail là-bas. - Si une couche commence à devenir trop volumineuse, déterminez si elle a dérivé en dehors de son plan ou si vous avez réellement besoin de deux couches au lieu d’une.
- Créez de nouvelles branches pour chaque couche au fur et à mesure, de sorte que chaque branche reste un diff propre et autonome.
- Lorsque vous êtes prêt à créer des pull requests, envoyez votre stack avec
gh stack submit. - Laissez chaque pull request se suffire à elle-même. Un titre ciblé et une description concise et explicite de la couche sont généralement suffisants.
4. Passez en revue les demandes de fusion vous-même avant de demander une révision
Chaque couche est petite, ce qui facilite également l’auto-révision. Passez en revue chaque branche avant d’impliquer vos collègues. Les réviseurs doivent consulter les modifications auxquelles vous faites déjà confiance.
- Exécutez vos tests, linters et analyse du code sur chaque branche pour vérifier chaque couche par rapport à vos normes avant de demander des révisions.
5. Demander des révisions pour la stack, en commençant en bas
Avec les couches créées, les réviseurs obtiennent de petites différences au lieu d’un grand mur de code.
- Si les dépendances sont fortement intégrées, demandez des révisions en commençant au bas de la pile, afin de pouvoir intégrer les modifications en remontant la pile avant les révisions suivantes.
- Si vous avez besoin de révisions de personnes différentes pour différents niveaux, les réviseurs peuvent travailler en parallèle. Une personne peut passer en revue le modèle de données tandis qu’une autre examine les points de terminaison, et aucun des deux n’a à passer laborieusement en revue l’ensemble de la fonctionnalité.
6. Itérer sur les commentaires
Les commentaires de révision portent sur les couches individuellement, et non sur la fonctionnalité entière. Les stacks vous permettent de corriger la couche appropriée en place et de propager la modification vers le haut.
- Modifiez la couche signalée par un réviseur. Accédez à la branche appropriée, apportez la modification et validez-la là.
- Conservez chaque correctif dans la couche à laquelle il appartient. Une modification apportée à la mauvaise branche peut prêter à confusion et créer des erreurs en amont.
- Naviguer dans les branches avec
gh stack down,gh stack upough stack checkout BRANCH-NAME. Ensuite, validez vos modifications, exécutezgh stack rebase --upstackpour rebaser les branches ci-dessus, puisgh stack pushpour remonter les modifications dans la pile.
7. Fusionner avec le calque inférieur
Une stack se fusionne dans l’ordre, en commençant par la branche pointant vers votre branche principale. Fusionnez toutes les couches de modifications en même temps, ou une par une, et GitHub cible automatiquement la couche de modifications suivante pour qu’elle pointe vers main.
- Fusionnez la pile, une branche à la fois, en partant du bas vers le haut, ou depuis n’importe où dans la pile, et toutes les branches sous la pull request que vous fusionnez seront fusionnées en partant du bas vers le haut.
- La différence de chaque couche reste exactement la même par rapport à son parent, seule la base change, ce qui facilite la fusion d’une couche à la fois sans affecter le travail en cours ou les révisions.
- Utilisez une file d’attente de fusion pour que chaque modification fusionne dans l’ordre une fois qu’elle est approuvée et que ses vérifications aboutissent. Vous n’avez pas besoin d’attendre toute la pile d’un seul coup.
Une fois la couche supérieure fusionnée, la fonctionnalité est entièrement intégrée. Chaque modification a été examinée plus efficacement comme une petite modification délibérée plutôt qu’une pull request volumineuse.