Accélérer les builds qui dépendent de nodejs

Quel que soit le procédé utilisé pour compiler ces projets JavaScript ou TypeScript, il y a une étape qui est trop souvent négligée. Il s’agit de l’opération de récupération des modules. Le fameux : npm install.

Même si npm a beaucoup évolué ces dernières années, il est toujours à la traine par rapport aux alternatives que sont yarn et pnpm.

Pourquoi ?

Yarn a la bonne idée de ne télécharger qu’une fois un module, quel que soit le nombre de projets qui l’utilisent. Il télécharge aussi plus rapidement les fichiers.

Pnpm va un peu plus loin. Il a les mêmes avantages que yanr sur npm. Mais, il ne réalise pas de copie des modules. Il crée des liens symboliques vers les dossiers des modules téléchargés (il adapte la technologie à employer en fonction de l’OS : Linux, Mac, Windows). La durée de création de ces liens est bien plus courte qu’une copie. Il a en plus l’avantage de structurer différemment les modules dans le répertoire node_modules. Cela n’a pas d’impact sur la durée de la build, je ne vais donc pas détailler ce point.

Quels intérêts et limites pour un agent de build ?

Même si yarn et pnpm ont prouvé tout leur intérêt sur un PC de développement, leur emploi dans une build automatisée n’est pas toujours aussi efficace.

Ne vous méprenez pas, yarn et pnpm peuvent être utilisés dans une build Azure DevOps, GitHub, Jenkins ou autres sans problèmes. Il y a cependant des cas où ils sont inutiles :

  • Agent autohébergé par GitHub ou Azure DevOps
  • Agent utilisé dans un conteneur instancié à chaque nouvelle build.
  • Agent hébergé derrière un bon proxy.

Dans les deux premiers cas, yarn et pnpm ne peuvent pas profiter des modules téléchargés lors d’une précédente build. Les modules sont donc téléchargés à chaque build. La différence par rapport à npm est donc mimine (à chaque version de npm, cette différence s’amenuise). Il est même possible que ce gain s’annule par le temps perdu à installer yarn ou pnpmn à chaque build (hormis si votre agent contient déjà ces outils). Pour la même raison, la présence du proxy peut donner l’avantage à npm.

Vous l’aurez compris, yarn et pnpm révèlent leur plein potentiel quand ils sont utilisés avec un agent selft-hosted. Ce peut être une VM dans le cloud ou héberger sur son propre réseau. Dans tous les cas, le serveur de build doit permettre à yarn ou pnpm da’voir un cache local. Ce cache pourra profiter à plusieurs projets (à la manière du package référence de nuget).

Concrètement

Exemple : Sur l’un de mes projets, une première installation de module via npm, yarn ou pnpm qui prend entre 5 et 6 minutes :

  • npm consommera toujours 5 à 6 minutes.
  • yarn ne consommera plus que 24 secondes après la première build.
  • pnpm ne consommera plus que 6 secondes après la première build.

L’Hyper-V qui héberge mes agents de builds Azure DevOps utilise des disques mécaniques. L’usage de SSD pour la build pourrait réduire l’écart entre yarn et pnpm. Mais ce n’est pas garanti. Dans mon cas, l’usage de pools, ReFS et de disque VHDX me permet de faire passer de vieux disques pour de véritables petites bombes.

Jérémy Jeanson

Azure Pipeline Agent incapable de détecter ses capacités ?

En temps normal, un agent Azure Pipeline détecte automatiquement ses capacités. Cette détection à chaque lancement de l’agent. Si celui-ci est installé en tant que service, un redémarrage du service suffit pour lancer la recherche des capacités.

Contrairement à ce que j’ai déjà pu entendre, l’installation ou la suppression d’application d’un serveur de build n’entraine donc pas d’opérations manuelles complexes. Le redémarrage du serveur n’est pas requis (hormis si l’outil installé ou désinstaller le recommande).

Le problème

