包版本控制

始终使用特定包的包标识符和确切的版本号来引用该包。 例如,nuget.org 上的实体框架提供了数十个特定包,范围从版本 4.1.10311 到版本 6.1.3(最新稳定版)以及各种预发布版本(例如 6.2.0-beta1) 。

创建包时,可以分配带有可选预发布文本后缀的特定版本号。 另一方面,使用包时,可以指定确切的版本号或可接受的版本范围。

本主题内容:

版本基础知识

特定版本号的格式为 Major.Minor.Patch[-Suffix] ,其中的组件具有以下含义:

  • Major:重大更改
  • Minor:新增功能,但可向后兼容
  • Patch:仅可向后兼容的 bug 修复
  • -Suffix(可选):连字符后跟字符串,表示预发布版本(遵循 语义化版本控制或 SemVer 1.0 约定)。

示例:

1.0.1
6.11.1231
4.3.1-rc
2.2.44-beta1

重要

nuget.org 拒绝缺少确切版本号的任何包上传。 必须在用于创建包的 .nuspec 或项目文件中指定版本。

预发布版本

从技术上讲,包创建者可以将任何字符串用作后缀来表示预发布版本,因为 NuGet 会将任何此类版本视为预发布版本,而不进行任何其他解释。 也就是说,NuGet 在任何涉及的 UI 中显示完整版本字符串,并让使用者自行理解后缀的含义。

综上所述,包开发人员通常遵循识别的命名约定:

  • -alpha:Alpha 版本,通常用于在制品和试验品。
  • -beta:Beta 版本,通常指可用于下一计划版本的功能完整的版本,但可能包含已知 bug。
  • -rc:候选发布,通常可能为最终(稳定)版本,除非出现重大 bug。

备注

NuGet 4.3.0+ 支持 SemVer 2.0.0,后者支持采用点表示法的预发布号,如 1.0.1-build.23 中所示。 NuGet 4.3.0 之前的版本不支持点表示法。 可以使用类似于 1.0.1-build23 的形式 。

解析包引用时,如果多个包版本只有后缀不同,NuGet 会首先选择不带后缀的版本,然后按反向字母顺序来排列预发布版本的优先顺序。 例如,将按显示的确切顺序选择以下版本:

1.0.1
1.0.1-zzz
1.0.1-rc
1.0.1-open
1.0.1-beta
1.0.1-alpha2
1.0.1-alpha
1.0.1-aaa

语义化版本控制 2.0.0

借助 NuGet 4.3.0+ 和 Visual Studio 2017 版本 15.3+,NuGet 支持语义化版本控制 2.0.0

旧客户端不支持 SemVer v2.0.0 的某些语义。 在以下任意一种情况下,NuGet 会将包版本视为特定于 SemVer v2.0.0:

  • 预发布标签以点分隔,例如,1.0.0-alpha.1
  • 版本具有生成元数据,例如,1.0.0+githash

对于 nuget.org,在以下任意一种情况下,会将包定义为 SemVer v2.0.0 包:

  • 按照上述定义,包自己的版本与 SemVer v2.0.0 兼容,但与 SemVer v1.0.0 不兼容。
  • 按照上述定义,包的任何依赖项版本范围都具有与 SemVer v2.0.0 兼容但与 SemVer v1.0.0 不兼容的最低版本或最高版本;例如,[1.0.0-alpha.1, ) 。

如果将 SemVer v2.0.0 特定包上传到 nuget.org,则该包对较旧的客户端不可见,并且仅可用于以下 NuGet 客户端:

  • NuGet 4.3.0+
  • Visual Studio 2017 版本 15.3+
  • 带有 NuGet VSIX v3.6.0 的 Visual Studio 2015
  • dotnet
    • dotnetcore.exe (.NET SDK 2.0.0+)

第三方客户端:

  • JetBrains Rider
  • Paket 版本 5.0+

版本范围

引用包依赖项时,NuGet 支持使用间隔表示法来指定版本范围,汇总如下:

Notation 应用的规则 说明
1.0 x ≥ 1.0 最低版本(包含)
(1.0,) x > 1.0 最低版本(独占)
[1.0] x == 1.0 精确的版本匹配
(,1.0] x ≤ 1.0 最高版本(包含)
(,1.0) x < 1.0 最高版本(独占)
[1.0,2.0] 1.0 ≤ x ≤ 2.0 精确范围(包含)
(1.0,2.0) 1.0 < x < 2.0 精确范围(独占)
[1.0,2.0) 1.0 ≤ x < 2.0 混合了最低版本(包含)和最高版本(独占)
(1.0) 无效 无效

