单仓库中的软件包的独立版本控制

时间:2018-11-21 12:15:55

标签: c# git jenkins nuget versioning

我们刚刚开始研究可能最好描述为公司范围内的“开源”框架的事物。我们的主要语言是C#,我们使用Jenkins和ProGet来创建和共享nuget包。我们开始将所有内容(我的意思是一切。一个模块至少包含三个存储库)放入自己的Git存储库中。 我们认为这是一个好主意,因为我们可以分别对所有内容进行版本控制和发布,但是如果您要对具有依赖关系的多个存储库进行更改,结果将导致非常烦人的工作流程。

我开始四处张望,似乎,大多数项目使用的是更单一的方法,我认为这也可能使我们在这里的生活也更轻松。我不太确定的是,使用这种方法进行版本控制的方式。

CoreFx存储库是我们试图实现的一个很好的例子。一个回购导致产生许多单独的软件包。当我在本地构建此软件包时,所有软件包都有一个版本号,但是当我查看nuget.org上可用的软件包版本时,这些版本似乎是针对每个软件包的。例如,System.Diagnostics.DiagnosticsSource的版本为4.5.1,但引用的System.Diagnostics.Debug版本为4.3.0。

这正是我认为对我们来说是一个好的解决方案。一个仓库,很多带有独立版本的软件包。

有人知道corefx项目是如何实现的,或者有其他建议,可以怎么做?

1 个答案:

答案 0 :(得分:1)

monorepos和非常多的repos都有优点;许多小型存储库的优势示例之一是,您可以轻松git tag单个软件包的 specific 版本。有时候在monorepo中做同样的事情比较尴尬。

但是,如果您发布的内容更多是“一组相关的软件包”,那也许不是一个坏主意:您可以拥有一个.bat或{{ 1}}文件,该文件将为您的存储库构建所有NuGet软件包并相应地设置版本号。像this example(Powershell脚本)

您正在谈论的参考/依赖性(.ps1版本4.5.1,取决于System.Diagnostics.DiagnosticsSource版本4.3.0)将成为System.Diagnostics.Debug中的单独<dependency>标签“消费”程序包(在这种情况下,即.nuspec。)在这里,您可以选择两种主要策略:

  • 始终颠覆所有System.Diagnostics.DiagnosticsSource版本,以便“升级一个将升级所有”软件包。有时这就是您想要的,然后您应该这样做。
  • 更细粒度:仅当您以某种方式实际使用更新的功能时才更新依赖项。例如,当使用程序包使用仅存在于特定版本的依赖项中的方法时。

后一种策略可以说是更优雅的方法,但是也更复杂(可能需要更多的工作才能使它很好地完成)

.NET特定的挑战

  

假定我有项目A和项目B,它们对A都有引用,并且两者都在同一个存储库中。我还有一个针对项目B的Visual Studio解决方案,其中包含对项目A的项目引用。

     

现在,我对项目B进行更改,并增加其版本,而无需增加项目A的版本。我推送更改,詹金斯对仓库进行了干净签出,并创建了创建两个软件包的解决方案,但软件包A现在具有与先前版本相同的版本,无法推送到nuget提要

这确实是一个有趣的问题。一些可能的解决方法:

  • 让詹金斯(Jenkins)检测/确定更改之间的差异,并仅针对已更改的树的部分构建软件包。可能可行,但可能并不容易;在您的<dependency>脚本中需要一些逻辑。也许是我能想到的最优雅的解决方案。

  • 使NuGet推送由于“版本已存在”而失败,这是非致命错误。即如果发现该特定错误(非常重要的细节!),请检测何时运行.ps1并忽略它。您绝对不想忽略nuget push中的所有错误,而只忽略这些特定的错误。不太优雅,但仍然是全自动的。

  • 使发布包成为半自动而不是全自动进程。在Jenkins中设置一个或多个作业,当要发布新版本的软件包时,您可以手动“按一下按钮”,也许带有一个作业参数,说“要释放哪个软件包”(可能是Jenkins中的下拉菜单,所以没人听起来可能有点手工,但是这个选项可以使您作为一个团队,在什么时候推送什么软件包以及什么时候提供最大的 control 控制。

进一步阅读

(通常,关于monorepos,不专门处理您提到的CoreFx案例。尽管如此,它仍然可以提供有价值的信息。)