Guía de implementación del servidor de NuGet

En algunos casos, puede que quieras implementar tu propio feed de paquetes NuGet. Hay muchas implementaciones existentes que te permiten alojar tu propio feed de una manera variada, pero el protocolo entre el software cliente de NuGet oficial y un feed de paquetes se encuentra documentado, lo que te permite generar tu propia implementación de feed desde cero.

El protocolo evoluciona con el tiempo y esta guía está dirigida a aquellos que desean o ya han implementado un servidor de paquetes NuGet.

Desde la versión inicial del protocolo NuGet V3 en 2015, NuGet ha evolucionado para proporcionar a los desarrolladores una experiencia más completa, y esto requiere que los repositorios de paquetes realicen un trabajo adicional con el fin de proporcionar valor adicional a sus consumidores de paquetes, más allá de simplemente extraer los metadatos de los paquetes hospedados y devolverlos en distintos formularios. Por ejemplo, los puntos de conexión de metadatos de búsqueda y paquete contienen más que los metadatos que se incluyen en el archivo nuspec de nupkg.

Nota: Esta guía se centra en el protocolo NuGet V3, ya que el protocolo V2 no está documentado y, desde 2015, el protocolo recomendado para la comunicación entre cliente y servidor de NuGet es el protocolo V3. Para obtener más información, consulta los detalles sobre el control de versiones del protocolo.

Cronología

Para ayudar a los autores de repositorios de NuGet existentes a mantenerse al día de las características más recientes de NuGet, ofrecemos la cronología de las características relevantes que se mencionan en el resto del documento.

Year Característica
2013 Una entrada de blog que explica cómo administrar los propietarios de paquetes en nuget.org aclaraba que los propietarios que se muestran en el sitio web son las cuentas que tienen permiso para cargar nuevas versiones y, por tanto, se ignoran los metadatos owners del paquete
2017 Se ha agregado verified a las respuestas SearchQueryService.
Compatibilidad con Versionamiento Semántico 2.0.0
2018 Licencias incrustadas
2019 Iconos incrustados
Desuso de paquetes en RegistrationBaseUrl (recurso de metadatos del paquete)
2020 Información de vulnerabilidad del paquete en RegistrationsBaseUrl (recurso de metadatos del paquete)
Se ha agregado el parámetro de consulta packageTypes a las solicitudes SearchQueryService
2021 Léame incrustado
2023 Solicitudes autenticadas con autenticación previa
Recurso VulnerabilityInfo

Campo “Propietario”

Tomemos dos de los campos de archivo de manifiesto de paquete (.nuspec), <authors> y <owners>. Los autores de paquetes que empaquetan contenido de terceros suelen colocar el nombre de terceros en el campo <authors>. El campo <owners> estaba pensado para indicar quién publicó el paquete en un repositorio y, por lo tanto, con quién debemos ponernos en contacto en caso de dudas o de problemas de empaquetado.

Esto se explicó en una entrada de blog de 2013, por lo que el campo <owners> se considera en desuso en el archivo .nuspec. Si el manifiesto del paquete contiene estos metadatos, se debe ignorar. No es posible devolver el valor del campo <owners> del archivo .nuspec que se encuentra en la propiedad owners del recurso de búsqueda o en la respuesta JSON del recurso de metadatos del paquete.

Si el repositorio tiene permisos por paquete, se recomienda informar sobre las cuentas que tienen permisos para publicar nuevas versiones en los metadatos de owner para buscar y empaquetar las respuestas JSON de los recursos de metadatos.

Campo de respuesta de búsqueda verified

La UI del administrador de paquetes de Visual Studio muestra una marca de verificación azul junto a los paquetes en los resultados del servicio Search cuando un nuevo campo verifiedse ajusta en true.

NuGet.org usa esto con datos de prefijo de paquete (datos del lado servidor; no forman parte de la API de NuGet), de modo que esta marca de verificación solo se muestra a los clientes cuando la cuenta propietaria del paquete es la responsable de cargar el paquete. Por ejemplo, cualquier paquete con prefijo microsoft.* solo se verifica cuando el paquete es propiedad de la cuenta de Microsoft en nuget.org. Cualquier persona que haya cargado un paquete con el id. de paquete que empieza por microsoft. antes de que se implementaran los prefijos reservados, no tendrá esta marca de verificación. NuGet.org también permite que los prefijos no sean exclusivos, de modo que cualquier usuario pueda cargar un paquete en Contoso.ToolWithPlugins.Community.*. Sin embargo, en este caso no se obtendrá una marca de verificación.

Compatibilidad con Versionamiento Semántico 2.0.0

