Partager via


Plug-ins multiplateformes NuGet

La prise en charge des plug-ins multiplateformes a été ajoutée dans NuGet 4.8 et versions ultérieures. Cela a été réalisé avec la création d’un nouveau modèle d’extensibilité de plug-in, qui doit se conformer à un ensemble strict de règles d’opération. Les plug-ins sont des exécutables autonomes (exécutables dans le monde .NET Core), que les clients NuGet lancent dans un processus distinct. Il s’agit d’un plug-in qui, une fois écrit, fonctionne partout. Il fonctionne avec tous les outils clients NuGet. Les plug-ins peuvent être écrits dans n’importe quel langage de programmation, mais l’expérience de développement et d’installation du plug-in le plus simple sera avec .NET. Un protocole de communication avec version entre le client NuGet et le plug-in est défini. Lors de la poignée de main au démarrage, les 2 processus négocient la version du protocole.

Comment fonctionne-t-il ?

Le flux de travail de haut niveau peut être décrit comme suit :

  1. NuGet découvre les plug-ins disponibles.
  2. Le cas échéant, NuGet effectue une itération sur les plug-ins dans l’ordre de priorité et les démarre un par un.
  3. NuGet utilise le premier plug-in qui peut traiter la requête.
  4. Les plug-ins seront arrêtés lorsqu’ils ne sont plus nécessaires.

Exigences générales du plug-in

La version actuelle du protocole est 2.0.0. Dans cette version, les exigences sont les suivantes :

  • Soutenir le lancement sans état dans le contexte de sécurité actuel des outils client de NuGet. Par exemple, les outils clients NuGet n’effectuent pas d’élévation ou d’initialisation supplémentaire en dehors du protocole de plug-in décrit ultérieurement.
  • Ne pas être interactif, sauf indication explicite.
  • Respectez la version négociée du protocole de plug-in.
  • Répondez à toutes les demandes dans un délai raisonnable.
  • Honorez les demandes d’annulation pour toute opération en cours.

Les plug-ins découverts à partir de la variable d’environnement PATH (par exemple, installés via dotnet tool) doivent également correspondre au modèle nuget-plugin-*de nom de fichier. La nuget-plugin- partie doit être entièrement écrite en minuscules.

NuGet 6.12 (MSBuild 17.12 et .NET SDK 9.0.100) et les versions précédentes exigeaient également que les plug-ins soient signés avec Authenticode sur Windows.

La spécification technique est décrite plus en détail dans les spécifications suivantes :

Client - Interaction du plug-in

Les outils clients NuGet et les plug-ins communiquent avec JSON sur des flux standard (stdin, stdout, stderr). Toutes les données doivent être encodées en UTF-8. Les plug-ins sont lancés avec l’argument « -Plugin ». Si un utilisateur lance directement un exécutable de plug-in sans cet argument, le plug-in peut donner un message informatif au lieu d’attendre une négociation de protocole. Le délai d’expiration du handshake protocolaire est de 5 secondes. Le plug-in doit terminer la configuration aussi vite que possible. Les outils clients NuGet interrogent les opérations prises en charge par un plug-in en passant l’index de service pour une source NuGet. Un plug-in peut utiliser l’index de service pour vérifier la présence des types de service pris en charge.

La communication entre les outils clients NuGet et le plug-in est bidirectionnelle. Chaque requête a un délai d’expiration de 5 secondes. Si les opérations sont censées prendre plus de temps, le processus respectif doit envoyer un message de progression pour empêcher la demande d’expirer. Après 1 minute d’inactivité, un plug-in est considéré comme inactif et est arrêté.

Installation et découverte du plug-in

NuGet recherche des plug-ins à partir d’une structure de répertoires basée sur une convention et analyse la variable d’environnement PATH.

Découverte par convention

