Azure Devops – Pull Request (part 2)

Cet article est la suite de https://reactor.fr/azure-devops-pull-request/ On avait créé des règles de branche sur la master : interdiction d’effacer cette branche pas de git push direct sur cette branche règle de Pull Request (light) Ceci nous permet de sécuriser la branche master. Faisons de même avec la branche develop. Rappels Git Flow On a vu la PR develop –> master.  Maintenant, on va ajouter une PR sur chaque commit vers la branche develop. Si on applique Git Flow, on aura une branche feature qui devra à un moment livrer son contenu sur la develop.  La PR intervient à ce moment.  Règle de branche develop sur Azure Devops On va donc fairre un clic sur le menu de la ligne représentant la branche develop dans Repos – Branches, puis on sélection "Branch Policies" Pour la branch dévelop, j’ai rajouté plus de contraintes que la master. En effet je veux qu’en premier lieu chaque commit sur la branch dévelop corresponde à un work item. Ensuite si il y a une intervention d’un reviewer, celle ci doit être résolut par un commentaire. Dans la pratique ça peut simplement être une question qui ne demande pas vraiment d’intervention. Mais ça peut aller jusqu’à ce que le reviewer demande un refacto voir refuse carrément le code (c’est rare…) Je limite aussi le type de merge afin d’avoir un historique lisible et en cohérence avec la branche master. Ensuite j’ajoute une règle de build. Je sélectionne une nouvelle Pipeline que je viens de juste de crée : pool: vmImage: ubuntu-latest variables: buildConfiguration: ‘Release’ projectBlazorWasmServer: ‘src/BlazorDemo/BlazorDemo/Server/BlazorDemo.Server.csproj’ steps: # Publish Blazor Demo Server – task: DotNetCoreCLI@2 displayName: Publish inputs: command: publish publishWebProjects: false projects: ‘$(projectBlazorWasmServer)’ arguments: ‘–configuration $(buildConfiguration) –output $(build.artifactstagingdirectory)’ zipAfterPublish: false modifyOutputPath: false La seule différence avec l’autre pipeline de build, c’est que je ne précise pas le trigger. En effet, je ne connais pas le nom de la branche feature. Donc par défault ce sera la source de la PR concernée. Mise en situation Mon tech lead m’a affecté une tâche. On va aller la créer pour la simuler, normalement elle est déjà existante : Je suis développeur, je dois donc créer une branche si elle n’existe pas déjà. Sut mon terminal je tape : git checkout -b feat/LoginPage Je développe, quand j’ai fini : git add . git commit -m « mon travail sur la page login » git push –set-upstream origin feat/LoginPage Je peux bien évidement avoir plusieurs commit et/ou avoir d’autre commit d’autre développeurs. D’ailleurs (si vous avez les droits) n’importe qui peut aller voir ce qu’il se passe sur cette branche depuis Azure Devops : La Pull Request feat -> develop Azure Devops sait qu’une branche feat/LoginPage est en cours et vous propose directement de choisir celle ci et de créer une pull request à partir de celle ci. Dans mon cas j’ai eu ceci : C’était pas voulu, mais j’ai eu la surprise de voir que j’ai un conflit de merge. Et c’est finalement un point intéressant à montrer.  J’ai pas récupéré la branche develop dans mon dev sur ma branche feature. Et honnetement ça arrive TOUT LE TEMPS.  Normal, qq a pu entre temps livrer qq chose sur la branche develop. Il faut donc s’assurer que ce nouveau code s’intègre au mien. Il faut alors lancer toute une série de commandes git: git checkout develop git pull git checkout feat/LoginPage git rebase develop git pull git push Explication : on change de branche pour aller sur develop. On récupère la dernière version de cette branche. On re bascule sur notre branche feat. On applique ces nouveautés (rebase permet de garder un historique chronlogique en mettant nos modifs après celle de develop). A ce stade on est iso en local. Faut faire un pull pour que ça lance un merge automatique (ca met au carré le repo local et le distant et prépare au push) Et enfin on push sur le repo distant.   Maintenant on retourne sur Azure devops : Ya plus de conflit ! 🙂 si on regarde de plus prêt Il ne reste plus qu’à associer notre PR à un Work Item : Ce qui résoud le problème : On peut valider le PR : Ceci effacera la branche feat/LoginPage Au final : Conclusion Pourquoi c’est génial ? C’est vrai qu’avant on publiait directement sur develop et tout allait bien. Et vous avez pas tort. Chacun travail comme il le souhaite.  Avec cette façon de faire, vous allez prendre un petit plus de temps à faire un "peu de paprasse". Mais on a un suivi très intéressant sur chaque étape de la construction de morceau d’application. Tout est lié, et tout le monde peu savoir ce qu’il se passe. Qui travaille sur quoi et quand. Attention, faut pas le voir comme un outil de flicage, mais plutot un outil d’orchestration dans une équipe logiciel.  L’élément que j’ai peu évoqué ici, et qui est relié à a chaque PR c’est le board. Le Board permet de suivre des work items de plusieurs types : Chacun s’organise comme il veut. On peut créer autant de work item que l’on veut et utiliser scrum ou kanban Le développeur se focalise sur sa feature et traite de bout en bout celle ci (jusqu’à la branche develop) Le tech lead suit tout ça. A chaque fin de sprint, ou quand il le souhaite, il peut faire une release. Le product owner est au courant des évolutions de son app.  Azure Devops est vraiment un super outil.  Et j’ai pas fait le tour de toutes ses possibilités.

