Control de versiones de paquetes

Siempre se hace referencia a un paquete específico mediante su identificador de paquete y un número de versión exacto. Por ejemplo, Entity Framework en nuget.org tiene varias docenas de paquetes específicos disponibles, que van desde la versión 4.1.10311 a la versión 6.1.3 (la versión estable más reciente) y una variedad de versiones preliminares como 6.2.0-beta1.

Al crear un paquete, se asigna un número de versión específico con un sufijo de texto de versión preliminar opcional. Por otra parte, al consumir paquetes puede especificar un número de versión exacto o un intervalo de versiones admisibles.

El siguiente documento sigue el estándar Versionamiento Semántico 2.0.0, compatible con NuGet 4.3.0+ y Visual Studio 2017 versión 15.3+. Ciertas semánticas de SemVer v2.0.0 no se admiten en los clientes más antiguos.

En este tema:

Aspectos básicos de la versión

Un número de versión específico tiene el formato .Revisión[-Sufijo], donde los componentes tienen los significados siguientes:

  • Principal: cambios importantes
  • Secundaria: nuevas características, compatibles con versiones anteriores
  • Revisión: solo correcciones de errores compatibles con versiones anteriores
  • -Sufijo (opcional): un guión seguido de una cadena que denota una versión preliminar (según la convención de Versionamiento Semántico o SemVer 1.0).

Ejemplos:

1.0.1
6.11.1231
4.3.1-rc
2.2.44-beta.1

Importante

nuget.org rechaza cualquier carga de paquetes que carezca de un número de versión exacto. La versión debe especificarse en el archivo .nuspec o de proyecto que se usa para crear el paquete.

Versiones preliminares

Técnicamente hablando, los creadores de paquetes pueden usar cualquier cadena como sufijo para denotar una versión preliminar, ya que NuGet trata cualquier versión como versión preliminar y no realiza ninguna otra interpretación. Es decir, NuGet muestra la cadena de versión completa en cualquier interfaz de usuario que esté implicada, dejando cualquier interpretación del significado del sufijo para el consumidor.

Dicho esto, los desarrolladores de paquetes generalmente siguen las convenciones de nomenclatura reconocidas:

  • -alpha: versión alfa, que se suele usar para el trabajo en curso y la experimentación.
  • -beta: versión beta, que suele contar con todas las características de la próxima versión planificada, pero puede contener errores conocidos.
  • -rc: versión candidata para lanzamiento. Suele ser una versión potencialmente definitiva (estable) a menos que surjan errores importantes.

Al ordenar las versiones por precedencia, NuGet sigue el estándar SemVer y elige primero una versión sin sufijo, luego aplica prioridad a las versiones preliminares por orden alfabético inverso y trata los números de notación de puntos con orden numérico.

Nota:

Los números de versión preliminar con notación de puntos, como en 1.0.1-build.23, se consideran parte del estándar SemVer 2.0.0 y, como tal, solo se admiten con NuGet 4.3.0+.

1.0.1
1.0.1-zzz
1.0.1-rc.10
1.0.1-rc.2
1.0.1-open
1.0.1-beta
1.0.1-alpha2
1.0.1-alpha10
1.0.1-aaa

Tenga en cuenta que 1.0.1-alpha10 se organiza estrictamente por orden alfabético inverso, mientras que la precedencia de 1.0.1-rc.10 es mayor que 1.0.1-rc.2.

Rangos de versiones

Cuando se hace referencia a las dependencias de paquete, NuGet admite el uso de la notación de intervalo para especificar intervalos de versión, que se resumen de la siguiente manera:

Notación Regla aplicada Descripción
1.0 x ≥ 1.0 Versión mínima, incluida
[1.0,) x ≥ 1.0 Versión mínima, incluida
(1.0,) x > 1.0 Versión mínima, excluida
[1.0] x == 1.0 Coincidencia de versión exacta
(,1.0] x ≤ 1.0 Versión máxima, incluida
(,1.0) x < 1.0 Versión máxima, excluida
[1.0,2.0] 1.0 ≤ x ≤ 2.0 Intervalo exacto, ambos incluidos
(1.0,2.0) 1.0 < x < 2.0 Intervalo exacto, ambos excluidos
[1.0,2.0) 1.0 ≤ x < 2.0 Versión mínima incluida y versión máxima excluida mezcladas
(1.0) no válido no válido

