Projet Ledger Live Monorepo : Partie 1 - Problématique (Make it Pain) | registre

Projet Ledger Live Monorepo : Partie 1 – Problématique (Make it Pain) | registre

Dans cette série d'articles de blog, Valentin De Almeida, développeur de Ledger Live, nous explique l'évolution de la base de code de Ledger Live au fil des ans. Dans cet article de blog, vous apprendrez qu'il était initialement basé sur plusieurs référentiels, les problèmes que nous avons rencontrés en cours de route et pourquoi il a dû évoluer vers une architecture mono-référentiel. Dans les prochains articles du blog, nous vous expliquerons comment ce grand projet de migration a été mené. 

Un peu d'histoire 

La croissance de Ledger en 2020 et 2021 a été significative. Nous avons recruté de nouveaux talents de manière agressive, élargissant notre équipe d'une poignée à plus de 20 développeurs. Cela signifie que de nombreux nouveaux ingénieurs ont été intégrés à des projets existants. Au fur et à mesure que notre équipe s’agrandissait, nous avons été confrontés à de nouveaux défis que nous avons dû relever rapidement. Malgré ces nouvelles difficultés, nous sommes restés concentrés sur notre objectif et avons continué à livrer un travail exceptionnel.

Nous avons pris du recul et nous sommes penchés sur les nouvelles problématiques qui surviennent lorsque de plus en plus de personnes s'engagent dans le projet. Parmi ces nouveaux défis, on peut citer les besoins suivants :

  • Des flux plus simples.
  • De meilleures directives pour les contributeurs entrants et externes.
  • Un ensemble d’outils unifié.
  • Meilleure gestion des dépendances.
  • Contributions open source centralisées.
État de l’art : avant la migration
Projet Ledger Live Monorepo : Partie 1 - Problématique (Make it Pain) | Ledger PlatoBlockchain Data Intelligence. Recherche verticale. Aï.
Projet Ledger Live Monorepo : Partie 1 - Problématique (Make it Pain) | registre

Initialement, et jusqu'à l'année dernière, Ledger Live était basé sur une architecture poly-dépôt, pour les front-ends mobiles et de bureau, ainsi que toute la logique qui la sous-tend. Ce n’était pas une décision consciente de travailler de cette manière, mais ce n’était que le résultat d’un projet en expansion sans véritable avance architecturale. Ledger Live est un projet qui rassemble divers composants en un seul pour fournir l'application la meilleure et la plus sécurisée à nos utilisateurs Nano, et cela se reflète dans la base de code.

Les flux que nous avions en place étaient au mieux instables, principalement à cause du fait que nous étions 6 ou 7 développeurs il y a quelques années. Comme il y avait moins de parties impliquées, la communication était beaucoup plus facile et nous nous en sommes sortis. Néanmoins, il y avait quelques problèmes dans la façon dont nous travaillions, notamment en ce qui concerne l'expérience des développeurs et le processus de publication.

Goulots d'étranglement de l'expérience de développement

Dépendances

En raison de la nature de nos projets, nous travaillons sur plusieurs référentiels en même temps, avec des dépendances entre eux. Voici un aperçu rapide :

Projet Ledger Live Monorepo : Partie 1 - Problématique (Make it Pain) | Ledger PlatoBlockchain Data Intelligence. Recherche verticale. Aï.
Projet Ledger Live Monorepo : Partie 1 - Problématique (Make it Pain) | registre

Les bibliothèques open source Ledger sont utilisées par la logique métier, qui est ensuite utilisée à la fois par les applications de bureau et mobiles. Mais ces applications utilisent également les bibliothèques open source et utilisent deux versions différentes de la même bibliothèque (comme @ledgerhq/errors par exemple) casserait l'application.

Nous devions déplacer la version d'un côté, puis publier les bibliothèques (oui, sur npm !!!), puis réessayer si cela ne fonctionnait pas. Nous avons commencé à compter sur yalc pour créer des liens symboliques vers des projets, ce qui était généralement acceptable tant que nous n'avions pas plusieurs couches de dépendances (par exemple, des bibliothèques open source à la logique métier, puis de la logique métier aux applications). Nous avons provisoirement essayé de travailler avec yarn link aussi, mais il semble que cela soit voué à l'échec avec React Native.

Essais

Il était quasiment impossible de faire des tests d'intégration avec tout le dernier code des différents projets. Puisque nous devions publier les bibliothèques dans le registre, tester tous les composants avec le code le plus récent était un cauchemar.

Nous avons également dû maintenir plusieurs CI avec une logique dupliquée.

Changement de contexte

Se déplacer constamment dans plusieurs éditeurs de code/projets/répertoires rendait l'expérience de développement vraiment faible.

