Azure DevOps : Repos

Dans les différentes fonctionnalités d’Azure DevOps vues en introduction, le Repos est la base incontournable à tout projet. C’est la fonctionnalité qui permet de déposer le code source de l’application, de le versionner, et de travailler en équipe. Voyons tout cela en détail.

Qu’est-ce qu’un contrôle de code source ?

Les outils tels qu’Azure DevOps sont construits autour de la fonctionnalité principale qu’est le contrôle de code source, avec Azure Devops Repos en l’occurrence. Mais qu’est-ce donc?

Le contrôle de code source, c’est un service proposé par un logiciel et qui va être chargé de sauvegarder les modifications de … votre code source. Le principe de ce type d’outil est assez basique : c’est souvent un service chargé d’analyser vos fichiers dans un répertoire donné. Si le fichier change, cette modification est détectée, et on vous propose alors de sauvegarder les modifications effectuées.

Une détection sur un simple fichier texte. Ce n’est pas forcement pour du code

Si aujourd’hui vous utilisez des services collaboratifs tels que Onedrive, Sharepoint ou Google Drive, dites-vous que c’est un peu l’ancêtre de cela, mais orienté développeurs.

Quels sont les avantages du contrôle de code source ?

Les avantages de ce type d’outils sont vraiment importants, à tel point qu’ils font l’unanimité dans le monde du développement. Des technologies telles que Git ont connu une adoption extrêmement rapide car cela répondait à des besoins cruciaux. Là encore, pour faire référence à Google Drive & co, si vous travaillez aujourd’hui avec des documents collaboratifs via ces technologies, imaginez la souffrance de travailler à plusieurs sur un même document mais sans cela. Et bien pour les développeurs c’est ça, mais avec des dizaines, des centaines de fichiers !

Voici quelques avantages donc :

  • Sauvegarde distante : le code source est déposé sur un serveur externalisé, ce qui garantit une sauvegarde, en plus de facilement sauvegarder le serveur en question
  • Travail en équipe : qui dit serveur, dit outil accessible simultanément par plusieurs personnes. Le travail collaboratif est le fondement de ce type de solution
  • Sécurité : le travail collaboratif, ça veut dire pouvoir avoir des reviews plus simple de son travail par les pairs. Ca implique donc plus de contrôle, ce qui améliore la maintenabilité et la sécurité du logiciel sur le long terme (même si ça demande un peu de process)
  • Formation : le contrôle entre pairs, ça veut dire aussi se former et former les autres ! On apprend de ses erreurs, on voit des choses chez nos pairs qu’on ne connaissait pas, on pose des questions … Cela permet de tirer l’ensemble de l’équipe vers le haut !

Comment fonctionne le versionning de code source?

Azure DevOps vous propose un contrôle de code source qui supporte deux protocoles : l’incontournable Git, et TFVC (qui est le contrôle de code source proposé par Microsoft).

Le protocole est défini lors de la création d’un nouveau projet. Par défaut, c’est Git qui est sélectionné. Les différents exemples qui vont suivre, ainsi que les démonstrations, seront sur des projets gérés avec Git.

Premiers pas sur Azure DevOps

Le principe de Git est assez simple : un répertoire de votre machine va être géré par Git et lié à un dépôt sur un serveur.

Lorsque vous allez travailler sur un projet, vous allez nécessairement modifier des fichiers. Git va être justement chargé de détecter les changements qui ont été effectués. Ces changements pourront alors être revus pour vérifier qu’ils soient bien conformes, pour ensuite créer un point de sauvegarde (appelé commit). Les changements en attente le sont toujours vis-à-vis du dernier commit à partir duquel on travaille. Une fois le travail sauvegardé, il peut être envoyé sur le serveur par l’action push.

Exemples de modifications détectées par Git. Une modification et un ajout de fonction ont été détectés ici.

Un outil collaboratif

Une fois envoyée sur le serveur, cette version devient accessible à l’ensemble de l’équipe. C’est là l’une des forces des logiciels de contrôle de code source : ce sont non seulement des outils de sauvegarde et de collaboration, mais aussi de versionning. Il est possible de voir l’ensemble des fichiers modifiés, ce qui a été modifié, par qui, ainsi que le commentaire associé à ce changement. Ce sont des données particulièrement utiles lors de besoin de contrôle qualité ou de recherche d’un problème.

Exemple des fichiers proposés par Git. On voit qui l’a modifié, lors de quel commit.

La gestion des branches, base du travail en équipe

Les outils de contrôle de code source permettent de mieux travailler en équipe, notamment via l’historique des changements vu plus haut. Mais la fonctionnalité la plus intéressante reste probablement la possibilité de créer des branches.

La gestion des branches sous Azure DevOps Repos

Pour expliquer rapidement le système de gestion des branches, il faut penser ça comme une copie. Imaginez que vous avez votre répertoire de travail, et que vous désirez travailler dessus, tout en sauvegardant vos modifications, mais sans gêner le reste de l’équipe avec du travail non terminé. Si ça avait été le travail sur un fichier, une solution aurait pu être de créer une copie du fichier « monfichier_JoffreyNurit.docx » par exemple. C’est ce que le système de branche vous propose : prendre un certain commit (une sauvegarde précise, pour rappel), et faire une copie de ce commit « à côté », qu’on pourra fusionner plus tard, quand le travail sera terminé.