Ejemplos

Especifique siempre una versión o un intervalo de versiones para las dependencias de paquete en archivos de proyecto, archivos packages.config y archivos .nuspec. Sin una versión o un intervalo de versiones, NuGet 2.8.x y las versiones anteriores eligen la versión del paquete más reciente disponible al resolver una dependencia, mientras que NuGet 3.x y las versiones posteriores eligen la versión de paquete más baja. La especificación de una versión o un intervalo de versiones evita esta incertidumbre.

Referencias en los archivos de proyecto (PackageReference)

<!-- Accepts any version 6.1 and above.
     Will resolve to the smallest acceptable stable version.-->
<PackageReference Include="ExamplePackage" Version="6.1" />

<!-- Accepts any 6.x.y version.
     Will resolve to the highest acceptable stable version.-->
<PackageReference Include="ExamplePackage" Version="6.*" />

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

<!-- Accepts any version up below 5.x, which might be used to prevent pulling in a later
     version of a dependency that changed its interface. However, this form is not
     recommended because it can be difficult to determine the lowest version. 
     Will resolve to the smallest acceptable stable version.
     -->
<PackageReference Include="ExamplePackage" Version="(,5.0)" />

<!-- Accepts any 1.x or 2.x version, but not 0.x or 3.x and higher.
     Will resolve to the smallest acceptable stable version.-->
<PackageReference Include="ExamplePackage" Version="[1,3)" />

<!-- Accepts 1.3.2 up to 1.4.x, but not 1.5 and higher.
     Will resolve to the smallest acceptable stable version. -->
<PackageReference Include="ExamplePackage" Version="[1.3.2,1.5)" />

Referencias en packages.config:

En packages.config, todas las dependencias se muestran con un atributo version exacto que se usa al restaurar los paquetes. El atributo allowedVersions solo se usa durante las operaciones de actualización para restringir las versiones en las que se puede actualizar el paquete.

<!-- Install/restore version 6.1.0, accept any version 6.1.0 and above on update. -->
<package id="ExamplePackage" version="6.1.0" allowedVersions="6.1.0" />

<!-- Install/restore version 6.1.0, and do not change during update. -->
<package id="ExamplePackage" version="6.1.0" allowedVersions="[6.1.0]" />

<!-- Install/restore version 6.1.0, accept any 6.x version during update. -->
<package id="ExamplePackage" version="6.1.0" allowedVersions="[6,7)" />

<!-- Install/restore version 4.1.4, accept any version above, but not including, 4.1.3.
     Could be used to guarantee a dependency with a specific bug fix. -->
<package id="ExamplePackage" version="4.1.4" allowedVersions="(4.1.3,)" />

<!-- Install/restore version 3.1.2, accept any version up below 5.x on update, which might be
     used to prevent pulling in a later version of a dependency that changed its interface.
     However, this form is not recommended because it can be difficult to determine the lowest version. -->
<package id="ExamplePackage" version="3.1.2" allowedVersions="(,5.0)" />

<!-- Install/restore version 1.1.4, accept any 1.x or 2.x version on update, but not
     0.x or 3.x and higher. -->
<package id="ExamplePackage" version="1.1.4" allowedVersions="[1,3)" />

<!-- Install/restore version 1.3.5, accepts 1.3.2 up to 1.4.x on update, but not 1.5 and higher. -->
<package id="ExamplePackage" version="1.3.5" allowedVersions="[1.3.2,1.5)" />

Referencias en archivos .nuspec

El atributo version de un elemento <dependency> describe las versiones de intervalo que son aceptables para una dependencia.

<!-- Accepts any version 6.1 and above. -->
<dependency id="ExamplePackage" version="6.1" />

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

<!-- Accepts any version up below 5.x, which might be used to prevent pulling in a later
     version of a dependency that changed its interface. However, this form is not
     recommended because it can be difficult to determine the lowest version. -->
<dependency id="ExamplePackage" version="(,5.0)" />

<!-- Accepts any 1.x or 2.x version, but not 0.x or 3.x and higher. -->
<dependency id="ExamplePackage" version="[1,3)" />

<!-- Accepts 1.3.2 up to 1.4.x, but not 1.5 and higher. -->
<dependency id="ExamplePackage" version="[1.3.2,1.5)" />

Números de versión normalizados

