【问题标题】:Handling multiple branches in continuous integration在持续集成中处理多个分支
【发布时间】:2011-08-02 10:52:49
【问题描述】:

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

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

因此,如果我想为开发人员自己的自定义分支提供 CI,我需要为 Jenkins 提供特殊工具(API 或 shellscript 之类的?)并处理扩展。或者我可以告诉他们更频繁地合并到 DEV 并在自定义分支上不使用 CI。你会选择哪一个或有其他选择?

【问题讨论】:

    标签: continuous-integration hudson jenkins


    【解决方案1】:

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

    执行真正的 CI 意味着您的所有开发人员都定期致力于主线。说起来容易,但困难的部分是在不破坏您的应用程序的情况下做到这一点。我强烈建议您查看Continuous Delivery,尤其是第 13 章:管理组件和依赖项中的保持应用程序可发布部分。要点是:

    • 在完成之前隐藏新功能 (A.K.A Feature Toggles)。
    • 将所有更改作为一系列小更改逐步进行,每个更改都是可发布的。
    • 使用抽象分支对代码库进行大规模更改。
    • 使用组件来解耦以不同速率变化的应用程序部分。

    除了通过抽象分支外,它们非常易于解释。这只是一个花哨的术语:

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

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

    与创建分支并全力以赴重新架构和开发新功能相比,渐进式方法当然需要更多的纪律和关注——实际上也需要更多的创造力。但它显着降低了您的更改破坏应用程序的风险,并将为您和您的团队节省大量时间合并、修复损坏以及使您的应用程序进入可部署状态。

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

    【讨论】:

    • Tom,这只有在 1) 发布和更新都相对容易 2) 您的大部分更改都被很好地隔离时才有效。对于 Web 开发人员来说确实如此,但如果您正在发布盒装产品,那么稳定版本必须不惜一切代价保持稳定,因为在大型企业环境中修补程序非常昂贵甚至是不可能的。
    • 真正的 CI 不仅仅关乎集成,还关乎反馈
    • 我选择了这个作为答案(至少给了赏金,如果我仍然需要以某种方式将其标记为正确,请告诉我)但我认为这不是我的问题的解决方案。我已经在zeroturnaround.com/blog/… 写了一篇后续文章
    • @Jevgeni Kabanov 和@toomasr 你们俩似乎都认为做真正的 CI 意味着放弃质量,它只适用于 Web 开发,因为推出修复程序非常容易。我猜你担心的是在发布之前的一个狡猾的提交。是的,这可能会导致糟糕的发布,修复起来可能会很昂贵。然而,在功能分支发布之前,在功能分支上的狡猾提交同样糟糕。如果你觉得有区别,请分享你的推理。解决这个问题的一种方法(如果提交到主线或功能分支)是使用持续交付方法。
    • 哦,顺便说一句,在过去的 4 年里,我的主要开发经验一直在金融机构工作。拥有稳定版本的必要性和出错的成本(更不用说推出修补程序所需的更改控制过程)并没有比这大得多。盒装产品对我来说是一个轻松的改变。
    【解决方案2】:

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

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

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

    【讨论】:

    • 我认为缺乏工具意味着这个部门有一些插件/产品的空间。不想自己写。
    • Jenkins 有一个实用程序可以自动为每个分支创建构建配置:entagen.github.com/jenkins-build-per-branch
    【解决方案3】:

    我会选择 dev+stable 分支。如果您仍然想要自定义分支并且害怕负载,那么为什么不将这些自定义分支移动到云端并让开发人员自己管理它,例如http://cloudbees.com/dev.cb 这就是小介现在所在的公司。 还有一个 Eclipse Tooling,所以如果您使用 Eclipse,您可以将它紧密集成到开发环境中。

    【讨论】:

    • 我会因为缺乏管理多个分支机构的工具而在云端遇到同样的问题吗?我的意思是我现在可以管理负载但仍然不能管理分支?
    • 我的意思是忘记工具并在开发人员之间分配管理 - “如果您想要自定义的个人构建,这里是您的 CB 帐户”。不影响主服务器的构建性能。尽管他们的 API 非常简单,但创建管理工具可能只需要一到两周的时间,然后你就可以随心所欲。就像生活中的平常一样,如果你想要一些特别的东西,你最好自己做。同时他们正在快速成长并倾听社区的声音,所以请填写一个功能请求,它可能很快就会出现。
    • 哦,明白了。告诉分支所有者挑选他感兴趣的工作,并根据需要为他的自定义分支设置它们。我喜欢这个主意。
    【解决方案4】:

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

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

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

    但正如汤姆在上面所说的那样,克服功能分支的必要性并教开发人员干净地集成会更好,但这是一个较长的过程,并且由于许多您不会接触的遗留系统部分结果不清楚没有了。

    我的 2 美分

    【讨论】:

      猜你喜欢
      • 2011-06-24
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 2010-09-14
      • 2014-01-08
      • 2017-06-30
      • 1970-01-01
      • 2013-07-26
      相关资源
      最近更新 更多