NuGet admite un híbrido entre System.Version y la versión semántica, pero la compatibilidad con la versión semántica 2.0.0 se agregó en 2017. Por lo tanto, los recursos de la API de NuGet que devuelven versiones a versiones de cliente inferiores a 3.6.0 no deben devolver paquetes que utilicen características semánticas 2.0.0 incompatibles con Versionamiento Semántico 1.0.0.

Las diferencias más importantes entre las dos versiones son las etiquetas de versión preliminar y la cadena de metadatos. La especificación de Versionamiento Semántico 1.0.0 proporciona [0-9A-Za-z-] como una cadena de expresión regular de muestra para los únicos caracteres que se permiten como parte de la etiqueta de versión preliminar, y no admite cadenas de metadatos. La especificación de Versionamiento Semántico 2.0.0 permite separar los id. de versión preliminar mediante caracteres . y prohíbe que un identificador numérico tenga un cero inicial. Asimismo, permite agregar metadatos de generación después de +.

En el recurso de metadatos del paquete (RegistrationsBaseUrl), las versiones de recursos inferiores a 3.6.0 solo deben devolver paquetes que cumplan con System.Version de .NET o con Versionamiento Semántico 1.0.0. Esto significa que los paquetes cuyas versiones solo son compatibles con Versionamiento Semántico 2.0.0 son invisibles para estas versiones de cliente.

Del mismo modo, el servicio de consulta de búsqueda (SearchQueryService) y el servicio de autocompletar (SearchAutocompleteService) han agregado parámetros de consulta &semVerLevel={version}. Cuando falte semVerLevel, debes suponer el valor 1.0.0. Al igual que ocurre con el recurso de metadatos de paquete, los paquetes cuya versión solo sea compatible con Versionamiento Semántico 2.0.0 no se deben devolver cuando el valor semVerLevel sea inferior a 2.0.0.

Archivos incrustados

Los iconos, la licencia y los archivos Léame del paquete pueden (y deben) estar incrustados en dicho paquete. Estos archivos necesitan un punto de conexión de dirección URL, ya sea mediante su extracción y colocación en un servidor de archivos estáticos, o por medio de una dirección URL que extraiga dinámicamente los archivos de .nupkg cuando así se requiera, de modo que se puedan visualizar sin descargar todo el archivo nupkg. Si el repositorio de paquetes proporciona información de navegación y visualización, puedes utilizar las direcciones URL para mostrar a los clientes el contenido incrustado en tu sitio web.

Por último, el recurso de metadatos del paquete y el recurso de búsqueda deben contener la dirección URL hospedada en las propiedades iconUrl, licenseUrl y/o readmeUrl de la respuesta JSON. Los paquetes (archivos .nupkg) no se deben modificar, ya que las características de cliente (es decir, los archivos de bloqueo y los paquetes firmados) detectarán modificaciones, como en caso de que el paquete haya sido alterado.

Nota: La licencia podría ser una expresión SPDX o un archivo incrustado (pero no ambos). Los paquetes que utilizan una expresión de licencia, cuando se representan en los resultados de metadatos de búsqueda y paquete, pueden tener la licenseUrl configurada como la expresión de licencia, codificada como dirección URL y anexada al final de la dirección https://licenses.nuget.org/. Por ejemplo, https://licenses.nuget.org/Apache-2.0. El equipo del servidor de NuGet.org tiene documentación adicional sobre licenses.nuget.org.

Datos conocidos de vulnerabilidad y desuso

Recurso de metadatos de paquete (RegistrationsBaseUrl)

El recurso de metadatos de paquete puede contener información de desuso y vulnerabilidad. Esto permite a los clientes que examinen paquetes en la interfaz de usuario Administrador de paquetes de Visual Studio, o en una herramienta equivalente de otros IDE, recibir notificaciones de problemas importantes de seguridad o mantenimiento.

Si el repositorio de paquetes está “reuniendo” paquetes de otro repositorio a fin de reflejar los paquetes de tu propio feed, te recomendamos comprobar periódicamente el origen por si hay datos de vulnerabilidades o de desuso, y reflejar esos metadatos en tu propio repositorio. Si el repositorio de paquetes reúne los datos de nuget.org específicamente, y mantiene el estado de la última vez que lo has comprobado (por medio de un “cursor”), puedes utilizar el recurso Catalog para comprobar de forma eficaz si existen actualizaciones de los paquetes que estás reflejando, y evitarte así tener que descargar un gran número de archivos JSON de metadatos de paquete desde el feed del canal de subida. Hay disponible una guía sobre la utilización del recurso de catálogo con código de ejemplo que puede ayudarte a comenzar.

