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

我一直在处理在公司扩展CI的问题,同时试图找出CI和多个分支机构采用哪种方法。 在stackoverflow, 多个function分支和持续集成有一个类似的问题。 我已经开始了一个新的,因为我想在这个问题上进行更多的讨论并提供一些分析。

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

  • 每个分支有多套工作(在这里谈论Jenkins / Hudson)
    • 编写工具来pipe理额外的工作
      • 批量创build/修改/删除作业
      • 每个分支的每个作业的自定义设置(SCM url,deppipe理repos重复)
      • 人们用shell工具,ant脚本和Jenkins CLI解决这个问题的一些例子。 看到:
        1. http://jenkins.361315.n4.nabble.com/Multiple-branches-best-practice-td2306578.html
        2. http://jenkins.361315.n4.nabble.com/Is-it-possible-to-handle-multiple-branches-where-some-jobs-should-run-on-each-one-without-duplicatin-td954729。 HTML
        3. http://jenkins.361315.n4.nabble.com/Parallel-development-with-branches-td1013013.html
        4. 自动configuration或创build哈德森作业
    • 会在您的CI群集上造成更多负载
    • 开发人员的反馈周期变慢(如果基础架构无法处理新的负载)
  • 每2个分支的多组作业(开发和稳定)
    • 手动pipe理这两套(如果您更改工作的configuration,那么一定要在另一个分支中更改)
      • 皮塔什,但至less很lesspipe理
    • 其他额外的分支在推送到开发之前将不会得到完整的testing套件
    • 不满意的开发者。 为什么开发人员应该关心CI缩放问题? 他有一个简单的请求,当我分支我想testing我的代码。 简单。

所以看来,如果我想为他们自己的定制分支提供CI的开发人员,我需要Jenkins(API或shellcripts或其他?)的特殊工具,并处理缩放。 或者我可以告诉他们更经常地合并到DEV,并且在定制分支上没有CI。 你会采取哪一个或有其他的select?

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

执行真正的CI意味着您的所有开发人员都定期进入主线。 容易说,但难的部分是这样做,而不会破坏你的应用程序。 我强烈build议您查看持续交付 ,特别是第13章:pipe理组件和依赖项中保持应用程序可释放部分。 要点是:

  • 隐藏新的function,直到完成(AKA function切换 )。
  • 逐步进行所有更改,作为一系列小的更改,每个更改都是可释放的。
  • 使用抽象分支对代码库进行大规模更改。
  • 使用组件来分离应用程序中以不同速率更改的部分。

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

  1. 在需要更改的系统部分创build一个抽象。
  2. 重构系统的其余部分以使用抽象层。
  3. 创build一个新的实现,这是不完整的生产代码path的一部分。
  4. 更新您的抽象层以委托给您的新实现。
  5. 删除旧的实现。
  6. 如果抽象层不再合适,则移除抽象层。

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

渐进的方法当然需要更多的纪律和关怀 – 甚至更多的创造力 – 比创build一个分支机构和潜水工具来重新devise和开发新的function。 但是,它大大降低了更改中断应用程序的风险,并且可以帮助您和您的团队大量合并,修复破坏,并使您的应用程序进入可部署状态。

放弃特征分支需要相当的思维转换,并且总是会遇到阻力。 以我的经验来看,这种阻力是基于开发人员感觉不到安全的代码,而这是一个合理的担忧。 这反过来通常是由于缺乏对上述技术的知识,信心或经验,可能是因为对自动化testing缺乏信心。 前者可以通过培训和开发人员支持来解决。 后者是一个更难处理的问题,但是分支并没有提供任何额外的真正的安全性,它只是推迟了这个问题,直到开发人员对代码足够自信。

我会为每个分支机构设置单独的工作。 我之前做过这个,如果你正确设置了Hudson / Jenkins,pipe理和设置并不困难。 创build多个作业的快速方法是从具有相似需求的现有作业中进行复制,并根据需要对其进行修改。 我不确定是否要让每个开发人员为自己的分支机构设置自己的工作,但是要pipe理一个人(即,构build经理)并不需要很多工作。 一旦自定义分支合并到稳定分支中,相应的作业可以在不再需要时被删除。

如果您担心CI服务器上的负载,则可以设置CI的单独实例,甚至可以将独立的从站设置为帮助平衡多个服务器之间的负载。 确保运行Hudson / Jenkins的服务器已经足够。 我已经使用了Apache Tomcat,并且必须确保它有足够的内存和处理能力来处理构build队列。

清楚你想用CI来达到什么目标,然后想出一个方法来实现它,而不需要人工或重复。 使用由CI服务器执行的其他外部工具或脚本没有任何问题,这有助于简化整个构buildpipe理过程。

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

其实真正有问题的是build立与function分支的隔离。 在我们公司,我们有一套独立的maven项目,这些项目都是大型分销的一部分。 这些项目由不同的团队维护,但对于每个分配,所有项目都需要发布。 一个特征分支现在可能会从一个项目重叠到另一个,那么当构build隔离变得痛苦的时候。 我们尝试了几种解决scheme:

  • 在每个function分支的联结中创build单独的快照存储库
  • 共享专用从站上的本地存储库
  • 使用存储库服务器插件与上游存储库
  • 使用一个私有存储库在一个作业中构build所

事实上,最后的解决scheme是最有前途的。 所有其他解决scheme缺乏这样或那样的方式。 与job-dsl插件一起,很容易build立一个新的function分支。 只需复制和粘贴groovy脚本,调整分支,让种子工作创造新的工作。 确保种子作业删除不受pipe理的作业。 然后,您可以轻松地通过不同的Maven项目来调整function分支。

但是正如汤姆在上面所说的那样,克服function分支和教导开发人员整合的必要性会更好,但这是一个更长的过程,结果并不清楚,许多遗留系统部分你不会再触及。

我的2美分