Nota:

Se trata de un cambio importante en NuGet 3.4+.

Al obtener paquetes de un repositorio durante las operaciones de instalación, reinstalación o restauración, NuGet 3.4+ trata los números de versión de la manera siguiente:

  • Los ceros a la izquierda se quitan de los números de versión:

    • 1.00 se trata como 1.0
    • 1.01.1 se trata como 1.1.1
    • 1.00.0.1 se trata como 1.0.0.1
  • Un cero en la cuarta parte del número de versión se omitirá

    • 1.0.0.0 se trata como 1.0.0
    • 1.0.01.0 se trata como 1.0.1
  • Se eliminarán los metadatos de la compilación 2.0.0 de SemVer.

    • 1.0.7+r3456 se trata como 1.0.7

Las operaciones pack y restore normalizan las versiones siempre que sea posible. En el caso de los paquetes ya creados, esta normalización no afecta a los números de versión de los propios paquetes; solo afecta al modo en que NuGet coincide con las versiones cuando se resuelven las dependencias.

Sin embargo, los repositorios de paquetes NuGet deben tratar estos valores de la misma manera que NuGet para evitar la duplicación de la versión del paquete. Por lo tanto, un repositorio que contiene la versión 1.0 de un paquete no debe hospedar también la versión 1.0.0 como un paquete independiente y diferente.

Versionamiento Semántico 2.0.0

Ciertas semánticas de SemVer v2.0.0 no se admiten en los clientes más antiguos. NuGet considera que una versión de paquete es específica de SemVer v2.0.0 si alguna de las siguientes afirmaciones es verdadera:

  • La etiqueta de versión preliminar está separada por puntos, por ejemplo, 1.0.0-alpha.1
  • La versión tiene metadatos de compilación, por ejemplo, 1.0.0+githash

En el caso de nuget.org, se define un paquete como un paquete de SemVer v2.0.0 si se cumple alguna de las siguientes instrucciones:

  • La versión propia del paquete es compatible con SemVer v2.0.0, pero no con SemVer v1.0.0, tal y como se definió anteriormente.
  • Cualquiera de los intervalos de versiones de dependencia del paquete tiene una versión mínima o máxima que es compatible con SemVer v2.0.0 pero no con SemVer v1.0.0, definida anteriormente; por ejemplo, [1.0.0-alpha.1, ).

Si carga un paquete específico de SemVer v2.0.0 en nuget.org, dicho paquete no es visible para los clientes más antiguos y solo está disponible para los siguientes clientes de NuGet:

  • NuGet 4.3.0+
  • Versión de Visual Studio 2017 15.3+
  • Visual Studio 2015 con NuGet VSIX v3.6.0
  • SDK DE .NET 2.0.0+

Clientes de terceros:

  • JetBrains Rider
  • Versión de Paket 5.0+

Divergencias entre NuGetVersion y el versionamiento semántico

Si quiere usar versiones de paquetes NuGet mediante programación, se recomienda encarecidamente usar el elemento NuGet.Versioning del paquete. El método estático NuGetVersion.Parse(string) se puede usar para analizar las cadenas de versión, y VersionComparer se puede usar para ordenar las instancias de NuGetVersion.

Si va a implementar la funcionalidad de NuGet en un lenguaje que no se ejecute en .NET, a continuación encontrará una lista de las diferencias conocidas entre NuGetVersion y el versionamiento semántico, así como los motivos por los que es posible que una biblioteca de versionamiento semántico existente no funcione para paquetes ya publicados en nuget.org.

  1. NuGetVersion admite un segmento de la cuarta versión, Revision, que será compatible con System.Version, o bien un superconjunto de este. Así pues, sin incluir las etiquetas de versiones preliminares y metadatos, una cadena de versión es Major.Minor.Patch.Revision. De acuerdo con la normalización de versiones descrita anteriormente, si Revision es cero, se omite de la cadena de versión normalizada.
  2. NuGetVersion solo requiere que se defina el segmento principal. El resto son opcionales y equivalentes a cero. Esto significa que 1, 1.0, 1.0.0 y 1.0.0.0 se aceptan y son iguales.
  3. NuGetVersion usa comparaciones de cadenas que no distinguen mayúsculas de minúsculas para componentes de versión preliminar. Esto significa que 1.0.0-alpha y 1.0.0-Alpha son iguales.