在持续集成中处理多个分支

时间:2011-04-10 11:14:58

标签: continuous-integration hudson jenkins

我一直在处理在我的公司扩展CI的问题,同时试图找出在CI和多个分支机构中采用哪种方法。 stackoverflow上有一个类似的问题Multiple feature branches and continuous integration。我已经开始了一个新的,因为我想进一步讨论并在问题中提供一些分析。

到目前为止,我发现我可以采取两种主要方法(或者其他一些方法)。

所以,如果我想为他们自己的自定义分支提供开发人员,我需要Jenkins的特殊工具(API或shellcripts或其他什么?)并处理扩展。或者我可以告诉他们更频繁地合并到DEV并且在自定义分支上没有CI。您会选择哪一个或有其他选择?

4 个答案:

答案 0 :(得分:69)

当您谈到扩展CI时,您真正在谈论扩展CI服务器的使用,以便与主线一起处理所有功能分支。最初,这看起来是一种很好的方法,因为分支中的开发人员可以获得CI作业所包含的自动化测试的所有优势。但是,您在管理CI服务器作业时遇到了问题(就像您发现的那样),更重要的是,您并没有真正使用CI。是的,您正在使用CI服务器,但您没有持续集成所有开发人员的代码。

执行真实CI意味着您的所有开发人员都定期向主线提交。很容易说,但困难的部分是在不破坏您的应用程序的情况下这样做。我强烈建议您查看Continuous Delivery,尤其是第13章:管理组件和依赖关系中的保持应用程序可释放部分。要点是:

  
      
  • 隐藏新功能直至完成(A.K.A Feature Toggles)。
  •   
  • 逐步进行所有更改,作为一系列小的更改,每个更改都是可释放的。
  •   
  • 使用逐个分支来对代码库进行大规模更改。
  •   
  • 使用组件将应用程序中以不同速率更改的部分分离。
  •   

它们非常自我解释,除了抽象分支。这只是一个奇特的术语:

  
      
  1. 在您需要更改的系统部分上创建抽象。
  2.   
  3. 重构系统的其余部分以使用抽象层。
  4.   
  5. 创建一个新实现,该实现在完成之前不是生产代码路径的一部分。
  6.   
  7. 更新您的抽象层以委托您的新实施。
  8.   
  9. 删除旧的实现。
  10.   
  11. 如果不再合适,请删除抽象层。
  12.   

第14章:高级版本控制分支,流和持续集成部分的以下段落总结了这些影响。

  

增量方法当然需要更多的纪律和关注 - 实际上更多的创造力 - 而不是创建一个分支和潜水重新构建和开发新功能。但它可以显着降低您的更改破坏应用程序的风险,并将为您和您的团队节省大量时间合并,修复破坏并使您的应用程序进入可部署状态。

放弃功能分支需要相当大的思维转变,你总会遇到阻力。根据我的经验,这种阻力是基于开发人员不能安全地将代码提交给主线,这是一个合理的问题。这反过来通常源于缺乏对上述技术的知识,信心或经验,并且可能对您的自动化测试缺乏信心。前者可以通过培训和开发人员支持来解决。后者是一个难以处理的问题,但是分支并没有提供任何额外的真正安全性,它只是推迟了问题,直到开发人员对他们的代码充满信心。

答案 1 :(得分:4)

我会为每个分支设置单独的工作。我以前做过这个,如果你正确设置了Hudson / Jenkins,就不难管理和设置。创建多个作业的快捷方法是从具有类似要求的现有作业进行复制,并根据需要进行修改。我不确定您是否希望允许每个开发人员为自己的分支机构设置自己的工作,但是对于一个人(即构建管理员)来说管理起来并不多。将自定义分支合并到稳定分支后,可以在不再需要时删除相应的作业。

如果您担心CI服务器上的负载,您可以设置CI的单独实例,甚至可以设置单独的从服务器,以帮助平衡多个服务器之间的负载。确保运行Hudson / Jenkins的服务器足够。我已经使用过Apache Tomcat,只需要确保它有足够的内存和处理能力来处理构建队列。

重要的是要明确您希望使用CI实现什么,然后找出一种实现它的方法,而无需太多的手动操作或重复。使用CI服务器执行的其他外部工具或脚本有助于简化整个构建管理过程。

答案 2 :(得分:3)

我会选择开发+稳定分支。如果你仍然想要自定义分支并且担心负载,那么为什么不将这些自定义分支移动到云中并让开发人员自己管理它,例如http://cloudbees.com/dev.cb 这是Kohsuke现在所在的公司。 还有一个Eclipse Tooling,所以如果你在Eclipse上,你会将它紧密地集成到dev env中。

答案 3 :(得分:1)

实际上真正有问题的是使用功能分支构建隔离。在我们公司,我们有一套独立的maven项目,都是更大的分销项目的一部分。这些项目由不同的团队维护,但是对于每个分发,所有项目都需要发布。现在,一个featurebranch可能会从一个项目重叠到另一个项目,这就是构建隔离变得痛苦的时候。我们尝试了几种解决方案:

  • 在nexus中为每个功能分支创建单独的快照存储库
  • 在专用奴隶上共享本地存储库
  • 将repository-server-plugin与上游存储库一起使用
  • 使用一个私有存储库在一个作业内构建所有

事实上,最后的解决方案是最有希望的。所有其他解决方案都缺乏一种或另一种方式。与job-dsl插件一起,可以轻松设置新的功能分支。只需复制并粘贴groovy脚本,调整分支,让种子作业创建新的作业。确保种子作业删除非托管作业。然后,您可以使用不同maven项目上的功能分支轻松扩展。

但正如汤姆所说的那样,更好地克服功能分支的必要性并教导开发人员干净地整合,但这是一个更长的过程,并且结果不清楚许多遗留系统部件你不会接触更多。

我的2美分