Azure Devops – Pull Request

Dans mon dernier article, j’ai introduis Git Flow avec un exemple, la naissance d’une application.  A un moment, je raconte l’évolution de l’équipe de dev et de leur organisation autour du code source. On y parle de Pull Request.  La PR est une procédure de validation d’un ensemble de commits regroupés dans une branche feature (quand on applique Git Flow). On peut aussi appliquer une PR de la branche develop vers master. C’est ce qu’on appelle une "release".  Chacun ayant ses stratégies, je vous propose la mienne, qui va bien pour un petit/moyen projet :  Situation J’ai 2 branches principales : master. A considérer comme la branche release car c’est ce code qui part en prod. develop. Son code part en staging. Ca sert aux dev pour voir le résultat de leur travail sans influencer la prod. Quand j’estime que la branche develop a quelque chose d’intéressant, je pousse le code vers la master (merge).  Cette action est réalisé via une Pull Request depuis Azure Devops. Je ne fais aucune manipulation git. Tout ce passe sur Azure Devops. D’ailleurs j’ai interdit toute manipulation de la branche master en dehors d’une PR. Voyons voir comment faire cela : Règle de branche master Sur Azure Devops, il faut se rendre sur l’onglet "Repos" puis "Branches" : Cliquez sur le bouton à droite de la branche master, ce qui ouvre un menu. Cliquez sur Branch Policies. Nous y voila, si on lit la première ligne, elle nous dit que si une seule des options est cochée, alors la branche ne peut pas être effacée et toute modification devra passer par une PR. Quelque part, je pourrais m’arréter la car c’est tout ce dont j’ai besoin. Mais on va voir qu’il y a quelques options bien intéressantes : Require a minimum number of reviewers. J’ai une équipe de 1 dev, moi. donc je vais m’auto évalué, ça n’a pas de sens. Je n’ai pas coché cette case. Mais c’est intéressant dès lors qu’on valide par un second dev (lead tech pour la master).  – Check for linked work items. Cette option est intéressante dès lors que l’on travaille avec un backlog. Ce qui n’est pas mon cas pour ce projet "demo". Mais c’est conseillé. En effet, vous allez améliorer chaque PR avec un "work item" qui sera donné par votre product owner ou votre tech lead. C’est hyper quali de faire ça. Surtout intéressante depuis une branche feature vers la develop. Ici depuis la branche develop vers la master, on aurait plus un ensemble de feature. A voir avec les types de work item. Si ca se trouve ça peut coller.  Check for comment resolution option pas obligatoire. Si coché, cela force à valider tout commentaire dans le code. On le verra plus tard, mais si un reviewer constate un manquement, une erreur ou une objection dans le code, il le signifie par un "commentaire". Si celui ci n’est pas "résolut", alors on peut pas valider la PR. A tester avec votre équipe. La encore, c’est intéressant pour une PR vers la branche develop  Limit merge types cette option permet de laisser le choix lorsque la PR est validé, de choisir le type de merge que l’on souhaite appliquer à la branche cible. Pour mon cas, je ne laisse pas le choix, j’impose un squash merge. La encore, c’est les goûts et les couleurs. It’s up to you. Je pense qu’un article entier peut y être consacré. On en discute encore dans l’équipe où je bosse…  On va maintenant rajouter des règles de build : On ajoute une règle qui impose qu’un build s’execute correctement. Pour cela on doit construire une pipeline de build. Si la branche develop ne build pas, alors on ne fait pas le merge. Pour ma part, le build est un publish. Ce qui revient a peu prêt au même (un publish est un build + génération des fichiers statics web dans le cas d’une app Blazor WASM).  Ma première Pull Request On va tester tout ça. On va dans Repos – Pull request Cliquez sur New pull request : Il faut choisir sa source et sa destination, pour nous, develop –> master Notez que j’ai juste mis un titre. On peut ajouter des reviewers et bien sûr un work item. Tout ca on le verra dans une pull request de type feature –> develop. Cliquez sur Create. Voici ce qui se passe : Première chose, on a un élément requis qui doit se lancer. Celui ci c’est notre "règle de build" écrite juste avant.  Notez aussi qu’il y a un check "No merge conflict". Ce qui permet de vérifier en amont qu’on a pas foiré un merge/rebase malencontreux.  Si on attends qq secondes : On voit notre pipeline qui se lance et qui passe au vert si notre publish est ok.  En haut a droite on a un bouton approve qui va concerner des validations "humaines". Tout est vert. On a un pre-merge ok. Un build ok. Pas de reviewer, et pas d’autre règle (j’ai volontairement fait en sorte que ce soit pas trop compliqué pour cet exemple)  Si on clic sur Complete On a un message qui veut supprimer develop. On veut pas. Surtout pas. D’ailleurs on fera en sorte par la suite de rendre develop ineffacable.  Le squash commit est l’unique option, comme indiqué dans les règles de la branche master que l’on vient de définir. On peut si on veut rajouter un commentaire personalisé de commit.   On clique sur Complete merge, quand il est fini, on a cette info : Et si on vérifie nos pipeline, notre DEPLOY master to prod est lancée ! On vient d’automatiser notre branche master. Elle est sécurisée (personne hormis une PR peut la modifier). Elle est tracable et on peut échanger via une interface web sur une operation qui d’habitude se passe en ligne de commande dans un coin.  De plus en rajoutant une seconde pipeline, lorsque la PR est validé puis mergé, on a un deploy automatique vers la prod.…

