正确管理解决方案之间的私有 nuget 包依赖项

Gon*_*eto 1 nuget nuget-package .net-core

我们有 2 个解决方案。

SolutionA是一个内部解决方案,我们将可重用代码放在我们的产品中 为了这个问题,它只有两个项目,NugetProjectA并且NugetProjectB有一个project referenceto NugetProjectA

SolutionB它是通过 nugetpackage references实现的解决方案SolutionA

麻烦的是:

  • 添加新方法 NugetProjectA
  • NugetProjectB使用以前方法的项目中添加新方法
  • 发布新版本 NugetProjectB
  • 更新的NuGet参考ProjectSolutionA
  • Project新添加的方法中执行NugetProjectB

由于我们没有发布NugetProjectA更新的版本,所以上一步描述的将失败。

这似乎是一个很容易解决的问题。但是想象一下,SolutionBSolutionA.

在此处输入图片说明

ziv*_*kan 5

您的问题含糊不清且开放式,因此没有简单明了的答案。老实说,它很容易成为一个多帖子的博客系列,甚至是一本短书。我会尝试给出一些一般性建议,但我不会详细介绍以避免使这个答案太长。

单回购与多个回购

就像几年前的微服务热潮一样,你应该先问问自己是否需要它。将所有源代码放在一个存储库和解决方案中可能会让它感觉“遗留”,并且在签入 1 行代码时,3 分钟构建一个组件而不是 30 分钟构建整个系统似乎更好错误修复。但是,您在问题中列出的问题是否值得更短的 CI 构建带来的好处?

在另一个极端,谷歌可能会在一个存储库中运行几乎所有东西,但他们的团队只是管理他们的单一存储库和构建系统,因为在单个存储库上工作的大量开发人员拥有不同的集合的问题。这些是不从事客户应用程序的工程师。如果他们的工作使其他团队更有效率,那么这可能是值得的。

您需要弄清楚什么最适合您,但考虑到您在问题中描述的问题,也许您有太多的存储库/解决方案,如果您稍微整合一下,您的流程可能会更快,错误更少。

自动化

下一个最好的事情就是使用良好的工程实践。尽可能自动化以降低人为错误的风险,包括自动化流程以验证是否正确遵循手动流程。

  • 拥有 CI 或 CD 管道推送包,因此您不能忘记推送依赖项,就像在您的示例中一样。
  • 有一些工具会根据自检入版本控制配置文件以来的提交次数自动从 git 历史记录生成版本号。这可以防止您在检入对包的更改时忘记增加包版本。
  • 在推送之前进行测试以确保包可以正常工作。您可以像确保存在依赖关系一样简单,但您也可以更进一步,运行使用该包的测试程序,以确保向后兼容性不会被破坏,并且新功能实际上按预期工作。在推送包之前运行这些测试,所以如果测试失败,你不会推送一个坏包。
  • 您可以拥有一个管道,当您的一个包的新版本发布时,该管道将自动在使用包的解决方案上创建拉取请求。你甚至可以自动合并它,但你需要确保你有真正好的测试,以避免有错误的包级联成一团糟,特别是如果你对成功的构建进行自动部署。
  • 要有创意,并考虑其他可以自动化流程的方法,让您和您的团队更轻松。

但要务实地对待你的自动化。没有必要花一周的时间来自动化一些每月只需要 5 分钟手动完成的事情。但是,如果手动过程有时会出错并导致需要花费数小时或数天的时间来修复,那么使过程自动化更有价值。

使用现代功能

自 .NET Core 发布以来,.NET 生态系统在过去的 2-3 年里发生了很大变化。现在使用 MSBuild(dotnet packmsbuild -t:pack)打包比创建.nuspec文件更容易创建包,并确保您做正确的事情以将项目依赖项打包为 nuget 依赖项,将所有文件放在正确的位置等。如果您的类库使用 SDK 样式项目,然后没有什么额外的事情要做。如果您的项目是传统项目,则需要将其PackageReference用于 NuGet 依赖项(或<ProjectStyle>PackageReference</ProjectStyle>在项目文件中指定为 MSBuild 属性),然后引用该NuGet.Build.Tasks.Pack包。

版本应用程序,而不是每个包

就像单存储库与多存储库点一样,考虑使用单个版本号对应用程序中的所有包进行版本控制,而不是单独对每个包进行版本控制。是的,这意味着您有时(或者可能经常)发布一个包的新版本,该版本对以前的版本没有任何代码更改,但它大大简化了发布。结合上一节中的 MSBuild 打包,您可以Directory.Build.props在存储库根目录中创建一个文件,并设置<Version>属性为您的应用程序版本,并且所有项目都将具有相同的版本。因此,当您准备好发布时,将版本添加到单个文件中,并且每个项目和每个 NuGet 包都将具有相同的版本。

概括

在理想的世界中,每个组件都可以在不同的应用程序中重用,在单独的源代码存储库中,每个包都使用语义版本控制单独进行版本控制。但在现实世界中,这会增加很多开发时间的复杂性。您的客户可能更乐意更快地获得错误修复和新功能,即使软件包的版本号意义不大。因此,请做出数据驱动的决策。如果您经常遇到依赖项版本问题,请减少您的依赖项,从而减少可能出错的情况。

不要误会我的意思,拥有多个项目、多个解决方案、多个存储库有很多很好的理由。只要确保你这样做的原因是因为它可以帮助你的团队/公司提高工作效率,而不是因为理想化的原因会减慢你的速度或导致错误。