Mais il arrive que l’on se trouve dans une situation frustrante : un agent Windows pour ne détecte aucune capacité. Il ne remonte que quelques informations liées à son environnement (variables d’environnement, dont le PATH, nom de la machine … etc …). Mais aucun outil de build. Pas même les frameworks .net ou MsBuild.

Contrairement à ce que l‘on pourrait penser de prime abord, le problème n’est pas lié à un manque de droits du compte exécutant l’agent. Il s’agit d’un problème lié à PowerShell : l’exécution de scripts non signés est impossible sur le serveur. Malheureusement, les scripts de détections des capacités ne sont pas signés.

La solution

En temps normal, le script .cmd de configuration de l’agent effectue le travail nécessaire pour éviter ce problème. Malheureusement, ce script est limité. Si la stratégie de sécurité PowerShell change après la configuration, ou si elle est diffusée via une GPO, l’agent est incapable de fonctionner.

Pour résoudre le problème, il faut donc jouer avec la commande Set-ExecutionPolicy.

Exemple :

Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope LocalMachine

Si la commande remonte un avertissement indiquant une GPO contraire, il faut modifier la GPO (ou demander à votre gentil administrateur de la faire pour vous).

Jérémy Jeanson

L’erreur à ne pas commettre avec Live Unit Testing

Quand on débute avec Live Unit Testing, on devient vite accros. On est alors tenté de configurer cette fonctionnalité pour qu’elle se lance à l’ouverture d’une solution.

Malheureux, ne faites jamais cela !

À son lancement, Live Unit Testing va procéder à plusieurs opérations, dont une compilation et une découverte de tests unitaires.

Dans une journée de travail classique, il n’est pas rare d’avoir à jongler entre les solutions (ou les branches). Dans un tel contexte, on ne souhaite pas avoir à attendre.

N’activez donc pas l’exécution automatique de Live Unit Testing à l’ouverture d’une solution. Dans le cas contraire, vous allez vite détester cette fonctionnalité de Visual Studio Enterprise.

Jérémy Jeanson

La fonctionnalité de Visual Studio Enterprise dont je ne peux pas me passer

Visual Studio Enterprise regorge de fonctionnalités sympathiques. Il en existe certaines comme celles qui sont dédiées à l’architecture qui ont un peu moins la cote. A contrario, il y a le très célèbre IntelliTrace. Entre les deux, il y a pléthore de fonctionnalités très utiles que l’on n’emploie pourtant que ponctuellement. Tout dépend de notre rôle et de notre charge de travail à l’instant T.

Pour moi, il n’y a pas de fonctionnalité de Visual Studio Enterprise que j’aimerais voir disparaitre. Mais si cela devait arriver, il en est une qui me manquerait énormément et qui me ferait perdre en productivité : Live Unit Testing (traduite en français : "Test unitaire en direct").

Pourquoi j’aime cette fonctionnalité ?

Live Unit Testing m’est indispensable pour les raisons suivantes :

  • Cette fonctionnalité me sert au quotidien.
  • Les tests s’exécutant alors que je code, je peux éviter un bug alors que je n’ai pas fini d’écrire ma méthode.
  • Les pictogrammes affichés en début de ligne me permettent d’avoir un aperçu instantané de ma couverture de code. Étant daltonien, je trouve ceux-ci plus pratiques que la coloration ajoutée par Code Coverage.
  • Dans une journée de développement classique, j’utilise beaucoup plus qu’IntelliTrace.
  • Je ne lance que très rarement les tests manuellement. J’attends donc moins et pourtant les tests s’exécutent plus souvent.

Moralité

Si vous n’avez jamais utilisé Live Unit Testing, je vous encourage à sauter le pas. Vous ne serez pas déçus.

Jérémy Jeanson

Utiliser des scripts PowerShell signés ne vous protège pas

Parmi les fausses idées qui circulent au sujet de PowerShell, il en est une qui est très dangereuse : utiliser uniquement des scripts signés vous protégerait contre tout acte malveillant.

Malheureusement, tout n’est pas aussi simple. La signature d’un script Powershell permet de s’assurer qu’un script provenant d’un tiers de confiance n’a pas été modifié.