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

Jon*_*ter 64 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构建和部署新的nuget包
  7. 现在打开A并更改对B和nuget更新包的引用
  8. 在A中进行更改以符合B中的更改(并且可传递C)

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

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

Pet*_*rik 40

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

  • 有一个内部NuGet存储库,用于存放公司的所有已发布包.此存储库只是我们其中一台服务器上的共享目录.
  • 每个开发人员可以在自己的计算机上拥有(但不需要)一个或多个目录,这些目录充当本地NuGet包存储库.通过使用特定于用户的NuGet 配置,开发人员可以控制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>
    
    Run Code Online (Sandbox Code Playgroud)
  • 所有解决方案都启用了自动包恢复,因此我们不必将包提交到我们的版本控制系统.

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

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

  1. 对基础库进行更改(A).如果需要,更新(A)的版本.
  2. 运行MsBuild脚本来构建二进制文件并创建(A)的NuGet包
  3. 将新的NuGet包复制到本地计算机上的包存储库中
  4. 在依赖项目(B)中升级到刚刚放置在本地机器包存储库中的(A)新包(其应该比公司范围存储库或NuGet.org上的可用版本更高)
  5. 对(B)进行更改.

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

一旦更改完成,我们就:

  1. 将更改提交到(A).构建服务器将运行集成构建以验证一切正常.
  2. 告诉构建服务器运行发布版本,它构建二进制文件并将NuGet包推送到公司范围的NuGet存储库.
  3. 在(B)中,升级到最新版本的(A)(应该具有比测试包更高的版本号,因为测试包应该具有版本abc0,而在公司范围的存储库中的新构建版本应该是abc where> 0
  4. 将更改提交到(B).等待构建服务器完成集成测试
  5. 告诉构建服务器运行(B)的发布版本.

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

  1. 对基础库进行更改(A).如果需要,更新(A)的版本.
  2. 构建二进制文件
  3. 将二进制文件复制到NuGet解包项目(B)的(A)包的位置(例如c:\mysource\projectB\packages\ProjectA.1.2.3.4)
  4. 对项目进行必要的更改(B)

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

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

  • 开发的第三种方法可能是使用http://nugetreferenceswitcher.codeplex.com VS扩展,它会自动将NuGet引用切换到项目引用并返回... (2认同)

Mat*_*ton 7

你有两个选择:

  1. 在您的组织中运行NuGet Gallery的实例.这是运行nuget.org的代码
  2. 获取Artifactory Pro的许可证,该许可证具有内置的Nuget支持并充当Nuget存储库.

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

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

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

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

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

但是,如果你必须经常进行构建"舞蹈",你也应该质疑你的包分离是否真的合适,因为这表明所有代码应该在一个包中,或者可能在不同的包中分开.一个明确的包的一个主要特点是,它应该不会造成其他的包涟漪效应,肯定不是,如果你正在使用语义版本有效.

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

  • TeamCity还具有充当Nuget仓库的能力.http://www.developerfusion.com/article/144809/continuous-integration-using-nuget-and-teamcity/ (2认同)
  • "你不应该使用nuget.org"他从未说过他正在使用官方画廊,使你的答案的主要部分完全没用. (2认同)