Exemple de gestion de branche

Ainsi, chaque membre de l’équipe peut travailler de son côté, sur la fonctionnalité ou le bug qu’il doit traiter. Il peut faire des sauvegardes intermédiaires, mais s’assurer ainsi de ne pas livrer un travail non terminé qui pourrait gêner le projet et/ou l’équipe. Le travail sera fusionné une fois qu’il le considérera comme pleinement terminé.

Sur l’exemple ci-dessus, on peut voir que la branche « Joffrey_menu » possède du travail qui n’est pas encore intégré à la branche principale main

Chaque équipe possède son « branching model » qui peut lui être propre. Cet excellent article sur le MSDN de Microsoft, ainsi qu’une vidéo associée, vous explique les différents pattern possibles!

Les Pull Request, pour améliorer la qualité de code

La gestion des branches permet à l’équipe de travailler sans gêner le travail des collègues, ou même de pouvoir faire ses tests sans provoquer de problèmes majeurs. Mais une fois le travail terminé, il faut fusionner !

Pour cela, on va passer par la fonctionnalité de Pull Request (aussi appelée Merge request sur d’autres outils). Elle permet de créer une demande de fusion entre le travail qui a été effectué et la branche principale. Il est possible de faire une fusion « directe », sans créer une telle demande. Mais comme on va le voir ci-dessous, ce n’est pas une bonne pratique, donc nous ne l’aborderons pas là.

Lorsque vous mettez à jour une branche, Azure DevOps vous propose directement de créer une Pull Request à partir de là
L’écran de Pull Request permet de configurer les informations relatives au travail effectué : de quelle branche on part, vers quelle branche on fusionne, une description pour la compréhension, les tâches associées, etc.

Une fois la Pull Request créée, l’ensemble de l’équipe est en mesure de la voir, et donc de voir quel va être le code qui va être modifié lors de l’intégration de ce travail au reste du projet. Des retours peuvent être effectués pour poser des questions, des suggestions d’améliorations, etc.

Mettre en place ce type de pratique à plusieurs avantages :

  • Amélioration de la maintenabilité : suggestions de commentaires, code plus clair, etc.
  • Limitation des bugs : détection de potentiels problèmes dans les processus, ou de conflits avec d’autres travaux.
  • Formation continue : certaines syntaxes et/ou process peuvent être inconnus d’autres développeurs. Les voir lors des Pull Request peut amener de la formation .
Exemples de retour sur une Pull Request. Il est possible d’ouvrir une communication sur chaque retour via des commentaires. De plus, il est possible de donner son approbation (ou non) après vérification

Sur l’exemple ci-dessous, la Pull Request précédente se voit fusionnée à la branche principale, après traitement et validation des différents retours. Une fois la fusion effectuée, on peut voir sur la branche principale que le travail est bien présent dans les fichiers, mais aussi dans l’historique !

Exemple de fusion avec Azure DevOps Repos

Mais la fusion n’est pas toujours aussi simple, et nous n’avons pas non plus abordé les différentes options qui s’offrent à nous. Voyons tout cela dans les parties ci-dessous.

La gestion des conflits de fusion

Nous avons vu au-dessus un cas simple : le développeur travaille sur sa branche, puis la fusionne, et tout ce passe bien. Mais que ce passe-t-il si deux développeurs travaillent sur un même morceau de code? Un conflit de fusion survient alors!

Ce genre de problématique arrive régulièrement, même si nous faisons tout pour l’éviter. Il suffit que deux personnes touchent au même composant, ou que l’un effectue un hotfix pendant qu’un autre travaille sur une nouvelle fonctionnalité, et un conflit peut survenir.

Les outils de Visual Studio, ou de gestion de Git en général, permettent souvent de gérer au plus simple les conflits en proposant des interfaces de comparaison de code. Ce type de problématique étant plus une manipulation de Git que d’Azure DevOps, je ne rentrerais pas plus en détail sur le sujet dans cet article. Si vous êtes intéressé par un article autour de Git, sa gestion et ses cas particuliers, n’hésitez pas à me le signaler en commentaire.

Exemple de gestion de branche pouvant conduire à un conflit. Deux équipes partent de la même origine et travaillent en parallèle. Si le même fichier / fonction est manipulé, un conflit Git peut survenir.
Ici, j’ai provoqué volontairement un conflit entre la branche fusionnée précédente et cette nouvelle. J’ai modifié le menu du layout, en ajoutant un nouvel élément dans les deux cas.
L’interface de fusion de Visual Studio. Il me reconnait bien les deux éléments du menu ayant été ajoutés dans les deux cas. L’interface du bas est le résultat final de la fusion. Je peux privilégier une branche, l’autre, ou comme dans le cas présent sélectionner les deux.

Les différents types de fusion