使用 PackageReference 格式时,NuGet 还支持使用浮点表示法 * 来表示版本号的主要、次要、修补程序和预发布后缀部分。 packages.config 格式不支持可变版本。 指定可变版本后,规则是解析为与版本描述匹配的现有最高版本。 下面是可变版本和解析方法的示例。

备注

PackageReference 中的版本范围包括预发布版本。 按照设计,可变版本不会解析预发布版本,除非选择加入。 有关相关功能请求的状态,请参阅问题 6434

示例

始终指定项目文件、packages.config 文件和 .nuspec 文件中的包依赖项的版本或版本范围。 如果没有版本或版本范围,NuGet 2.8. x 及更早版本会在解析依赖项时选择最新的可用包版本,而 NuGet 3.x 及更高版本会选择最低的包版本。 指定版本或版本范围可以避免这种不确定性。

项目文件中的引用 (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)" />

可变版本解析方法

版本 服务器上存在的版本 解决方法 原因 说明
* 1.1.0
1.1.1
1.2.0
1.3.0-alpha 版本
1.2.0 最高稳定版本。
1.1.* 1.1.0
1.1.1
1.1.2-alpha 版本
1.2.0-alpha 版本
1.1.1 遵循指定模式的最高稳定版本。
* - * 1.1.0
1.1.1
1.1.2-alpha 版本
1.3.0-beta 版本
1.3.0-beta 版本 包含不稳定版本的最高版本。 在 Visual Studio 版本 16.6、NuGet 版本5.6、.NET Core SDK 版本 3.1.300 中提供
1.1.* - * 1.1.0
1.1.1
1.1.2-alpha 版本
1.1.2-beta 版本
1.3.0-beta 版本
1.1.2-beta 版本 遵循模式并包含不稳定版本的最高版本。 在 Visual Studio 版本 16.6、NuGet 版本5.6、.NET Core SDK 版本 3.1.300 中提供

packages.config 中的引用:

packages.config 中,通过还原包时使用的确切 version 属性列出每个依赖项。 allowedVersions 属性仅在更新操作过程中用于将版本约束到包可能更新到的版本。

<!-- 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)" />

.nuspec 文件中的引用

<dependency> 元素中的 version 属性描述了依赖项可接受的范围版本。

<!-- 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)" />

规范化的版本号

备注

这是 NuGet 3.4 及更高版本的重大更改。

当在安装、重新安装或还原操作过程中从存储库获取包时,NuGet 3.4+ 会按如下所示处理版本号:

  • 从版本号中删除前导零:

    1.00 被视为 1.0,1.01.1 被视为 1.1.1,1.00.0.1 被视为 1.0.0.1

  • 将忽略版本号第四部分中的零

    1.0.0.0 被视为 1.0.0,1.0.01.0 被视为 1.0.1

  • 已删除 SemVer 2.0.0 生成元数据

    1.0.7+r3456 被视为 1.0.7

packrestore 操作可尽可能规范化版本。 对于已生成的包,此规范化不会影响包本身的版本号;仅影响 NuGet 在解析依赖项时匹配版本的方式。

但是,NuGet 包存储库必须以与 NuGet 相同的方式处理这些值,以防止包版本重复。 因此,包含包版本 1.0 的存储库还不应将版本 1.0.0 作为单独的不同包进行托管。

其中,NuGetVersion 与语义化版本控制分离

如果要以编程方式使用 NuGet 包版本,强烈建议使用包 NuGet.Versioning。 静态方法 NuGetVersion.Parse(string) 可用于分析版本字符串,VersionComparer 可用于对 NuGetVersion 实例进行排序。

如果要使用不在 .NET 上运行的语言来实现 NuGet 功能,可参考以下 NuGetVersion 和语义化版本控制的已知差异列表,以及现有语义化版本控制库可能不适用于已在 nuget.org 上发布的包的原因。

  1. NuGetVersion 支持第 4 个版本段,即 Revision,以兼容 System.Version 或作为其超集。 因此,除了预发行版和元数据标签,版本字符串为 Major.Minor.Patch.Revision。 根据上述版本规范,如果 Revision 为零,将从规范化版本字符串中省略它。
  2. NuGetVersion 只要求定义 major 段。 所有其他段都是可选的,等效于零。 这意味着 11.01.0.01.0.0.0 都是可接受并且相等的。
  3. 对于预发行组件,NuGetVersion 使用不区分大小写的字符串比较。 这意味着 1.0.0-alpha1.0.0-Alpha 相等。