--- title: Organiser le développement en équipe avec git theme: ./_themes/5ika.css verticalSeparator: revealOptions: transition: 'fade' --- # **Organiser le développement en équipe avec git** À la fin de la master class, les participants seront en mesure de : - Comprendre comment et pourquoi utiliser un modèle de branche git - Utiliser les outils de gestion de projet de GitHub liés à la base de code - Effectuer des tâches simples avec Docker --- # Tim Izzo - Ingénieur IT et développeur - Travail chez [Octree](https://octree.ch) et en tant qu'indépendant - Enseigne les réseaux et la sécurité IT - Approche minimaliste et écologique du développement 🦌 [5ika.ch](https://5ika.ch)
✉️ [tim@5ika.ch](mailto:tim@5ika.ch)
👔 [LinkedIn](https://www.linkedin.com/in/tim-izzo/) --- Qui êtes-vous ? --- **Vous êtes membre d'une équipe de développement devant développer un site web.** Vous avez besoin de: 1. Organiser le développement à plusieurs pour ne pas vous marcher sur les pieds 2. Tester votre site web pendant le développement pour s'assurer que tout fonctionne à chaque étape 3. Déployer votre site web en production une fois qu'une version est prête --- Pour comprendre les différentes étapes, nous allons toutes et tous collaborer sur une même base de projet: https://github.com/5ika/Deer
![Capture d'écran du site](img/deer.png)
--- # Créer un projet git ```bash # Je me déplace dans le dossier qui contient mon site cd /home/tim/projets/Deer # J'initialise git pour ce dossier git init # J'ajoute toutes les modifications à la zone de staging git add -A # Je crée un premier commit git commit -m "🎉 First commit" ``` > Pas besoin de réaliser cette étape de votre côté. > Elle est à faire une seule fois par la personne qui initialise le projet. --- # Synchroniser le projet avec GitHub Dans un premier temps, je crée un nouveau projet sur GitHub puis je connecte mon dépôt local avec le dépôt distant. ```bash # Je configure un dépôt distant (en utilisant l'adresse SSH plutôt que HTTP) git remote add origin git@github.com:5ika/Deer.git # Je push la branche locale 'main' sur le dépôt distant git push -u origin main ``` Le dépôt local correspond au dossier sur ma machine tandis que le dépôt distant correspond au projet GitHub. > Pas besoin de réaliser cette étape de votre côté. > Elle est à faire une seule fois par la personne qui initialise le projet. --- # Récupérer le projet sur sa machine 🫵 **À vous !** En tant que collaborateur/trice, vous pouvez récupérer le code du site sur votre machine en le *clonant*. ```bash # Je me déplace sur ma machine à l'endroit où je place mes projets cd /home/tim/projets # Je récupère le projet commun depuis GitHub git clone git@github.com:5ika/Deer.git # Je me déplace dans le nouveau dossier contenant le code cd Deer ``` --- # Exploration Les commandes suivantes nous permettent de constater ce qui se passe: ```bash # Lister les fichiers et dossiers présents dans le projet ls -la # Voir les commits déjà faits sur le projet git log # Voir les modifications pas encore dans un commit git status ``` Ces commandes ne modifient rien. Elles servent juste à voir. On peut en abuser 😁 --- Nous avons désormais toutes et tous une copie du même projet sur notre machine avec un seul commit: celui que j'ai fait. Maintenant, **comment ajouter du nouveau code dans notre projet ?** Que se passe-t-il si chacun.e fait un commit et le push sur GitHub ? 🤔 ---
![](img/git_parallel.png)
--- # Les branches Comme les commits forment une suite ordonnée, on appelle un ensemble de commits une **branche**. Le dernier commit correspond à la version la plus actuelle de notre code. On nomme ce commit le *HEAD*. C’est le bout de la branche. ![](img/git_branch.png) Par défaut, quand rien n'est précisé, les commits sont automatiquement ajoutés à la branche nommée *main*. --- # Les branches Il est possible de créer plusieurs branches pour paralléliser le travail sur une même base de code. ![](img/git_branches.png) --- # Créer une nouvelle branche La commande suivante crée une nouvelle branche `my-new-branch` à partir du dernier commit de la branche `main`. ```bash git checkout -b my-new-branch ``` Tous les commits qui seront faits ensuite seront placés sur cette nouvelle branche. --- # Se déplacer entre les branches Si on retire le `-b` dans la commande, on indique qu'on souhaite juste se déplacer d'une branche à une autre. ```bash # Je me trouve sur la branche `my-new-branch` git checkout main # Je me trouve maintenant sur la branche `main` git checkout my-new-branch # Je me trouve sur la branche `my-new-branch` git checkout one-more-branch # Erreur car la branche `one-more-branch` n'existe pas git checkout -b one-more-branch # Je me trouve sur la branche `one-more-branch` ``` --- Pour voir sur quelle branche on se trouve, on peut utiliser la commande suivante: ``` git branch ``` Cela retourne par exemple: ```bash * main my-new-branch one-more-branch ``` J'ai donc 3 branches actuellement et je me trouve sur la branche *main* (celle indiquée par un `*`). --- # Supprimer une branche Pour supprimer une branche locale: ```bash # D'abord, je me déplace sur une branche autre git checkout main # Ensuite, je retire la branche git branch -d one-more-branch # On peut vérifier avec git branch ``` --- # Pusher une nouvelle branche Quand on crée un nouvelle branche, elle n'existe que localement dans un premier temps. Comme un commit, il faut la *pusher* sur GitHub pour qu'elle soit visible par les autres devs. ```bash git push -u origin my-new-branch ``` Ici, on indique que l'on veut pusher la branche `my-new-branch` vers le dépôt distant nommé `origin`. `origin` est un alias correspondant à notre projet commun sur GitHub. --- 🫵 À vous maintenant de **créer une nouvelle branche** à partir de la branche *main* et de la **pusher sur GitHub**. Pour qu'on puisse s'y retrouver, nommer cette branche avec votre prénom, sans accent, sans majuscule et sans espace. Il faut donc entrer deux commandes que l'on a vu dans les slides précédentes. > Vous pouvez constater sur GitHub que votre branche s'y trouve bien pour vérifier. --- # Faire un commit Désormais, nous avons toutes et tous une branche à notre nom sur notre machine et sur GitHub. Pour le moment, cette branche est identique à la branche *main* car nous n'avons pas fait de commit dessus. 🫵 De votre côté: 1. Modifiez un petit peu le CSS ou le HTML du projet. Par exemple, changer la couleur de la tête du cerf ou un autre élément. 2. Créez un nouveau commit avec votre modification (sur votre branche, pas sur *main*) 3. Pusher ce commit sur GitHub 4. Constater sur GitHub que votre commit est présent **au niveau de votre branche** --- # Faire un commit
![](img/git_steps.png)
--- # Code review: C'est quoi ? Dans une équipe de développement, pour assurer une bonne **qualité de code** et éviter que chaque dev porte seul.e la responsabilité du code qu'il ou elle produit, il est courant de faire du *code review*. Cela consiste à faire relire son code par une autre personne de l'équipe afin de s'assure que le code est bien fait, les choix sont bons, les règles de l'équipe sont respectées et que le cahier des charges est remplie. > Dans certains projets, il y a une personne spécifique qui s'occupe de faire > tout le code review. On la nomme *Mainteneur/euse"*. --- # Code review: C'est quand ? En tant que dev, nous faisons généralement du code review au moment où nous souhaitons que les modifications faites sur notre branche soient ajoutées sur la branche principale (*main*). Pour ce faire, nous créons une **Pull Request** sur GitHub. Une Pull Request est la manière de demander à l'équipe de dev de **merger** notre branche dans la branche principale. Cette fonctionnalité permet à des centaines de devs de collaborer sur un projet, notamment dans le monde de l'Open-Source. => [Exemple avec le projet Caroster](https://github.com/octree-gva/caroster) --- # Créer une Pull Request On crée une Pull Request directement sur l'interface de GitHub, dans le menu *Pull Requests* du projet. On nous demande d'indiquer deux branches: - Un branche **source** qui correspond à la branche que l'on souhaite merger. - Une branche **destination** qui correspond à la branche qui doit recevoir les changements. Généralement, c'est *main*. 🫵 **À vous** de créer une Pull Requests au niveau du projet GitHub commun pour demander que l'on merge votre branche dans la branche *main*. Note: Repasser sur quelques Pull Requests faites pour montrer la page d'une Pull Request et le système de commentaires --- Imaginez la situation suivante : 1. Alice a modifié la couleur de la tête du cerf ([ligne 101 de style.css](https://github.com/5ika/Deer/commit/be7f148d518c61fc77d18eab2154dcf6443be185#diff-b78be019f1dc6d57753ea900c3805b114cd53ab7c0db836cc081836df1b99b7aR101)) dans sa branche 2. Bob a également modifié la couleur de la tête à la même ligne dans sa propre branche 3. Les deux devs font une Pull Requests pour demander que l'on merge leur branche dans *main* Est-ce que vous voyez un problème ? 🤔 --- # Conflits Cette situation s'appelle un **conflit**: Comme Alice et Bob travaillent en même temps, ils ne savent pas ce que l'autre fait. Quand on demande à git de merger leur travail, le programme ne sait pas comment faire car la machine est incapable de définir lequel des deux à le + raison. Il est donc nécessaire de passer par une action humaine pour résoudre cela. 1. On merge une première branche dans *main* (disons, celle d'Alice). GitHub nous indique un conflit au niveau de la branche de Bob. 2. Bob merge *main* (avec les modifications d'Alice) dans sa branche à lui. 3. Bob résout les conflits entre l'état actuel de *main* et ses modifications puis push les corrections. 4. On merge la deuxième branche dans *main* --- # Éviter les conflits Les conflits git ne sont pas désirables et en tant que dev, on cherche à en avoir le moins souvent possible. Pour cela, quelques règles à respecter: - Pullez souvent pour mettre à jour votre copie locale avec ce qu'il y a dans le dépôt commun - Il est préférable de faire beaucoup de petits commits avec peu de modifications que des commits avec énormément de modification: plus facile à débugger, à lire, à commenter et à revenir en arrière - Avoir une bonne gestion de projet pour éviter que deux personnes de l'équipe travaillent sur la même chose en même temps --- # Gestion de projet avec GitHub Suivant l'approche Agile / SCRUM, GitHub propose des outils au niveau d'un projet pour organiser le projet autour du code. Il y a notamment deux outils très utiles : - Les **Issues** qui permettent de lister des fonctionnalités à développer ou déclarer des bugs/problèmes - Les "**Projects**" qui permettent d'organiser les issues --- # Issues Les issues sont très utilisées. Très grossièrement, cela correspond à la liste des tâches de développement à faire pour faire avancer un projet. Leur utilisation est très flexible et chaque projet s'organise comme il le souhaite. En exemple dans ce cours, nous allons voir une utilisation compatible avec une approche Agile/SCRUM. --- # Étape 1: Créer les issues En début de projet, on crée une issue pour chaque fonctionnalité qu'on souhaite implémenter dans l'itération Agile à venir. 🫵 Par équipe de 2, créez une issue décrivant une fonctionnalité originale à faire. Évitez d'avoir la même qu'un autre binôme. > Pas besoin de voir trop compliqué. Cela doit pouvoir être fait rapidement, en quelques lignes de CSS, HTML ou JS. Une fois l'issue créée: - Assignez les deux membres du binôme au niveau du champ *Assignees* - Assignez l'issue au *projet* "Développement du site web" - Au niveau du [projet Développement du site web](https://github.com/users/5ika/projects/1), glissez votre issue dans la colonne "In Progress" Note: Faire un exemple en // --- # Étape 2: Créer une branche À chaque fois qu'on implémente une nouvelle fonctionnalité, décrite dans une issue, on crée une nouvelle branche dans le dépôt avec un nom clair. Ces branches qui concernent de nouvelles fonctionnalités s'appellent des **feature branches**. 🫵 Créez une branche sur laquelle vous allez prochainement modifier le code pour implémenter la fonctionnalité décrite dans votre issue. Vous pouvez donnez un nom clair à la branche. Par exemple `ajout-3e-oeil`. > Un seul des deux membres du binôme doit faire le travail mais les deux doivent comprendre ce qui est fait. --- # Étape 3: Développer ! 🫵 Sur votre machine, développez la fonctionnalité sur la bonne branche et pushez le ou les commits sur GitHub. --- # Étape 4: Créer une Pull Request 🫵 1. Créer une Pull Request pour merger votre branche dans *main* 2. Assigner le membre du binôme qui n'a pas fait le développement à la PR (Pull Request) 3. Sur la page projet "Développement du site web", glissez votre issue dans "In Review" --- # Étape 5: Code Review 🫵 La personne assignée à la PR peut maintenant relire le code et éventuellement faire des commentaires si le travail est incomplet ou incorrect. Une fois que tout est bon, elle peut *merger* la Pull Request pour l'ajouter à *main*. Puis, on peut déplacer l'issue dans la colonne "Done" sur le projet. > À cette étape, il y aura surement des conflits et des résolutions à faire. Nous allons gérer cela > au cas par cas. --- # Bravo 🎉 Nous avons développé ensemble une nouvelle version du site web. Le travail pratique d'aujourd'hui n'est pas si loin de la réalité. En général: - La création des issues est faite de manière plus réflechie en impliquant le Product Owner, le client et d'autres rôles - Le code review est une étape qui prend du temps et qui peut nécessiter plusieurs aller-retours --- # Liaison entre commits et issues Quand on crée une issue, il lui est attribué un numéro. Par exemple, l'issue https://github.com/5ika/Deer/issues/1 a obtenu le numéro `1`. Quand on fait un commit, dans le *commit message* on peut ajouter `#1` pour indiquer que ce commit est lié à notre issue. GitHub est ensuite capable de comprendre cela et de faire des liens sur l'interface. C'est facultatif mais c'est très utile quand on avance dans un projet afin de garder un historique cohérent et de pouvoir s'y retrouver dans le futur. Note: Faire une démonstration --- # Bugs 🐛 Les bugs font parties intégrantes du développement. Ils peuvent être trouvés par différentes personnes: devs, testeurs, clients, utilisateurs/trices, contributeurs/trices,... Les issues servent également à relever et gérer les bugs: quand une personne rencontre un souci, elle peut créer une issue détaillant son bug. On peut ensuite gérer un bug comme une feature avec notre gestion de projet. La modification du code relatif est faite sur une *fix branch* qui sera aussi soumise à travers une Pull Request. Note: Montrer des exemples d'issues bug dans un projet Open-Source sur GitHub --- ![Exemple de mauvaise issue de bug](img/bug_bad.png) --- # Relever un bug Quand on crée une issue de bug, il est important d'être le plus clair possible pour faciliter la résolution. Il est important de fournir: - Une description claire du bug - Les étapes permettant de **reproduire** le problème - Une description de ce qui est attendu - Des captures d'écran ou une vidéo pour montrer [Exemple de bug dans le projet Strapi](https://github.com/strapi/strapi/issues/16539) --- Sur un projet git, tout le monde est libre de créer des branches et les nommer comme il ou elle veut. Quand on travaille à plusieurs et/ou sur une longue période, cela devient vite chaotique 💥. ![Branches chaos](img/branches_chaos.png) --- En équipe, il faut donc se mettre d'accord sur une manière de gérer les branches afin de rester efficaces. On appelle cela un **modèle de branche** 🌳 --- Le modèle de branche le plus utilisé est le *Feature Branch Worflow*. ![](https://wac-cdn.atlassian.com/dam/jcr:09308632-38a3-4637-bba2-af2110629d56/07.svg?cdnVersion=1004) ... et c'est celui que nous avons déjà appris précédemment. C'est le fait d'utiliser une autre branche que la principale pour faire des modifications: feature branch, fix branch,... > Ce modèle est la base des autres modèles, il est donc important de bien le comprendre. > [Cette documentation](https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow) est > particulièrement bien faite pour comprendre (en anglais). --- # Feature Branch Worfklow 1. Je crée une branche annexe (feature ou fix) dans laquelle je fais mes modifications 2. Je crée une Pull Request pour demander que l'on merge ma branche dans *main* 3. Une autre personne vérifie mon code et je l'affine si nécessaire 4. L'autre personne valide la Pull Request et les commits de ma branche sont ajoutés à *main* 5. Je supprime ma branche annexe (si ce n'est pas fait automatiquement) --- # L'ancien modèle 'Gitflow' ![Ancien modèle Gitflow](https://wac-cdn.atlassian.com/dam/jcr:34c86360-8dea-4be4-92f7-6597d4d5bfae/02%20Feature%20branches.svg?cdnVersion=1004) --- # Et dans les projets Open-Source ? Dans les projets Open-Source, il n'y a pas une équipe précise qui travaille sur le code car tout le monde peut participer et proposer des modifications. **Mais comment faire pour autoriser tout le monde à modifier le code sans perdre le contrôle de son app ?** --- # Fork ! 🍴 GitHub nous permet de *forker* des projets. "Forker" signifie *copier tout le projet et son historique vers son propre espace*. En forkant un projet, j'obtiens une copie de tout le code de ce projet sur laquelle j'ai le droit de faire ce que je veux. Note: Faire un exemple de fork de Caroster --- # Forking workflow Le forking workflow est un modèle de branche très semblable au feature branch workflow mais considère des branches qui ne sont pas dans le même projet. --- Par exemple, je souhaite proposer une modification de code au projet Strapi. Voilà les étapes qui je réalise: 1. Je fork le [dépôt de Strapi](https://github.com/strapi/strapi) pour obtenir [ma propre copie](https://github.com/5ika/strapi) 2. Sur la branche *main* de mon dépôt, je push des commits 3. Une fois que je suis satisfait des modifications, je crée [une Pull Request](https://github.com/strapi/strapi/pull/14280) au niveau du dépôt officiel de Strapi pour demander aux devs de Strapi de merger la branche *main* de mon dépôt (`5ika:main`) dans la branche *main* du dépôt officiel (`strapi:main`) Ensuite, un mainteneur de Strapi va regarder ce que je propose comme modification et me faire des commentaires. Selon ses retours, je vais ajuster mon code jusqu'à ce que ça corresponde aux attentes du projet officiel jusqu'à ce que la branche soit mergée. --- 🫵 Forkez le projet [Deer](https://github.com/5ika/Deer/) avec votre utilisateur GitHub et remarquez ce qui fait. Vous pouvez maintenant modifier le code comme vous voulez, sur les branches que vous voulez car vous êtes sur une copie du projet principal. --- 🫵 Faites un commit sur la branche *main* de vôtre copie de dépôt Deer avec une petite modification de code puis créez une Pull Request au niveau du [dépôt principal](https://github.com/5ika/Deer/) pour me soumettre votre proposition de changement. --- Des questions concernant git et l'utilisation des branches ❓ --- # Oh Shit, Git !?! 💩 Git est puissant et très élastique mais il peut arriver qu’on se perde dans son utilisation et dans les pires des cas, qu’on perde des modifications. Un site référencie les plus grosses mauvaises manipulations et comment les résoudre: http://ohshitgit.com/