Base de datos de vulnerabilidades conocidas (VulnerabilityInfo)

A fin de proporcionar un examen de vulnerabilidades de alto rendimiento durante la restauración del paquete, NuGet descarga la lista completa de vulnerabilidades conocidas del recurso VulnerabilityInfo. Nuget.org proporciona datos de vulnerabilidad para todas las advertencias revisadas de la base de datos de advertencias de GitHub, que incluye paquetes que no se hallan hospedados en nuget.org.

Si el repositorio de paquetes hospeda paquetes de primera entidad y quieres ofrecer información de vulnerabilidad a los clientes que usan tu propio feed, pero aún no tienes vulnerabilidades de paquete divulgadas, debes proporcionar un índice de vulnerabilidades con una o más páginas de vulnerabilidades cuyo contenido sea una matriz JSON vacía ([]).

Si el repositorio de paquetes está pensado para que lo utilicen las aplicaciones como repositorio predeterminado (en lugar de nuget.org), puedes utilizar los datos de vulnerabilidades de nuget.org. Una opción es utilizar la dirección URL del índice de vulnerabilidades de nuget.org en el índice de servicio. Otra opción es comprobar periódicamente el índice VulnerabilityInfo de nuget.org y descargar las páginas modificadas para reflejarlas localmente.

Consulta de búsqueda de packageTypes

La CLI de .NET permite buscar paquetes de herramientas de .NET con el comando dotnet tool search. Esto se implementa agregando un parámetro de consulta &packageTypes={value} al recurso de consulta de búsqueda, el cual lee los valores del campo <packageTypes> del archivo .nuspec del paquete.

Estructura de direcciones URL para feeds autenticados

Tal y como se describe en la información general de la API de NuGet, la dirección URL inicial para toda la comunicación del servidor NuGet es el índice de servicio. Este documento contiene las direcciones URL del resto de recursos que consultarán los clientes de NuGet. A partir de NuGet 6.7 (Visual Studio y MSBuild 17.7, y .NET SDK 7.0.400), NuGet utiliza HttpClientHandler.PreAuthenticate de .NET, que solo evita las solicitudes HTTP anónimas cuando las direcciones URL posteriores están en el mismo directorio virtual (o en un subdirectorio) de una dirección URL que se ha autenticado anteriormente. Esto reducirá considerablemente el número de solicitudes HTTP no autenticadas enviadas al servidor y, por tanto, también disminuirá la carga de trabajo de este.

Estos son algunos ejemplos:

URL ¿Realizará una autenticación previa?
https://pkgs.contoso.com/nuget/v3/feed/index.json N/D, este es el índice de servicio.
https://pkgs.contoso.com/nuget/v3/search No, no en el mismo directorio ni en el mismo subdirectorio que el índice de servicio.
https://search.pkgs.contoso.com/nuget/v3/feed/ No, no en el mismo nombre de host que el índice de servicio.
https://pkgs.contoso.com/nuget/v3/feed/search Sí, en el mismo directorio que el índice de servicio.
https://pkgs.contoso.com/nuget/v3/registration/ No, no en un subdirectorio del índice de servicio.
https://pkgs.contoso.com/nuget/v3/feed/registration/ Sí, en un subdirectorio del índice de servicio.
https://pkgs.contoso.com/nuget/v3/{guid}/registration/ Consulte a continuación

En el último ejemplo, el servidor podría tener un nombre canónico (en este ejemplo, un nombre “Guid”) y uno o más alias. Si la solicitud de índice de servicio se autenticó en una dirección URL no canónica (el nombre “descriptivo”, en nuestro feed de muestra), las solicitudes para los recursos de la dirección URL canónica no coincidirán con las reglas de HttpClientHandler para PreAuthenticate. Sin embargo, si la dirección URL no canónica es un redireccionamiento HTTP a la dirección URL canónica, https://pkgs.contoso.com/nuget/v3/{guid}/index.json, esta dirección URL se usará en la caché de credenciales de HttpClientHandler. En este caso, todas las solicitudes al índice de servicio tendrán latencia adicional, debido al redireccionamiento.

Aunque la API V3 de NuGet se diseñó para funcionar en un servidor de archivos estáticos, el recurso de búsqueda es la excepción que siempre requiere un servicio web dinámico para procesar las solicitudes. Si deseas alojar la búsqueda o, de hecho, cualquier otro recurso de API de NuGet en distintos servidores, para poder beneficiarte de los elementos PreAuthenticate de HttpClientHandler, deberás utilizar un proxy inverso para asegurarte de que todas las direcciones URL orientadas al cliente en el índice de servicio cumplan la regla “igual o subdirectorio”.