包版本控制
始终引用特定包的包标识符和确切版本号。 例如,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 的某些
在本主题中:
- 版本基础知识 包括预发行后缀。
- 版本范围
- 规范化版本号
- 语义版本控制 2.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
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
文件指定版本或版本范围。 如果没有版本或版本范围,在解析依赖项时,不能保证一致的还原结果。
除非知道兼容性问题,否则请避免将版本范围的上限指定到你不拥有的包。 对版本范围的上限会损害采用,阻止使用者获取对依赖项的宝贵更新,在某些情况下可能会导致用户使用不受支持的依赖项版本。
项目文件中的引用 (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
pack
和 restore
操作尽可能规范化版本。 对于已生成的包,此规范化不会影响包本身的版本号;它仅影响 NuGet 在解析依赖项时与版本匹配的方式。
但是,NuGet 包存储库必须以与 NuGet 相同的方式对待这些值,以防止包版本重复。 因此,包含包版本 1.0 的存储库不应将版本 1.0.0 作为单独的包承载。
语义版本控制 2.0.0
旧客户端不支持 SemVer v2.0.0 的某些语义。 如果以下任一语句为 true,NuGet 会将包版本视为特定于 SemVer v2.0.0:
- 预发行标签是点分隔的,例如,1.0.0-alpha.1
- 版本具有生成元数据,例如,1.0.0+githash
对于 nuget.org,如果以下任一语句为 true,则包定义为 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+
- Visual Studio 2015 与 NuGet VSIX v3.6.0
- .NET SDK 2.0.0+
第三方客户端:
- JetBrains Rider
- Paket 版本 5.0+
NuGetVersion 与语义版本控制存在分歧的位置
如果要以编程方式使用 NuGet 包版本,强烈建议 包 NuGet.Versioning。 静态方法 NuGetVersion.Parse(string)
可用于分析版本字符串,VersionComparer
可用于对 NuGetVersion
实例进行排序。
如果要以不在 .NET 上运行的语言实现 NuGet 功能,以下是 NuGetVersion
与语义版本控制之间的差异的已知列表,以及现有语义版本控制库可能不适用于已在 nuget.org 发布的包的原因。
-
NuGetVersion
支持第四个版本段(Revision
)与System.Version
的超集兼容。 因此,不包括预发行版和元数据标签,版本字符串Major.Minor.Patch.Revision
。 根据上述版本规范化,如果Revision
为零,则会从规范化版本字符串中省略它。 -
NuGetVersion
只需要定义主要段。 所有其他项都是可选的,等效于零。 这意味着,1
、1.0
、1.0.0
和1.0.0.0
都接受和平等。 -
NuGetVersion
对预发行组件使用不区分大小写的字符串比较。 这意味着1.0.0-alpha
和1.0.0-Alpha
相等。