Gestion des mises à jour de dépendances dans un projet .NET

Effectué

Tôt ou tard, vous souhaiterez mettre à jour une bibliothèque vers une nouvelle version. Peut-être qu’une fonction est marquée comme dépréciée ou peut-être qu’il existe une nouvelle fonctionnalité dans une version ultérieure d’un package que vous utilisez.

Tenez compte de ces considérations avant d’essayer de mettre à jour une bibliothèque :

  • Type de mise à jour : quel type de mise à jour est disponible ? S’agit-il du correctif d’un petit bogue ? La mise à jour ajoute-t-elle une nouvelle fonctionnalité dont vous avez besoin ? Cela empêchera-t-il votre code de fonctionner correctement ? Vous pouvez communiquer le type de mise à jour en utilisant un système appelé gestion sémantique de versions. La façon dont le numéro de version de la bibliothèque est exprimé indique aux développeurs le type de mise à jour auquel ils ont affaire.
  • Si le projet est configuré correctement : vous pouvez configurer votre projet .NET de manière à obtenir seulement les types de mises à jour souhaités. Vous effectuez une mise à jour seulement si un type de mise à jour spécifique est disponible. Nous recommandons cette approche, car elle vous évite les surprises.
  • Problèmes de sécurité : la gestion des dépendances de votre projet au fil du temps implique la prise en compte des problèmes qui peuvent se produire. Par exemple, des problèmes peuvent survenir quand des vulnérabilités sont détectées. Dans l’idéal, des correctifs sont publiés et vous pouvez les télécharger. L’outil .NET Core vous permet d’exécuter un audit sur vos bibliothèques pour déterminer si vous avez des packages à mettre à jour. Il vous aide également à prendre les mesures appropriées pour résoudre un problème.

Utiliser la gestion sémantique de versions

Il existe une norme industrielle appelée Gestion sémantique de version, qui permet d'exprimer le type de changement que vous ou un autre développeur apportez à une bibliothèque. Elle demande qu’un package comporte un numéro de version présentant les sections suivantes :

  • Version principale : numéro le plus à gauche. Par exemple, il s’agit du 1 dans 1.0.0. Une modification de ce nombre signifie que vous pouvez vous attendre à des « changements cassants » dans votre code. Vous devrez peut-être réécrire une partie de votre code.
  • Version mineure : numéro intermédiaire. Par exemple, il s’agit du 2 dans 1.2.0. Une modification de ce nombre signifie que des fonctionnalités ont été ajoutées. Votre code devrait continuer de fonctionner correctement. L’acceptation de la mise à jour ne présente généralement aucun danger.
  • Version du correctif : numéro le plus à droite. Par exemple, il s’agit du 3 dans 1.2.3. Une modification de ce nombre signifie qu’un correctif a été appliqué pour corriger quelque chose dans le code qui devrait fonctionner. Il est normalement sans danger d’accepter la mise à jour.

Ce tableau montre comment le numéro de version change pour chaque type de version :

Type Changement
Version majeure 1.0.0 passe à 2.0.0
Version secondaire 1.1.1 passe à 1.2.0
Version corrective 1.0.1 passe à 1.0.2

De nombreux développeurs et entreprises utilisent ce système. Si vous prévoyez de publier des packages et de les envoyer (push) au registre NuGet, vous devez suivre la gestion sémantique de version. Même si vous téléchargez seulement des packages à partir du registre NuGet, vous pouvez vous attendre à ce qu’ils suivent la gestion sémantique de versions.

Les modifications apportées à un package peuvent introduire un risque, notamment celui d’un bogue pouvant nuire à votre entreprise. Certains risques peuvent demander de réécrire une partie de votre code. La réécriture du code prend du temps et coûte de l’argent.

Approche de la mise à jour

En tant que développeur .NET, vous pouvez indiquer à .NET le comportement de mise à jour que vous voulez. Vous devez penser aux mises à jour en termes de risque. Voici quelques approches :

  • Version principale : j’accepte d’effectuer une mise à jour vers la dernière version majeure dès qu’elle est publiée. J’accepte le fait que je devrai peut-être modifier le code de mon côté.
  • Version mineure : j’accepte l’ajout d’une nouvelle fonctionnalité. Je n’accepte pas que mon code ne puisse plus fonctionner correctement.
  • Version corrective : les seules mises à jour que j’accepte sont des correctifs de bogues.

Si vous gérez un projet .NET nouveau ou plus petit, vous pouvez vous permettre d’être relativement souple quant à la façon dont vous définissez la stratégie de mise à jour. Par exemple, vous pouvez toujours mettre à jour vers la version la plus récente. Pour les projets plus complexes, les choses sont plus nuancées, mais nous aborderons cet aspect dans un autre module.

