程序包版本控制
始终使用特定包的包标识符和确切的版本号来引用该包。 例如,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-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
pack
和 restore
操作可尽可能规范化版本。 对于已生成的包,此规范化不会影响包本身的版本号;仅影响 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 上发布的包的原因。
NuGetVersion
支持第 4 个版本段,即Revision
,以兼容System.Version
或作为其超集。 因此,除了预发行版和元数据标签,版本字符串为Major.Minor.Patch.Revision
。 根据上述版本规范,如果Revision
为零,则将从规范化版本字符串中省略它。NuGetVersion
只要求定义 major 段。 所有其他段都是可选的,等效于零。 这意味着1
、1.0
、1.0.0
和1.0.0.0
都是可接受并且相等的。- 对于预发行组件,
NuGetVersion
使用不区分大小写的字符串比较。 这意味着1.0.0-alpha
和1.0.0-Alpha
相等。