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

时间:2013-08-07 20:30:58

标签: nuget

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

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

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

  1. 在C中进行更改。
  2. 将更改推送到git
  3. CI获取对C的更改并构建和部署新的nuget包。
  4. 进入B并使用nuget update package命令更新对C的引用。
  5. 将更改推送到packages.config文件,直到git
  6. CI获取B的更改,并为B
  7. 构建和部署新的nuget包
  8. 现在打开A并更改对B和nuget update package的引用
  9. 在A中进行更改以与B中的更改(以及可传递的C)
  10. 一起进行

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

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

4 个答案:

答案 0 :(得分:39)

在我们公司,我们通过以下设置解决了级联更新问题。首先,我们为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更愿意接受来自公司软件包存储库的软件包版本(只能通过构建服务器获取软件包)。

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

  1. 对基础库进行更改(A)。如果需要,更新(A)的版本。
  2. 运行MsBuild脚本以构建二进制文件并创建(A)
  3. 的NuGet包
  4. 将新的NuGet包复制到本地计算机上的包存储库
  5. 在依赖项目(B)中升级到刚刚放置在本地计算机软件包存储库中的(A)新软件包(其版本应该比公司范围的存储库或NuGet上的版本更高)。 ORG)
  6. 对(B)进行更改。
  7. 如果(A)需要进行更多更改,则重复步骤1,2和3,然后从(B)的工作目录中删除(A)的包。下次构建运行时,NuGet将寻找(A)的特定版本,在本地机器存储库中找到它并将其拉回。注意NuGet cache可能会在某些时候阻止此过程,尽管它看起来NuGet可能不会缓存来自同一台机器的软件包(?)。

    更改完成后,我们:

    1. 将更改提交到(A)。构建服务器将运行集成构建以验证一切正常。
    2. 告诉构建服务器运行发布版本,它构建二进制文件并将NuGet软件包推送到公司范围内的NuGet存储库。
    3. 在(B)中,升级到最新版本的(A)(应该具有比测试包更高的版本号,因为测试包应该具有版本abc0,而公司范围的存储库中的新版本应该是abc,其中&gt; 0
    4. 将更改提交到(B)。等待构建服务器完成集成测试
    5. 告诉构建服务器运行(B)的发布版本。
    6. 进行开发工作的另一种方法是采取以下步骤

      1. 对基础库进行更改(A)。如果需要,请更新(A)的版本。
      2. 构建二进制文件
      3. 将二进制文件复制到NuGet解包项目(B)的(A)包的位置(例如c:\mysource\projectB\packages\ProjectA.1.2.3.4
      4. 对项目(B)进行必要的更改
      5. 提交过程仍然相同,项目(A)需要首先提交,而在项目(B)中,需要升级NuGet对(A)的引用。

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

答案 1 :(得分:7)

你有两个选择:

  1. 在您的单位内运行NuGet Gallery的实例。这是运行nuget.org的代码
  2. 获取Artifactory Pro的许可证,该许可证具有内置的Nuget支持并充当Nuget存储库。
  3. 我已经使用了两者,#1是一个合理的选择,但是NuGet Galley针对nuget.org进行了优化和设计,而不是内部部署/企业使用,所以删除软件包这样的事情很痛苦(手工需要滚动SQL)。

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

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

    编辑:就工作流而言,为什么要将共享代码放入多个包中?如果代码需要共享,则需要使用自己独立的包。

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

    然而,你也应该质疑你的包分离是否真的合适,如果你必须经常进行这种构建'舞蹈',因为这表明所有代码应该在一个包中,或者可能在不同的包中分开不同的行。明确定义的软件包的一个关键特性是会导致其他软件包产生连锁反应,如果您有效使用Semantic Versioning,则肯定不会。

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

答案 2 :(得分:2)

如果A,B和C属于同一解决方案,您可以在一个版本中为它们创建NuGet包。

只需确保using软件包具有所依赖的软件包的新版本号(假设您的版本不会随机更改)。

如果A,B和C故意处于不同的解决方案,例如A是基础架构解决方案而B是产品解决方案,那么我唯一的建议是在登记时定义您的CI构建,而不是定期。


修改

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

答案 3 :(得分:0)

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

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