En général, plus la dépendance que vous mettez à jour est petite, moins elle a de dépendances et plus il est probable que le processus de mise à jour soit facile.

Configurer le fichier projet pour la mise à jour

Quand vous ajoutez une ou plusieurs dépendances, configurez votre fichier projet de manière à obtenir un comportement prévisible lors de la restauration, de la génération ou de l’exécution de votre projet. Vous pouvez communiquer l’approche que vous souhaitez appliquer pour un package. NuGet propose les concepts de plages de versions et de versions flottantes.

Les plages de versions sont une notation spéciale que vous pouvez utiliser pour indiquer une plage spécifique de versions que vous souhaitez résoudre.

Notation Règle appliquée Description
1.0 x >= 1,0 Version minimale, inclusive
(1.0,) x > 1,0 Version minimale, exclusive
[1.0] x == 1.0 Correspondance exacte des versions
(,1.0] x ≤ 1.0 Version maximale, inclusive
(,1.0) x < 1,0 Version maximale, exclusive
[1.0,2.0] 1.0 ≤ x ≤ 2.0 Plage exacte, inclusive
(1.0,2.0) 1,0 < x < 2,0 Plage exacte, exclusive
[1.0,2.0) 1,0 ≤ x < 2,0 Version maximum exclusive et minimum inclusive mixte
(1.0) non valide non valide

NuGet prend également en charge l’utilisation d’une notation de version flottante, pour les parties de suffixe associées au numéro de version principale, de version mineure, de version de correctif et de préversion. Cette notation est un astérisque (*). Par exemple, la spécification de version 6.0.* indique « Utiliser la version 6.0.x la plus récente ». Dans un autre exemple, 4.* signifie « Utiliser la version 4.x la plus récente ». L’utilisation d’une version flottante réduit les modifications apportées au fichier projet, tout en gardant à jour la dernière version d’une dépendance.

Notes

Nous vous recommandons d’installer une version spécifique plutôt que d’utiliser les notations flottantes. L’installation d’une version spécifique garantit que vos builds sont renouvelables, sauf si vous demandez explicitement une mise à jour vers une dépendance.

Quand vous utilisez une version flottante, NuGet résout la version la plus récente d’un package qui correspond au modèle de version. Dans l’exemple suivant, 6.0.* obtient la dernière version d’un package qui commence par 6.0. Cette version est 6.0.1.

Capture d’écran du choix de la version la plus récente quand une version flottante est demandée.

Voici quelques exemples que vous pouvez configurer pour la version principale, mineure ou corrective :

<!-- Accepts any version 6.1 and later. -->
<PackageReference Include="ExamplePackage" Version="6.1" />

<!-- Accepts any 6.x.y version. -->
<PackageReference Include="ExamplePackage" Version="6.*" />
<PackageReference Include="ExamplePackage" Version="[6,7)" />

<!-- Accepts any later version, but not including 4.1.3. Could be
     used to guarantee a dependency with a specific bug fix. -->
<PackageReference Include="ExamplePackage" Version="(4.1.3,)" />

<!-- Accepts any version earlier than 5.x, which might be used to prevent pulling in a later
     version of a dependency that changed its interface. However, we don't recommend this form because determining the earliest version can be difficult. -->
<PackageReference Include="ExamplePackage" Version="(,5.0)" />

<!-- Accepts any 1.x or 2.x version, but not 0.x or 3.x and later. -->
<PackageReference Include="ExamplePackage" Version="[1,3)" />

<!-- Accepts 1.3.2 up to 1.4.x, but not 1.5 and later. -->
<PackageReference Include="ExamplePackage" Version="[1.3.2,1.5)" />

Rechercher et mettre à jour des packages obsolètes

La commande dotnet list package --outdated liste les packages obsolètes. Cette commande peut vous aider à savoir quand des versions plus récentes des packages sont disponibles. Voici une sortie standard de la commande :

Top-level Package      Requested   Resolved   Latest
> Humanizer            2.7.*       2.7.9      2.8.26

Voici la signification des noms des colonnes dans la sortie :

  • Requested : version ou plage de versions que vous avez spécifiée.
  • Resolved : version réelle téléchargée pour le projet qui correspond à la version spécifiée.
  • Latest : la dernière version disponible pour la mise à jour à partir de NuGet.

Le workflow recommandé est d’exécuter les commandes suivantes, dans cet ordre :

  1. Exécuter dotnet list package --outdated. Cette commande liste les packages obsolètes. Elle fournit des informations dans les colonnes Requested, Resolved et Latest.
  2. Exécutez dotnet add package <package name>. Si vous exécutez cette commande, une tentative de mise à jour vers la dernière version est effectuée. Si vous le souhaitez, vous pouvez passer --version=<version number/range>.