Les scénarios CI/CD et les utilisateurs avancés peuvent utiliser des variables d’environnement pour modifier le comportement. Lorsque vous utilisez des variables d’environnement, seuls les chemins absolus sont autorisés. Notez que NUGET_NETFX_PLUGIN_PATHS et NUGET_NETCORE_PLUGIN_PATHS sont disponibles uniquement avec la version 5.3+ des outils NuGet et versions ultérieures.

  • NUGET_NETFX_PLUGIN_PATHS : définit les plug-ins qui seront utilisés par les outils .NET Framework (NuGet.exe/MSBuild.exe/Visual Studio). Est prioritaire sur NUGET_PLUGIN_PATHS. (NuGet version 5.3+ uniquement)
  • NUGET_NETCORE_PLUGIN_PATHS : définit les plug-ins qui seront utilisés par les outils .NET Core (dotnet.exe). Est prioritaire sur NUGET_PLUGIN_PATHS. (NuGet version 5.3+ uniquement)
  • NUGET_PLUGIN_PATHS - définit les plug-ins qui seront utilisés pour ce processus NuGet, priorité conservée. Si cette variable d’environnement est définie, elle remplace la découverte basée sur la convention. Ignoré si l’une des variables spécifiques à l’infrastructure est spécifiée.
  • Emplacement utilisateur, emplacement principal de NuGet dans %UserProfile%/.nuget/plugins. Cet emplacement ne peut pas être remplacé. Un autre répertoire racine sera utilisé pour les plug-ins .NET Core et .NET Framework.
Cadre Emplacement de découverte de la racine Utilisé par
.NET Core %UserProfile%/.nuget/plugins/netcore CLI dotnet
Cadre .NET %UserProfile%/.nuget/plugins/netfx MSBuild, NuGet.exe, Visual Studio

Chaque plug-in doit être installé dans son propre dossier. Le point d’entrée du plug-in sera le nom du dossier installé, avec les extensions .dll pour .NET Core et .exe extension pour .NET Framework.

.nuget
    plugins
        netfx
            myPlugin
                myPlugin.exe
                nuget.protocol.dll
                ...
        netcore
            myPlugin
                myPlugin.dll
                nuget.protocol.dll
                ...

Découverte PATH

À partir de NuGet 6.13, NuGet recherche chaque répertoire fourni dans la variable d’environnement PATH pour les fichiers correspondant au modèle nuget-plugin-*. Le modèle correspondant respecte la casse et nuget-plugin- doit être écrit entièrement en minuscules. Sur Windows, le fichier doit avoir une extension .exe ou .bat. Sur Linux et Mac, le fichier doit avoir le bit exécutable défini.

Cela permet aux plug-ins NuGet d’être installés via dotnet tool des commandes, WinGet, le gestionnaire de package d’une distribution Linux ou toute autre méthode qui peut placer des exécutables sur le chemin d’accès de l’utilisateur. Cela permet également aux plug-ins NuGet d’être écrits dans n’importe quel langage de programmation (précédemment les plug-ins pour Linux et Mac doivent être écrits dans .NET).

Nous vous recommandons de développer des plug-ins dans .NET, afin que vous puissiez utiliser le package NuGet.Protocol pour éviter d’avoir à écrire le code RPC json et permettre aux clients de découvrir votre plug-in via dotnet package search nuget-plugin.

Opérations prises en charge

Deux opérations sont prises en charge sous le nouveau protocole de plug-in.

Nom de l’opération Version minimale du protocole Version minimale du client NuGet
Télécharger le package 1.0.0 4.3.0
d’authentification 2.0.0 4.8.0

Exécution de plug-ins sous le runtime correct

Pour les scénarios NuGet dans dotnet.exe scénarios, les plug-ins doivent être en mesure d’exécuter sous ce runtime spécifique du dotnet.exe. Il incombe au fournisseur du plug-in et au consommateur de s'assurer qu'une combinaison compatible de dotnet.exe/plug-in est utilisée. Un problème potentiel peut survenir avec les plug-ins d’emplacement utilisateur quand, par exemple, une dotnet.exe sous le runtime 2.0 tente d’utiliser un plug-in écrit pour le runtime 2.1.