Goulots d'étranglement du processus de publication

Versioning

Gérer le versioning de différents projets est difficile, surtout lorsqu'il existe plusieurs couches de dépendances.

Libération

Le suivi des releases était compliqué du fait que les projets étaient fractionnés, et il fallait gérer les releases des différents projets

Il était impossible d'automatiser le processus de publication, encore une fois en raison du fait que les projets étaient répartis dans différents référentiels.

Et bien sûr, la livraison continue était impensable à ce stade.

Solution possible ?
Projet Ledger Live Monorepo : Partie 1 - Problématique (Make it Pain) | Ledger PlatoBlockchain Data Intelligence. Recherche verticale. Aï.
Projet Ledger Live Monorepo : Partie 1 - Problématique (Make it Pain) | registre

En cherchant l'inspiration, il semble qu'une architecture mono-référentiel soit la pièce centrale qui nous manquait. Cela permettrait un bien meilleur processus de développement. Il existe des outils construits autour de cette architecture qui nous aideraient à réaliser les parties manquantes (release, automatisation, versioning…).

Mais qu’est-ce qu’un dépôt mono ?

À la base, un référentiel mono est un projet qui encapsule tous les autres projets associés (applications, bibliothèques, outils) dans un seul dossier/projet git. Il permet une meilleure gestion des dépendances, une uniformisation des outils (comme les styles de code et les configurations dactylographiées), une intégration continue centralisée, des tests d'intégration, une version uniforme des packages utilisés (react par exemple)…

Puisqu'il s'agit d'un système assez agnostique, certaines fonctionnalités nous ont été laissées à découvrir et à implémenter. Espérons qu'il existe d'excellents outils communautaires qui pourraient nous aider à ajouter une orchestration aux builds (builds séquentiels, utiles pour CI), la gestion des versions, la génération du journal des modifications... ce qui compléterait ce qui nous manquait dans notre processus de publication.

Inconvénients

Les dépôts mono ont du sens dans un contexte où plusieurs développeurs, ou une équipe de développeurs travaillent sur plusieurs projets en même temps, avec des dépendances entre eux. Cependant, cela ajoute une certaine complexité lors de la phase de configuration (en particulier avec des projets déjà opérationnels qui ont 4 ans d'historique et de développement actif). Il convient de mentionner que le projet devient beaucoup plus gros (beaucoup plus gros) en termes d'espace disque. Tous les projets sont désormais dans le même dossier et toutes les dépendances. Quels tests sont obligatoires ? Quand les déclencher ?

Avantages

Après avoir évalué le délai, le coût et la faisabilité de nos ambitions, voici quelques-uns des bénéfices attendus de cette transition :

  • Gestion améliorée des dépendances : Avec un monorepo, il est plus facile de gérer les dépendances entre différents projets, car ils sont tous stockés dans le même référentiel. Cela peut réduire le besoin de solutions de contournement comme le lien de fil ou yalc, et il est plus facile de garantir que tous les projets utilisent les versions correctes des dépendances.
  • Meilleure organisation du code : un monorepo peut faciliter l'organisation du code, car tous les projets et leurs dépendances sont stockés dans un seul référentiel. Il est plus facile de comprendre comment les différents projets s'articulent et comment ils dépendent les uns des autres.
  • Expérience de développement améliorée : un monorepo peut permettre aux développeurs de travailler plus facilement sur plusieurs projets, car ils n'ont pas besoin de basculer entre différentes bases de code ou référentiels. Cela peut également faciliter l’exécution des tests d’intégration, car tout le code est stocké dans le même référentiel.
  • Automatisation améliorée et livraison continue : avec un monorepo, il est plus facile d'automatiser des tâches telles que la création, les tests et la publication de code. Cela peut contribuer à rationaliser le processus de publication et à faciliter la mise en œuvre de la livraison continue.
  • Vitesse de développement accrue. Étant donné que différentes équipes travaillent dans le même référentiel, elles n'ont pas besoin d'attendre la sortie pour vérifier le résultat, accélérant ainsi l'intégration.
Conclusion

Dans l’ensemble, la mise en œuvre d’une structure monorepo peut contribuer à améliorer le processus de développement, à rationaliser le processus de publication et à améliorer l’expérience du développeur.

Dans les prochains articles de blog de cette série, nous vous expliquerons comment ce projet de migration majeur a été mené, les outils que nous avons utilisés, les choix que nous avons faits, le résultat et bien plus encore. Restez à l'écoute pour la partie 2 : Les outils !


Valentin DE ALMEIDA
Expérience de développeur et technologie de base – Ledger Live

Horodatage:

Plus de Ledger