Chocoblog

Chocoblog

Billets sur l'informatique, les logiciels libres et retours d'utilisation sont au programme avec la possibilité de publier des billets de copains.

PeerTube - Partie 5 : gérer le code des releases en parallèle

Pour rappel, PeerTube est une application web, s'installe sur un serveur et tourne via NodeJS. Voir le sommaire pour plus d'informations.

Branches git

Pour les besoins du projet nous avons fait le choix d'utiliser une branche git develop pour le travail en cours et d'une branche release/x.x.x pour gérer le code de la dernière release. Lorsqu'il faut corriger un bug important de la dernière release, on commit sur release/x.x.x puis on merge les modifications sur develop. De cette manière develop est toujours en avance sur la branche de release et les deux branches ne divergent pas. Ceci simplifie la gestion des différentes bases de code.

Changer de branche, c'est lourd

PeerTube c'est du TypeScript et donc du JavaScript. Nous utilisons alors beaucoup de modules venant de NPM pour les besoins du serveur et pour compiler le client qui est une application web Angular. À chaque fois qu'il faut changer de branche il faut donc réinstaller tous les modules et potentiellement recompiler le projet ce qui prend du temps.

Ce n'est pas trop gênant lorsqu'on développe des petites fonctionnalités sur une branche dédiée, car la majorité du temps on ne change pas les versions des modules utilisés par PeerTube.

C'est par contre une autre mayonnaise lorsqu'il faut gérer la branche develop et la branche de la dernière release : très souvent les modules ont changé ou ont été mis à jour sur la branche develop, alors qu'ils sont freezé sur la branche de release. Or il nous faut souvent naviguer entre develop et release/x.x.x pour seulement quelques minutes afin de corriger un petit bug. Le processus ressemble à ça :

  • Changer de branche : git checkout release/x.x.x
  • Réinstaller les modules avec rm -r node_modules client/node_modules && yarn install --pure-lockfile
  • Relancer la compilation via npm run build ou npm run dev selon le bug à corriger
  • Corriger le bug
  • Commiter et pusher la branche git commit ... && git push
  • Repasser sur develop, réinstaller les node modules, recompiler (je passe les commandes...)
  • Merger release/x.x.x sur develop et pusher

Bref beaucoup d'étapes, certaines qui peuvent être longues et fastidieuses.

Git à la rescousse

Il serait donc intéressant d'optimiser ce process, en utilisant 2 dossier dédiés qui contiendraient pour l'un la branche develop et pour l'autre la branche de la dernière release, avec leur node_modules/ et leur fichiers compilés.

On peut imaginer cloner 2 fois PeerTube dans des dossiers séparés. La soucis de cette méthode c'est de potentielles incohérences car les deux dossiers seraient complètement indépendants. Il faudrait aussi à chaque fois pusher les modifications pour pouvoir les rapatrier dans l'un ou l'autre dossier.

Pour avoir les avantages des deux dossiers clonés mais sans leur inconvénients, git fournit la commande git worktree. Elle va nous permettre de créer un nouveau dossier/workspace à partir de notre dossier git courant. On aura donc Code/PeerTube qui est notre dossier git principal, et Code/PeerTube-release basé sur le git de Code/PeerTube, mais qui sera sur une branche différente de Code/PeerTube, et qui aura ses propres fichiers non suivis par git (node_modules/, fichiers compilés etc). Voici l'exemple avec PeerTube :

$ cd /Coding/NodeJS/PeerTube
$ git worktree add release/4.2.0 ../PeerTube-release
$ git worktree list --verbose
/Coding/NodeJS/PeerTube              4e56f0fff [develop]
/Coding/NodeJS/PeerTube-release  c3fb12b31 [release/4.2.0]

Le gros avantage de cette méthode, c'est que les deux dossiers partagent le même .git. De ce fait, les commits réalisés dans un des dossiers sera directement visible dans l'autre. On peut donc merger release/x.x.x (de Code/PeerTube-release/) dans develop(Code/PeerTube) sans avoir besoin de pusher sur la remote. Git interdit aussi que les deux dossiers soient sur la même branche, ce qui évite des conflits éventuels.

Ce système permet tellement de simplifier le développement de branches en parallèle qu'on l'utilise aussi lorsqu'on a de grosses fonctionnalités à developper.