Mise en cache des fonctionnalités

La vérification de la sécurité et l’instanciation des plug-ins sont coûteuses. L’opération de téléchargement se produit plus fréquemment que l’opération d’authentification, mais l’utilisateur NuGet moyen est susceptible d’avoir un plug-in d’authentification. Pour améliorer l’expérience, NuGet met en cache les revendications d’opération pour la demande donnée. Ce cache est par plug-in avec la clé de plug-in étant le chemin du plug-in, et l’expiration de ce cache de fonctionnalités est de 30 jours.

Le cache se trouve dans %LocalAppData%/NuGet/plugins-cache et doit être substitué par la variable d’environnement NUGET_PLUGINS_CACHE_PATH. Pour effacer cette de cache, vous pouvez exécuter la commande locale avec l’option plugins-cache. L’option all locals supprime désormais également le cache des plug-ins.

Index des messages de protocole

Version de protocole 1.0.0 messages:

  1. Fermer

    • Demande de direction : NuGet - plugin>
    • La requête ne contiendra aucune charge utile
    • Aucune réponse n’est attendue. La réponse appropriée est que le processus de plug-in se ferme rapidement.
  2. Copier des fichiers dans le package

    • Demande de direction : NuGet - plugin>
    • La demande contient les éléments suivants :
      • l’ID de package et la version
      • emplacement du référentiel source du package
      • chemin d’accès au répertoire de destination
      • une liste de fichiers contenus dans le package à copier dans le chemin du répertoire de destination
    • Une réponse contient :
      • code de réponse indiquant le résultat de l’opération
      • Un énumérable de chemins complets pour les fichiers copiés dans le répertoire de destination si l’opération s'est bien déroulée.
  3. Copier le fichier de package (.nupkg)

    • Demande de direction : NuGet - plugin>
    • La demande contient les éléments suivants :
      • l’ID de package et la version
      • emplacement du référentiel source du package
      • chemin du fichier de destination
    • Une réponse contient :
      • code de réponse indiquant le résultat de l’opération
  4. Obtenir les informations d’identification

    • Demander la direction : plug-in -> NuGet
    • La demande contient les éléments suivants :
      • emplacement du référentiel source du package
      • le code d’état HTTP obtenu à partir du référentiel source du package à l’aide des informations d’identification actuelles
    • Une réponse contient :
      • code de réponse indiquant le résultat de l’opération
      • un nom d’utilisateur, le cas échéant
      • un mot de passe, le cas échéant
  5. Obtenir des fichiers dans le paquet

    • Demande de direction : NuGet - plugin>
    • La demande contient les éléments suivants :
      • l’ID de package et la version
      • emplacement du référentiel source du package
    • Une réponse contient :
      • code de réponse indiquant le résultat de l’opération
      • une liste des chemins de fichiers dans le package si l'opération a réussi
  6. Obtenir les demandes d’opération

    • Demande de direction : NuGet - plugin>
    • La demande contient les éléments suivants :
      • le service index.json pour une source de paquet
      • emplacement du référentiel source du package
    • Une réponse contient :
      • code de réponse indiquant le résultat de l’opération
      • une énumération des opérations prises en charge (par exemple, téléchargement de paquets) si l'opération est réussie. Si un plug-in ne prend pas en charge la source du package, le plug-in doit retourner un ensemble vide d’opérations prises en charge.

Remarque

