NuGet的Restore Package坚持特定的软件包版本

Ily*_*tok 19 .net nuget nuget-package

我有一个包含以下packages.config的项目:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Framework.Infrastructure.Core" version="1.4.0.6" />
  <package id="Framework.Infrastructure.Extensions" version="1.4.0.6" />
</packages>
Run Code Online (Sandbox Code Playgroud)

Framework.*包位于我们的本地存储库中.

我启用了Package Restore并将内部repo添加到了源代码中.但是,当我尝试从packages.config(基本上nuget install packages.config -sources....)恢复包时,我收到以下错误:

error : Unable to find version '1.4.0.6' of package 'Framework.Infrastructure.Extensions'
error : Unable to find version '1.4.0.6' of package 'Framework.Infrastructure.Core'.
Run Code Online (Sandbox Code Playgroud)

存储库不再包含该软件包的1.4.0.6版本(几个月前相关),而是包含它的新版本(例如,1.5.1.6).

为什么NuGet没有找到新版本的软件包?我可以在packages.config中指定一些语法以确保下载最新版本吗?

简而言之,编写自定义脚本以更新我可以执行的包有什么用吗?

谢谢.

Kil*_*man 39

我认为有些人误解了Package Restore的意图.此功能仅添加到NuGet,目的是不要将包检入版本控制.很多人都在抱怨提交二进制文件正在扩大其存储库的大小,并且当使用像git这样的DVCS时会更糟糕,其中整个存储库在本地下载并包含每个版本的软件包Foo.

那么Package Restore究竟做了什么?基本上它在每个项目的packages.config中查找并简单地下拉列出的包的特定版本.这就像删除你的包文件夹,然后做git reset --hard回来(假设文件夹已签入).

为什么这很重要?为什么不升级到最新的软件包版本?如果您考虑Package Restore的最常见用例,即自动构建,那么应该为您提供线索.构建服务器应该只构建由开发人员测试和提交的项目.如果您让构建服务器决定何时更新包,那么您有一个尚未经过任何人测试的项目.作为开发人员,您应该决定何时进行升级.

请记住,安装或更新软件包并不只是简单地下载.nupkg文件并添加引用.很多软件包都有副作用,例如更新.config文件,添加代码等.安装软件包时,所有这些副作用都会发生在本地副本上.您现在可以提交代码并排除包文件.

当另一个开发人员或构建服务器检出代码时,他将使用完全相同的副作用代码减去包文件.Package Restore只是从NuGet存储库中提取这些文件,现在我们拥有了处理这个项目所需的一切.

NuGet团队承诺维护所有版本的软件包,以便您始终能够下载正确的版本.然而,正如我们几个月前看到的那样,当NuGet服务器出现故障时,它几乎瘫痪了Package Restore,很多人无法构建.

我建议您设置自己的NuGet存储库(一个简单的文件共享),并保留您在那里使用的所有包的副本.这样,您就不依赖于构建的外部服务器.正如NuGet团队所做的那样,你应该保留所有版本的软件包.这样,如果您必须返回并构建项目的旧版本,您将确保拥有正确的软件包版本.

我希望这可以解释该功能的工作原理以及它为何如此工作.


Jes*_*ebb 8

我建议您阅读版本控制NuGet文档.它解释了如何在packages.config文件中使用版本号(和范围)以允许Update-Package命令知道要升级到的可接受版本.

话虽这么说,包恢复功能不会自动为您更新包.

有了这些信息,最好的工作流程IMO是:

  • 安装您正​​在添加的任何新依赖项的最新稳定版本,除非您确实需要较旧(或预发布)版本
  • 在CI版本中使用Package Restore,允许您不在您的VCS中签入NuGet包
  • 只有Update-Package......
    • 您需要从最新版本进行新的API调用或错误修复
    • 你有一个很有信心的测试套件
    • 你有时间处理潜在的后果

我不鼓励定期升级包,因为.如果项目运行良好,最好让项目与旧的依赖项保持一致,因为在更新任何软件包的版本时存在风险.

NuGet包应该遵循语义版本控制,它具有允许最无压力的包升级体验的良好规则,但由于这没有强制执行(并且相信我,许多包发布者不遵循SemVer),你不能依赖它.即使只更新了一个版本来更新软件包,您也无法确定(没有经过充分测试)新版本将与您的代码一起使用.

总之,自动升级任何包通常是个坏主意.最好让开发人员明确选择更新任何给定的包,并且只有足够好的理由.

  • @FuriCuri您描述的版本范围仅用于`.nuspec`文件,而不是`packages.config`.它们用于描述包之间的依赖关系.在项目中指定依赖项时,使用`packages.config`文件,它始终引用特定版本.是的,你是对的,除非你最近构建了你的项目并且所有的Nu​​Get依赖项都存在于`/ packages`目录中,否则`Update-Package`命令将不起作用.这可能不方便或不直观,但我不认为这是一个错误; 这简直就是NuGet的运作方式. (4认同)
  • 它的问题在于,基于版本控制规范,`version ="1.4.0.6"`版本(默认情况下在packages.config中)应该被翻译成`version> = 1.4.0.6`,但事实并非如此.而且我认为这是nuget还原中的一个错误,因为"update"根本不使用packages.config(它似乎只使用`packages`目录中的文件夹 - 所以如果你没有包,那么"update"甚至不会做任何事情如果你有packages.config文件). (3认同)