Azure Devops – Git Flow intro

Intro Git Flow tu connais ? non ? Et Git tu connais ? non…ouais faut faire un effort la monsieur (ou madame). Alors git j’explique pas. Si tu connais pas reviens me voir, mais va tout de suite apprendre qq commandes car c’est juste une tuerie ce truc. Quand t’as connus vss, svn ou team foundation server, tu sais que git te sauve la vie. Il est juste incontournable aujourd’hui. Ho tu pourras faire semblant qq heures, mais tu vas vite te retrouver dans l’impasse. Un conseil, tarde pas trop, apprends git ! Et en ligne de commande, pas avec un outil (quoi qu’un outil peut éventuellement t’aider, mais crois moi, fait tout en ligne de commande…) J’ai personnellement tardé à y passer. Trop. Et j’ai aussi utilisé des outils graphiques. Personne n’est parfait ! Alors si tu es encore la, tu sais ce qu’est une branche, un merge ou un rebase, un commit…   C’est quoi Git Flow ? A lire, surtout le premier : voici 3 liens : https://danielkummer.github.io/git-flow-cheatsheet/index.fr_FR.html https://grafikart.fr/tutoriels/git-flow-742 https://git-flow.readthedocs.io/fr/latest/presentation.html Ca cause Git Flow mieux que moi. Je suis ici pour vulgariser. Alors Git Flow c’est un ensemble de commandes git qui permettent de s’organiser autour du code source d’une application. Git Flow propose une stratégie pour gérer le cycle de vie d’une application coté code source, du développement locale jusqu’aux versions releases finale en passant par des branches qui auront un but précis.  En vrai, c’est juste des commandes git ! C’est une surcouche qui facilite la vie. Enfin en théorie. Perso j’utilise les principes de Git Flow mais pas ses commandes.  Pour expliquer Git Flow, on va se mettre dans un contexte, imaginons la vie d’une application, par exemple Tonder, une app web pour flirter.   V0.0.1 alpha – naissance d’une app Il était une fois un développeur en recherche d’amour (il veut ken à donf) et il lui vient une idée d’application qu’il nomma Tonder. Le dev est tout seul sur son projet. Il bosse dessus comme un ouf et sort sa premiere app Tonder Alpha 0.0.1 Il est content, mais c’est une version alpha. Elle tourne sur un serveur à lui dans sa piaule, bancale, comme son code.  V0.1.0 bêta Arpès quelques jours de discussion avec son hamster, son app ressemble à quelque chose, il veut faire tester son app et la rend disponible en version bêta privé. Il a donc une « prod » (toujours dans sa piaule) et il s’appercoit qu’il devient difficile de travailler directement sur sa prod sans prendre le risque de tout péter. Alors il crée une version « staging » sur laquelle il bosse.  Mais pour le moment, il existe qu’une « version » de son code. Aucun historique, tout est en local sur un disque dur de sa machine. Un virus, un feu domestique, un coup de foudre, pire trouver une meuf et avoir des gosses… il peut tout perdre.  Notre dev se dit qu’il serait bien d’avoir un controleur de code source qui lui permettra de  sauvegarder son code sur un cloud le rendre accessible à d’autre dev via ce cloud pouvoir gérer l’historique de son code  Alors il crée son repo Git, qq part où il sait qu’il sera accessible et disponible.  V1.0.0 Première release officielle Ca y est, notre dev sort enfin au grand publique sa super App. Il est fiert. Il est content. Son poil brille (il a pas pris de douche depuis 72h, 15 cannettes de coca trainent sur le bureau, il ne sait même plus quel jour on est, et si d’ailleurs c’est le jour ou la nuit …) Les retours utilisateurs arrivent. Il les traite comme il peut, avec le mécanisme suivant : « je code en dev locale, puis si ca marche je passe sur staging puis si ca plante pas je balance sur la production ». Il fait tout à la main, pas d’automatisation, il se dit qu’il a pas le temps pour ça et que c’est qu’une petite release de plus, ça prendra 5 min… Ils se dit qu’il aimerait bien un peu d’aide… et prendre l’air… V1.0.547 Ca build à donf Notre développeur ne compte plus le nombre de build qu’il a fait. Toujours à la main. Ce coup ci il décide d’automatiser sa chaine de livraison/deploiement continue. Il passe par : son premier build automatisé : https://reactor.fr/azure-devops-pipeline-ci-cd-first-build son premier deploiement automatisé : https://reactor.fr/azure-devops-pipeline-ci-cd-deploy ses versions automatisées : https://reactor.fr/azure-devops-pipeline-ci-cd-versioning multi environnement : https://reactor.fr/azure-devops-pipeline-ci-cd-environnement Il est vraiment satisfait. Certe il vient d’y passé quelques heures. Mais a présent il ne s’occupe ni de son staging, ni de sa prod. Tout est fait automatiquement. Et du coup il peut prendre l’air… ça lui rappel d’ailleurs qu’il a un chien… mais il est où son chien ? V1.1.41 1er co développeur Enfin un peu d’aide ! Un nouveau dev arrive en renfort. Git devient indispensable.  Jusque là, le repo git contient 2 branches, une master et une develop.  La branche develop est celle que les développeurs utilisent.  La master sert de branche « release ». Quand on estime que l’on a quelque chose, on pousse du code depuis la branche develop vers la master.  Une pipeline s’occupe de mettre à jour le staging dès que la branche develop reçoit un commit. Une pipeline s’occupe de mettre à jour la prod dès que la branche master reçoit un commit. Nos deux devs travaillent en simultané sur la branche dev. A chaque commit, on a run de pipeline, ca fait bcp de deploiement pour parfois pas grand chose. Alors nos deux devs décident de travailler en branche.  Chacun aura sa branche au départ. Mais nos développeurs se rendront compte qu’avoir une branche chacun revient à avoir deux versions de la branche develop (en plus de celle ci). Il ne profite pas des avancés de chacun et attendent que la branche develop soit à jour pour récupérer le travail de l’autre, via des cherry-pick ou des rebases hasardeux. C’est un peu confu, et nos deux devs décident d’appliquer Git Flow avec des branches feature (fonctionalités).  Ainsi, ils peuvent travailler tous les deux sur une feature si il…