Ce message a été mis à jour dans la version 2.0.0. Il incombe au client de préserver la compatibilité rétroactive.

  1. Obtenir le hachage de paquet

    • Demande de direction : NuGet - plugin>
    • La demande contient les éléments suivants :
      • l’ID de package et la version
      • emplacement du référentiel source du package
      • algorithme de hachage
    • Une réponse contient :
      • code de réponse indiquant le résultat de l’opération
      • un hachage de fichier de package en utilisant l’algorithme de hachage demandé si l’opération a réussi
  2. Obtenir les versions du package

    • Demande de direction : NuGet - plugin>
    • La demande contient les éléments suivants :
      • l'ID de paquet
      • emplacement du référentiel source du package
    • Une réponse contient :
      • code de réponse indiquant le résultat de l’opération
      • un énumérable des versions de paquet si l’opération a réussi
  3. Obtenir l’index de service

    • Demander la direction : plug-in -> NuGet
    • La demande contient les éléments suivants :
      • emplacement du référentiel source du package
    • Une réponse contient :
      • code de réponse indiquant le résultat de l’opération
      • l’index de service si l’opération a réussi
  4. Poignée de main

    • Demande d'orientation : plug-in NuGet <->
    • La demande contient les éléments suivants :
      • version actuelle du protocole de plug-in
      • version minimale prise en charge du protocole de plug-in
    • Une réponse contient :
      • code de réponse indiquant le résultat de l’opération
      • version de protocole négociée si l’opération a réussi. Une défaillance entraîne l’arrêt du plug-in.
  5. Initialiser

    • Demande de direction : NuGet - plugin>
    • La demande contient les éléments suivants :
      • version de l’outil client NuGet
      • langue de fonctionnement de l’outil client NuGet. Cela prend en compte le paramètre ForceEnglishOutput, s’il est utilisé.
      • délai d'expiration par défaut de la demande, qui remplace le délai par défaut du protocole.
    • Une réponse contient :
      • code de réponse indiquant le résultat de l’opération. Une défaillance entraîne l’arrêt du plug-in.
  6. Rapport

    • Demander la direction : plug-in -> NuGet
    • La demande contient les éléments suivants :
      • le niveau de journalisation pour la demande
      • un message à consigner
    • Une réponse contient :
      • code de réponse indiquant le résultat de l’opération.
  7. Surveiller la sortie du processus NuGet

    • Demande de direction : NuGet - plugin>
    • La demande contient les éléments suivants :
      • l’ID de processus NuGet
    • Une réponse contient :
      • code de réponse indiquant le résultat de l’opération.
  8. Package de préchargement

    • Demande de direction : NuGet - plugin>
    • La demande contient les éléments suivants :
      • l’ID de package et la version
      • emplacement du référentiel source du package
    • Une réponse contient :
      • code de réponse indiquant le résultat de l’opération
  9. Définir les informations d’identification

    • Demande de direction : NuGet - plugin>
    • La demande contient les éléments suivants :
      • emplacement du référentiel source du package
      • le dernier nom d’utilisateur source du package connu, le cas échéant
      • le dernier mot de passe source du package connu, le cas échéant
      • le dernier nom d’utilisateur proxy connu, le cas échéant
      • le dernier mot de passe proxy connu, le cas échéant
    • Une réponse contient :
      • code de réponse indiquant le résultat de l’opération
  10. Définir le niveau de journal

    • Demande de direction : NuGet - plugin>
    • La demande contient les éléments suivants :
      • niveau de journal par défaut
    • Une réponse contient :
      • code de réponse indiquant le résultat de l’opération

Version du protocole 2.0.0 messages

  1. Obtenir les réclamations d’opération
  • Demande de direction : NuGet - plugin>

    • La demande contient les éléments suivants :
      • le service index.json pour une source de paquet
      • emplacement du référentiel source du package
    • Une réponse contient :
      • code de réponse indiquant le résultat de l’opération
      • un ensemble des opérations prises en charge si l’opération a réussi. Si un plug-in ne prend pas en charge la source du package, le plug-in doit retourner un ensemble vide d’opérations prises en charge.

    Si l’index de service et la source du package sont null, le plug-in peut répondre avec l’authentification.

  1. Obtenir les informations d’identification
  • Demande de direction : NuGet - plugin>
  • La demande contient les éléments suivants :
    • URI
    • estReessayer
    • NonInteractif
    • CanShowDialog
  • Une réponse contiendra
    • Nom d’utilisateur
    • Mot de passe
    • Message
    • Liste des types d’authentification
    • CodeDeRéponseDuMessage