Maintenant que l’on a créé notre branche, gérer les conflits, il ne nous reste plus qu’à fusionner ! Très bien, mais quelle fusion choisir?

Les 4 types de fusions proposées

En effet, Azure DevOps Repos vous propose 4 types de fusion entre les branches. Elles utilisent des méthodes Git différentes, et que vous pouvez gérer manuellement si vous le souhaitez. Elles ont leurs avantages et leurs inconvénients, que vous pouvez voir au travers des petites animations d’Azure Devops. Mais nous allons les détailler ci-dessous :

  • Le merge : la fusion classique par excellence. Il est possible de remonter dans l’historique, en sachant ce qui vient de la branche originelle, et les différents commits qui ont été faits sur la branche séparée. Elle permet donc de savoir précisément ce qui a été fait, quand, et sur quelle branche.
  • Le squash : lors de la fusion, l’ensemble de l’historique de la branche est détruit, afin que seul subsiste le commit de fusion. Ainsi, si un développeur a fait 8 commits avant de terminer son travail, seul 1 commit subsistera en historique. Je le trouve particulièrement utile pour la fusion d’une fonctionnalité terminée.
  • Le rebase : avant de fusionner, git effectue un rebase. C’est-à-dire que Git récupère l’historique de la branche originale, et le rejoue, afin que le début de la branche soit dans le même état que si elle venait tout juste d’être créée. Les commits qui sont propres à la branche sont ensuite rejoués par-dessus. Ainsi, l’historique des commits n’est pas perdu (contrairement au squash), et on considère que l’historique de la branche principale est plus important que la branche à fusionner (contrairement au merge classique). Je privilégie ce type de merge lors des montées en versions, notamment pour la récupération des hotfixs.
  • Le semi-linear : c’est un mix entre le rebase, et le merge. On garde l’historique de la branche à fusionner, comme le merge. Mais avant de faire la fusion de cette branche et de son historique, on effectue un rebase.

Et vous, quelles fusions utilisez-vous? Dans quels cas? N’hésitez pas à en parler en commentaire !

Et la sécurité dans tout ça?

La sécurité de la plateforme Azure DevOps Repos

Enfin, l’élément le plus important de la gestion Git sur Azure DevOps. Comment pouvons-nous sécuriser nos branches et notre développement?

Nous y reviendrons sur chaque partie d’Azure DevOps, car il y a beaucoup d’éléments sur ce sujet. Mais commençons avec l’interface Azure DevOps Repos, et notamment la gestion des branches.

Les options de sécurité que l’on peut avoir sur la gestion des branches

Dans la gestion des branches, vous avez notamment 3 options intéressantes pour chacune d’entre elles :

  • Lock : permets de verrouiller une branche. Elle ne peut pas être supprimée ou mise à jour. Utile pour conserver une version précise par exemple.
  • Branch Policies : définis les politiques de mise à jour de la branche. Elle permet de garantir une meilleure sécurité et maintenabilité du projet avec notamment la possibilité de rendre les revues de code obligatoire (pour un certain nombre, par certaines personnes…), en obligeant les Pull Request à être liées à une ou plusieurs tâches de la gestion de projet (pour la traçabilité) ou en déclenchant des processus de vérification automatisés (tests automatisés, logiciel de conformité de code, etc.).
Les différentes politiques de branches que vous pouvez mettre en place
La mise à jour de la branche est bloquée à cause des politiques non respectées
  • Branch security : cet écran vous permet de gérer les droits d’accès des utilisateurs et / ou des groupes, pour une branche particulière. Notamment si certains utilisateurs peuvent accéder au code en lecture mais pas en écriture, ou modifier des éléments de sécurité de cette branche.
Les droits d’accès pour une branche Git

La sécurité dans le code

La sécurité du code source, ça passe par plusieurs choses à vérifier. Une partie du travail va se faire en amont avec Boards et la définition des Abuses Cases, une autre avec Pipeline lors de process CI/CD en mesures de vérifier automatiquement la sécurité du projet.

Néanmoins, une part importante du travail vient aussi dans la partie repository d’Azure DevOps via de l’analyse manuelle. On a parlé en amont de la vérification des Pull Request, et c’est un point important pour garantir la sécurité de votre code, au travers de :

  • Le respect d’une architecture orientée sécurité (security by design)
  • La vérifications qu’aucun élément de sécurité ne soit sauvegardé sur le dépôt (pas de mot de passe, de clé API, etc.). Pensez à utiliser des service tel que Azure Key Vault
  • La vérification des points d’entrées (endpoints) et de la vérification des paramètres

Azure DevOps Repos vous permet ainsi de mieux vous concentrer sur la sécurité, essentielle au DevSecOps.

Conclusion

Azure DevOps Repos vous permettra de gérer votre code source très simplement, notamment par l’utilisation de Git. Même si l’outil semble classique face à la concurrence, certains points de sécurité tels que les politiques de branches ou la gestion fine des droits d’accès sont très appréciables.

Cependant, la grande force de la solution réside notamment dans les liaisons fortes qui peuvent exister entre la partie Repos et les autres fonctionnalités importantes que sont Boards et Pipelines !

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *