使用 GitVersion 对多个相关的 NuGet 库进行版本控制。 MonoRepo 还是 MultiRepo?

Multiple related NuGet libraries versioning with GitVersion. MonoRepo or MultiRepo?

需要以下建议:

在我的公司,我正在开发供外部利益相关者使用的 .NET class 库,并且我在利益相关者可以访问的私有 NuGet 提要上共享它们。

这些库依赖于一个核心库,如下所示。目前我在单个 VS 解决方案中维护这些库,显然是在一个 Git 存储库中。我正在关注 SemVer 来对它们进行版本控制。

CoreLibrary
CoreLibrary.Extension1 (references CoreLibrary as project reference)
CoreLibrary.Extension2 (references CoreLibrary as project reference)
...
There might be more of these extension libraries in the near future

到目前为止,我总是在 Visual Studio 中手动对它们进行版本控制(每当我需要更新版本时,在 AssemblyInfo.cs 中手动设置正确的值)并在每个项目中使用批处理文件来将该特定库打包并推送到 NuGet。

但现在我最近开始研究 VSTS,我的下一个任务是尽可能自动化构建和发布,同时使用自动版本控制。我偶然发现了 Git我认为对最后一部分有很大帮助的版本。

但是,这是但是。如果我理解正确,GitVersion 在存储库级别运行,因此由 GitVersion 计算的给定 semver 版本适用于存储库中的所有 assemblies/libraries,对吗?

那么您对这些库的发布和版本控制策略有何建议?

1) 像现在一样将所有内容保存在一个解决方案和存储库中,每当需要发布的一个包中发生更改时(比如 CoreLibrary.Extension1),这也会为所有其他库生成一个 NuGet 包。因此,如果所有包都在 1.0.0 上,并且其中一个包有一个小的变化,它们就会全部升级到 v1.1.0 并且全部打包并推送?

2) 为每个项目创建一个 git 存储库,然后让 GitVersion 在每个存储库上分别发挥其魔力。在扩展库中通过 NuGet 引用 CoreLibrary。

选项 2 是我认为最干净的,其优点是版本控制和打包是按项目处理的,但在维护它们方面可能对工作量来说太过分了,尤其是考虑到我是唯一的开发人员这一事实这些图书馆。

你有什么想法?给定上下文你会选择哪个选项?我是否错过了任何其他可能值得考虑的选择?

设置我在自动化构建和发布中的第一步,因此非常欢迎任何建议。

谢谢

我强烈建议不要在这里使用任何 nuget 包。 Nuget 旨在作为一种管理软件项目 third-party 依赖项的方式,而不是作为一种管理您定期构建的互连代码的方式。为此,您最好拥有一个存储库、一个 visual studio 解决方案和一个 build/deploy 来自的构建堆栈。

如果一定要用Nuget,就打一个单一版本的包。

你至少要考虑这两个因素:

  1. 维护多个 repo's/branches 和发布流需要付出努力。
  2. 当您仅对一个或一小部分库进行小的或大的更改时,您的客户需要付出的潜在努力。

当一个项目很小并且只有一个开发人员在处理它时,完全在一个存储库中工作并为所有版本剪切一个包通常会更容易。然而,即使对于单个开发人员来说,这也不会随着库的数量很好地扩展。一方面,VS 并不是特别擅长处理大型项目,尽管随着时间的推移,它确实在这方面不断改进。即便如此,实际限制仍然存在,但单个开发人员不太可能在不到几年的时间内达到足以达到该限制的生产力。

最终,即使是单个开发人员,通常也希望获得足够的成功,从而需要在开发方面或支持客户方面实现规模化。考虑一下当重要客户发现扩展 1 中的错误时,通过对扩展 2 进行一些主要工作而成为 half-way 的影响。现在你需要 check-out 一个更早的提交,产生一个快速修复,剪切一个新包,测试,rinse/repeat,发布,return 到你的 repo 的头部,cherry-pick错误修复,然后继续。如果您一直在不同的存储库中工作,甚至在同一个存储库中的分支机构中工作,则该任务更容易组织并在第一次尝试时就做好。

关于您假设每个 Nuget 包或 Git 版本 "operates at the repository level" 需要单独的回购协议,现在我有一个要点。通常,大多数文档和几乎所有示例都可以满足单一 product/package/repo 格式,在大多数情况下我可能会建议这样做,但实际上这并不是一个硬性要求。 Git分支级别的版本功能,如果不是不同的回购,你绝对应该在不同分支中为不同的库进行开发。拥有一个 master 分支来合并所有内容,可能也是一个好主意,但 Git 或 Git 版本甚至不需要 master 。您可以在单个 git 存储库中拥有多个 VS 解决方案和项目,并且可以从中生成多个 nuget 包。我不是说你应该这样做,我是说这不是一种罕见的做法,至少对于 non-trivial 产品线而言。

在客户方面,这在很大程度上取决于您产品的性质。所有的扩展对每个客户都是必要的,甚至是有用的吗?您会为早期采用者制作 alpha/beta 版本吗?您的代码是否在服务器上使用?它是在移动设备上使用的吗?通常,您不希望服务器上任何 运行 代码的升级时间过长,因此您应该认真考虑将您的产品线分解为多个独立版本的包。过去,客户端在这方面并不那么重要,但在移动设备上,下载时间成为一个主要因素。不是每个人都可以使用无限的免费下载带宽,因此成本可能是一个主要因素。

如果您要制作大量预发行版,您可能希望将产品线分成单独的包。您仍然可以生成一个包的包,但最终您将需要该选项,以在模块级别发送更新。

一旦您沿着 repo/project/package/release-stream 这条路走下去,您将很快开发出帮助维护它所需的自动化。这就像干净的编码实践,刚开始时有点痛苦,但它最终会成为第二天性,并且 pay-off 线下可能是巨大的。请记住,您没有任何理由不能拥有多个带有自己的解决方案和项目的回购协议,并且在父目录的上一级有一个 VS 解决方案,这为您提供了一个完全集成的构建。只需将其视为构建系统的层次结构即可。您只需要学习如何使用 .gitignore 文件或 git sub-modules(我更喜欢前者,因为后者的工具较弱)。