首页 文章

我应该如何使用Nuget进行内部企业开发?

提问于
浏览
59

我们使用Nuget进行内部开发,以便我们跨团队共享代码 . 然而,当一个人正在处理将同时跨多个nuget包部署的代码时,我们会遇到问题 . 例如

A取决于B,它取决于C.

A,B和C将他们的工件推送到Nuget,这就是我们如何管理A,B和C之间的依赖关系 . 我们发现的问题是,如果开发人员想要在C中进行更改并快速看到这些更改反映在A中,他们会必须经历以下过程 .

  • 在C中进行更改

  • 将更改推送到git

  • CI获取对C的更改并构建和部署新的nuget包 .

  • 进入B并使用nuget update package命令更新对C的引用 .

  • 将更改推送到packages.config文件,最多为git

  • CI获取B的更改,并为B构建和部署新的nuget包

  • 现在打开A并更改对B和nuget更新包的引用

  • 在A中进行更改以与B中的更改一起(并且可传递地为C)

这似乎非常痛苦,并且导致我们的一些开发人员质疑我们内部开发的代码对Nuget的选择 . 每个人都喜欢使用外部包 .

内部使用Nuget有更好的工作流程吗?

4 回答

  • 7

    在我们公司,我们通过以下设置解决了级联更新问题 . 首先,我们为NuGet存储库和构建服务器提供以下设置 .

    • 有一个内部NuGet存储库,用于存放公司的所有已发布包 . 此存储库只是我们其中一台服务器上的共享目录 .

    • 每个开发人员可以在自己的计算机上拥有(但不需要)一个或多个目录作为本地NuGet包存储库 . 通过使用特定于用户的NuGet configuration,开发人员可以控制NuGet在包存储库中搜索的顺序以查找包 .

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <packageRestore>
        <add key="enabled" value="True" />
      </packageRestore>
      <packageSources>
        <add key="Dev" value="D:\dev\testpackages" />
        <add key="Company" value="<UNC_ADDRESS_COMPANY_REPOSITORY>" />
        <add key="NuGet official package source" value="https://nuget.org/api/v2/" />
      </packageSources>
      <disabledPackageSources />
      <activePackageSource>
        <add key="All" value="(Aggregate source)" />
      </activePackageSource>
    </configuration>
    
    • 所有解决方案都启用了自动包恢复,因此我们不必将包提交到我们的版本控制系统 .

    • 开发人员仅控制4个版本号中的3个,例如如果版本是 <MAJOR>.<MINOR>.<BUILD>.<REVISION> ,那么开发人员只能更改主编号,次编号和编号,修订号设置为0,除非在构建服务器完成的构建中,它是构建的内部版本号 . 这很重要,因为它意味着对于由主要版本,次要版本和内部版本号组成的给定版本,构建服务器将始终生成更高版本号 . 这再次意味着NuGet更愿意采用来自公司软件包存储库的软件包版本(仅通过构建服务器获取软件包) .

    为了对其中一个基本库进行更改,使用了两种可能的过程 . 第一个过程是:

    • 对基础库进行更改(A) . 如果需要,更新(A)的版本 .

    • 运行MsBuild脚本以构建二进制文件并创建(A)的NuGet包

    • 将新的NuGet包复制到本地计算机上的包存储库

    • 在依赖项目(B)中升级到刚刚放置在本地计算机软件包存储库中的(A)新软件包(其版本应高于公司范围存储库或NuGet.org上可用的版本)

    • 对(B)进行更改 .

    如果(A)需要进行更多更改,则重复步骤1,2和3,然后从(B)的工作目录中删除(A)的包 . 下次构建运行时,NuGet将寻找(A)的特定版本,在本地机器存储库中找到它并将其拉回 . 注意NuGet cache可能会在某些时候阻止此过程,尽管它看起来像NuGet可能不缓存来自同一台机器的软件包(?) .

    一旦更改完成,我们就:

    • 将更改提交到(A) . 构建服务器将运行集成构建以验证一切正常 .

    • 告诉构建服务器运行发布版本,它构建二进制文件并将NuGet包推送到公司范围的NuGet存储库 .

    • 在(B)中,升级到最新版本的(A)(版本号应该比测试包更高,因为测试包应该具有版本abc0,而公司范围的存储库中的新版本应该是abc其中> 0

    • 将更改提交到(B) . 等待构建服务器完成集成测试

    • 告诉构建服务器运行(B)的发布版本 .

    进行开发工作的另一种方法是采取以下步骤

    • 对基础库进行更改(A) . 如果需要,更新(A)的版本 .

    • 构建二进制文件

    • 将二进制文件复制到NuGet解包项目(B)的(A)包的位置(例如 c:\mysource\projectB\packages\ProjectA.1.2.3.4

    • 对项目进行必要的更改(B)

    提交过程仍然相同,项目(A)需要首先提交,而在项目(B)中,需要升级对(A)的NuGet引用 .

    第一种方法稍微整洁,因为如果(A)的NuGet包中存在故障(例如忘记添加新的组件),此过程也会发出警告,而在第二个过程中,开发人员在包装之后才会知道(A) )已经出版 .

  • 0

    你有两个选择:

    • 在您的组织内运行NuGet Gallery的实例 . 这是运行nuget.org的代码

    • 获取Artifactory Pro的许可证,该许可证具有内置的Nuget支持并充当Nuget存储库 .

    我已经使用了两者,#1是一个合理的选择,但NuGet Galley针对nuget.org进行了优化和设计,而不是内部部署/企业使用,因此删除软件包这样的事情很痛苦(需要手动编写SQL) ) .

    我要说你应该支付Artifactory Pro的(低)许可费 - 这是一个很好的产品,JFrog团队非常热衷于开启 .

    您不应该将nuget.org用于内部/企业包; nuget.org是为第三方/开源库而设计的,而不是内部构建依赖项 .

    EDIT :就工作流而言,为什么要将 shared 代码放入多个包中?如果代码需要共享,则需要进入自己独立的包中 .

    EDIT 2 :为了加快开发人员的代码更改工作流程,您可以使用 nuget.exe (命令行客户端)并使用命令行可访问的构建,因此您可以定位"developer"构建运行 . 然后在您的"developer"构建(而不是CI构建)中,当您想要将新更新的 B 作为依赖项并将其构建时,将-Source指定为本地路径(例如 nuget install B -Source C:\Code\B );同样适用于 C 或其他本地新更新的包 . 然后当 ABC 都构建正常时,你可以 git push 所有这些(以反向依赖顺序),并让CI做它的事情 .

    However ,你也应该质疑你的包分离是否真的合适,如果你必须经常进行这种构建'dance',因为这表明所有代码应该在一个包中,或者可能在不同的包中分开 . 定义良好的包的一个关键特性是它不应该对其他包产生连锁反应,当然如果你有效地使用Semantic Versioning则不会 .

    Edit 3 marcelo-oliveira要求的一些说明:"command-line accessible builds"是完全可以从命令行进行的构建,而不使用Visual Studio,通常是通过批处理文件 . "developer build"是开发人员从她的工作站运行的构建,而不是在CI服务器上运行的CI构建(两个构建应该基本相同) .

  • 2

    If A, B and C are under the same solution ,您可以在单个版本中为它们创建NuGet包 .

    只需确保using包具有新版本号(假设您的构建不会随机更改它)所依赖的包 .

    If A, B and C are intentionally under different solutions 例如A是基础架构解决方案而B是产品解决方案,那么我唯一的建议就是在签入时定义您的CI构建,而不是定期 .

    Edit:

    另一种选择是在本地构建期间向NuGet服务器创建push pre-release packages (例如版本1.0.0-alpha),这样开发人员可以在创建发布版本之前尝试使用该包 .

  • 38

    Nuget旨在分享第三方图书馆 . 我们计划在内部使用Nuget来处理可以在项目之间共享的所有公共代码 . 像公共数据层,字符串和其他正则表达式函数,电子邮件组件和其他类似的工件 .

    我认为Nuget有任何帮助的唯一方法是,您在团队/项目中共享的组件,代码或工件是稳定的,并且具有与项目的发布周期不同的自己的发布周期 . 为了您的需要Nuget是一个矫枉过正 . 在同一解决方案中,您可以更好地连接所有此类项目 . 您的解决方案结构应包括三个项目A,B和C作为需要时在内部引用的依赖项目 .

相关问题