在许多 projects/solutions 中保持 Nuget 包更新

Keeping Nuget packages updated in many projects/solutions

如果在多个解决方案上使用相同的 nuget 包,我如何使它们保持最新状态而不必在发布新版本时打开每个解决方案和更新包?

文件夹结构通常是这样的,但在更多项目中。每个项目都有自己的 packages.config 和各种包引用。

$tfs/
├── Solution One/
│   ├ Solution 1.sln
│   ├   nuget.config (solution item)
│   ├── Packages/
│   ├    ├── Newtonsoft.JSON.12.0.2/
│   ├    ├── Jquery3.1.4/
│   ├── Project one/
│   ├       ── packages.config
│   ├       ── whatever.cs
│   ├       ── folder /
│   ├       ── another folder /
│   ├── Project Two/
│   ├       ── packages.config
│   ├       ── file.cs
│   ├       ── folder/
│   ├       ── another folder/
├── Solution Two/
│   ├ Solution 2.sln
│   ├   nuget.config
│   ├── Packages/
│   ├    ├── Newtonsoft.JSON.11.1.0/
│   ├    ├── Jquery1.3.4/
│   ├── Project one/
│   ├       ── packages.config
│   ├       ── whatever.cs
│   ├       ── folder /
│   ├       ── another folder /
│   ├── Project two/
│   ├       ── packages.config
│   ├       ── file.cs
│   ├       ── folder/
│   ├       ── another folder/

我已经在程序包管理器控制台中尝试 运行 这个 powershell,但这一次只适用于一个解决方案:

$packageId = "jquery"
Get-ChildItem *.sln -recurse | %{.\nuget.exe restore $_.fullname}
Get-ChildItem packages.config -Recurse `
| Where-Object {$_ | Select-String -Pattern $packageId} `
| %{.\nuget.exe update -Id $packageId $_.FullName}

我是否需要在每个项目的每个解决方案中更新 packages.config 并打开它们以获取更新?我本以为会有更简单的方法来做到这一点。如果它有所作为,我正在使用私人 nuget 服务器。

注意:我看过这个问题:Updating nuget packages in all projects in a solution 和我的情况不一样。我希望跨多个解决方案更新包,而不是一个解决方案中的多个项目。

正如@imps 在评论中所说,packages.config 个项目没有跨解决方案的解决方案。在一个解决方案中,您可以使用 NuGet 包管理器 UI 的 "Manage packages for solution",合并选项卡有助于确保所有项目使用相同的版本,但您需要对所有解决方案重复此操作。

如果你migrate from packages.config to PackageReference, you could take advantage of MSBuild extensibility and either import a common props file, or if using Visual Studio 2017 or newer, use Directory.Build.Props在所有项目的最高公共父目录中。

在你的 props 文件中,你定义你关心的包的版本,像这样:

<Project>
  <PropertyGroup>
    <NewtonsoftJsonVersion>12.0.1</NewtonsoftJsonVersion>
  </PropertyGroup>
</Project>

然后在您的 csproj 文件中,使用 <PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonVersion)" />。这个问题是你不能再使用包管理器 UI 或 VS 中的包管理器控制台来升级(你可以,但它会在 csproj 中更改它,而不是你的 props 文件),但您仍然可以使用 UI 检查更新。如果您将 props 文件添加到您的解决方案中,那么只需单击两次并在键盘上轻敲几下即可更新,所以这真的没什么大不了的。

在您的示例中,公共父目录将是 TFS 根目录,因此 $/Directory.Build.props。问题是,如果您使用 CI 并触发 运行 解决方案一基于对 $/Solution One/* 的更改和 运行 解决方案二基于对 $/Solution Two/*,那么他们都会错过对 $/Directory.Build.props 的更改。或者也许可以配置 TFS 构建触发器以包含它,但我不记得了,因为我已经很长时间没有使用 TFVC 了。

但是,更大的问题是在您的示例中,很明显您使用的是 jQuery 包。这使用 content,它将文件复制到 install/upgrade 上的项目中。 PackageReference 不能这样工作(它被列为 package compatibility issue) , so unless you want to have a different process for upgrading jQuery and any other js/css in your web projects, you can't migrate ASP.NET projects to PackageReference. Note that ASP.NET Core projects are SDK style which only support PackageReference, not packages.config, and typically use either LibMan 或 npm 以获得 css 和 javascript.

可以迁移到 SDK 样式项目的客户,他们甚至可以考虑使用 this SDK for central package management,这有助于确保您不会不小心在 csproj.

中留下版本号