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


85

我一直在处理我公司的CI扩展问题,同时试图弄清楚在CI和多个分支机构中采用哪种方法。在stackoverflow,多个功能分支和持续集成方面存在类似的问题。我开始了新的话题,因为我想进行更多的讨论并对该问题进行一些分析。

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

因此,如果我想为开发人员提供用于其自定义分支的CI,则我需要Jenkins的特殊工具(API或Shellscript或其他东西?)并进行缩放。或者,我可以告诉他们更多地合并到DEV并在定制分支上不使用CI地生活。您会选择哪一个?或者还有其他选择?

Answers:


69

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

执行真实的CI意味着您所有的开发人员都将定期提交主线。说起来容易,但难的是要做到这一点而不会破坏您的应用程序。我强烈建议你看看持续交付,尤其是使你的应用程序可释放在第13章:管理组件和依赖。要点如下:

  • 隐藏新功能,直到完成为止(又称为Feature Toggles)。
  • 以一系列小更改为增量进行所有更改,每个小更改都是可发布的。
  • 使用抽象分支来对代码库进行大规模更改。
  • 使用组件解耦应用程序中以不同速率变化的部分。

除了通过抽象进行分支外,它们非常容易解释。这只是一个花哨的名词:

  1. 在您需要更改的系统部分上创建一个抽象。
  2. 重构系统的其余部分以使用抽象层。
  3. 创建一个新的实现,直到完成,该实现才成为生产代码路径的一部分。
  4. 更新您的抽象层以委托给新的实现。
  5. 删除旧的实现。
  6. 如果不再合适,请删除抽象层。

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

与创建分支机构并投入工夫重新架构和开发新功能相比,渐进式方法无疑需要更多的纪律和关怀-实际上确实需要更多的创造力。但这大大降低了更改破坏应用程序的风险,并将为您和您的团队节省大量时间,以解决合并问题,并使应用程序进入可部署状态。

放弃功能分支需要花费很多心思,您将始终会遇到阻力。以我的经验,这种抵制是基于开发人员对主线提交代码感到不安全,这是一个合理的考虑。反过来,这通常是由于缺乏对上述技术的知识,信心或经验,并且可能是由于对自动化测试缺乏信心。前者可以通过培训和开发人员支持来解决。后者是一个非常困难的问题,但是分支并不能提供任何额外的实际安全性,它只是推迟了这个问题,直到开发人员对代码有足够的信心为止。


4
汤姆(Tom),只有在1)发行和更新都相对容易2)大部分变更都被隔离的情况下,这种方法才能很好地工作。对于Web开发人员而言,这是正确的,但是如果您要进行盒装产品发布,则必须不惜一切代价保持稳定的版本稳定,这会导致修补程序确实非常昂贵,甚至在大型公司环境中也不可能。
Jevgeni Kabanov 2011年

13
真正的CI不仅与集成有关,而且还与反馈有关
Anton Arhipov 2011年

3
我选择了这个作为答案(至少给予了赏金,如果我仍然需要将其标记为正确,请告诉我),但是我认为这不是解决我的问题的方法。我已经在zeroturnaround.com/blog/…上
toomasr 2011年

1
@Jevgeni Kabanov和@toomasr你们俩似乎都认为执行真正的CI意味着放弃质量,并且仅适用于Web开发人员,因为它很容易推出修复程序。我猜您担心的是发布之前的狡猾提交。是的,这可能会导致发行版本不正确,而且修复成本可能很高。但是,在功能分支发布之前就对它进行狡猾的提交同样糟糕。如果您觉得有所不同,请分享您的理由。解决此问题的一种方法(如果提交是提交给主线或功能分支)是使用持续交付方法。
汤姆·霍华德

1
哦,还有BTW,在过去的四年中,我的主要开发经验是在金融机构。拥有稳定的发行版本和解决错误的代价(更不用说您需要通过发布变更补丁程序来发布修补程序的代价)所带来的好处远不止于此。盒装产品对我来说将是一个轻松的变化。
汤姆·霍华德

4

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

如果您担心CI服务器上的负载,则可以设置CI的单独实例甚至单独的从属,以帮助平衡多台服务器上的负载。确保正在运行Hudson / Jenkins的服务器足够。我使用过Apache Tomcat,只是必须确保它具有足够的内存和处理能力来处理构建队列。

重要的是要清楚要使用CI实现的目标,然后找出一种无需大量人工或重复就可以实施的方法。使用其他由CI服务器执行的外部工具或脚本没有问题,这些工具或脚本有助于简化整体构建管理过程。


我认为缺少工具意味着该部门中仍有一些插件/产品的空间。不想写我自己的。
toomasr 2011年

1
Jenkins的实用程序可以自动为每个分支创建构建配置:entagen.github.com/jenkins-build-per-branch
kolen 2012年

3

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


我是否会因为缺乏管理多个分支机构的工具而在云上交易而遇到同样的问题?我的意思是我现在可以管理负载,但仍然不能管理分支?
toomasr 2011年

我的意思是忘记工具并在开发人员之间分配管理权-“如果您想要自定义个人版本,这是您的CB帐户”。不影响主服务器的构建性能。尽管他们的API非常简单,但是创建管理实用程序大概需要一到两周的时间,然后您就可以在其中进行任何操作。像平常一样,如果您想要一些特别的东西,最好自己动手做。同时,他们正在快速成长并在听取社区的意见,因此请填写功能要求,并可能很快就会出现。
Anton Safonov

哦,明白了。告诉分支所有者樱桃选择他感兴趣的工作,并根据需要将其设置为自定义分支。我喜欢这个主意。
toomasr 2011年

1

实际上,真正存在问题的是带有功能分支的构建隔离。在我们公司中,我们有一组单独的Maven项目,它们都是较大发行版的一部分。这些项目由不同的团队维护,但是对于每个发行版,所有项目都需要发布。现在,一个功能分支可能从一个项目重叠到另一个项目,这就是构建隔离变得很痛苦的时候。我们尝试了几种解决方案:

  • 在每个功能分支的关系中创建单独的快照存储库
  • 在专用奴隶上共享本地存储库
  • 对上游存储库使用repository-server-plugin
  • 通过一个私有存储库在一件事中构建全部内容

实际上,最后的解决方案是最有前途的。所有其他解决方案都缺乏一种或另一种方式。与job-dsl插件一起,可以轻松设置新功能分支。只需复制并粘贴groovy脚本,调整分支并让种子作业创建新作业。确保种子作业删除了非托管作业。然后,您可以轻松地在不同的Maven项目上使用要素分支进行缩放。

但是正如汤姆在上面所说的那样,最好克服功能分支的必要性,并教开发人员进行干净的集成,但这是一个更长的过程,而且对于许多不再需要使用的遗留系统部件,结果尚不清楚。

我的2美分

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.