程序包版本控制

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

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

以下文档遵循 NuGet 4.3.0+ 和 Visual Studio 2017 版本 15.3+ 支持的语义化版本控制 2.0.0 标准。 旧客户端不支持 SemVer v2.0.0 的某些语义

本主题内容:

版本基础知识

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

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

示例:

1.0.1
6.11.1231
4.3.1-rc
2.2.44-beta.1

重要

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

预发布版本

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

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

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

按优先顺序对版本进行排序时,NuGet 遵循 SemVer 标准,先选择不带后缀的版本,然后按反向字母顺序对预发布版本应用优先级,并使用数字顺序处理点表示法数字。

注意

1.0.1-build.23 中的点表示法发布前数字属于 SemVer 2.0.0 标准,因此仅 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

请注意,1.0.1-alpha10 严格按反向字母顺序排序,而 1.0.1-rc.10 的优先级高于 1.0.1-rc.2。

版本范围

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

表示法 应用的规则 说明
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) 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) 无效 无效

示例

始终指定项目文件、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)" />

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 作为单独的不同包进行托管

语义化版本控制 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
  • .NET SDK 2.0.0+

第三方客户端:

  • JetBrains Rider
  • Paket 版本 5.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 相等。