【问题标题】:Enforcing one build for one commit in Jenkins/Hudson在 Jenkins/Hudson 中为一次提交执行一次构建
【发布时间】:2011-10-03 04:12:08
【问题描述】:

我们使用 Jenkins 在每次提交到 SCM 时对我们的项目进行增量构建。我们希望为每个提交获得单独的构建。然而,简单的方法(设置 SCM 并使用提交后挂钩来触发构建)在以下场景中会出现问题:

  • 构建已触发。
  • 在构建过程中(最多可能需要几分钟)两个由两个开发人员分别向 SCM 提交。
  • 一个新构建被触发。它接收来自之前构建期间所做的两个提交的更改。

这种“竞争条件”使查找哪个提交破坏了构建/引入的警告变得复杂。

当前采用的解决方案是检查一项作业(“调度程序作业”)中的更改并触发另一项作业来进行实际的检查和构建。

这个问题有合适的解决办法吗?

【问题讨论】:

    标签: hudson jenkins


    【解决方案1】:

    还没有,有一个功能请求涵盖这种构建,但它仍然开放:Issue 673

    【讨论】:

    • 感谢错误报告的链接。
    【解决方案2】:

    也许它没有抓住重点,但我们在这里运行了一个非常好的构建过程。

    • 我们使用 git 作为我们的源代码控制系统
    • 我们使用 gerrit 作为我们的审核工具
    • 我们使用 gerrit 触发器在我们的 jenkins 服务器上运行构建
    • 我们检查开发分支上的更改以在合并变更集时运行 jenkins

    简而言之,理想的开发者日是这样的

    1. 开发者 1 根据我们的主开发分支创建一个新分支来进行更改
    2. 开发者 1 尽可能多地提交
    3. 开发人员 1 认为他完成了工作,他将所做的更改合并为一个更改并将其推送到 gerrit
    4. 创建了一个新的 gerrit 更改,jenkins 尝试完全构建此更改
    5. 如果在构建过程中没有错误,则会对此更改进行审核
    6. 提交review的时候,changeset被合并到主仓库的develop分支中(没有change被合并到develop分支,不review)
    7. Jenkins 构建合并版本以确保没有合并错误

    没有开发者 2 加入队伍并尝试做一些工作

    过程完全相同,两者都开始工作,在那里分支。开发人员 1 更快,他的更改被合并到开发分支中。现在,在开发人员 2 可以发布他的更改之前,他必须在开发人员 1 所做的更改之上重新调整他的更改。

    因此,我们确信,每次对我们的代码库所做的更改都会触发构建过程。

    我们将它用于我们的 C# 开发 - 在 windows 上而不是在 linux 上

    【讨论】:

      【解决方案3】:

      我不相信你想做的事是可能的。 Daniel Kutik 提到的“安静期”实际上是用来告诉 Hudson/Jenkins 等待多长时间,以便允许对同一项目的其他提交进行处理。含义 - 如果您将此值设置为 60 秒并且您已经提交,它将等待一分钟,然后再开始新的构建,从而允许其他提交也被拾取(在那一分钟内)。

      【讨论】:

      • 我假设他设置了一个安静的“高”安静期。如果他减少静默期,那么两个构建“合并”的可能性也会降低。
      • @Daniel Kutik:是的,确实如此。但是,在这种情况下,这并没有真正的帮助。
      • @Daniel Kutik:不,静默期设置为零,我们尝试设置每分钟一次的 SCM 轮询和通过 URL 触发构建。在这两种情况下,多个触发器合并为一个。
      • 就像我说的,这不受支持。
      【解决方案4】:

      如果您使用规则“NO COMMIT on a broken build‏”并得出合乎逻辑的结论,您实际上最终会得到“没有提交损坏的构建或正在进行的构建”,在这种情况下,您描述的问题就会消失。

      让我解释一下。如果您有两个开发人员在同一个项目上工作并且他们都尝试提交(或者如果您使用的是 DVCS,则推送)。其中一个会成功,另一个会失败,需要在提交前更新。

      必须进行更新的开发人员从提交历史中知道,另一个提交是最近的,因此正在构建(即使它尚未签出)。他们不知道该构建是否已损坏,因此唯一安全的选择是观望。

      唯一会阻止您使用上述方法的是,如果构建需要很长时间,在这种情况下,您可能会发现您的开发人员永远没有机会提交(它总是在构建)。然后,这是一个驱动程序,将您的构建拆分为多个步骤的管道,因此 Post Commit 作业不超过 5 分钟,但理想情况下为 1 分钟。

      【讨论】:

      • 使用 DVCS,您仍然可以轻松解决此问题。假设您正在处理本地功能分支,然后合并到 master 并推送。可能有任意数量的提交破坏了构建,诚然你会知道是谁破坏了它,但这无助于追踪哪个提交。
      • 你说的不一定是真的。有时,当构建是绿色的但另一个构建正在进行中时,多个开发人员将他们的更改提交到 repo。下次 Jenkins 运行作业时,它会拉取最新版本的存储库,任何这些更改都可能影响构建的结果。在大型团队中,当破坏构建的人应该负责修复它时,这可能是一个问题。
      【解决方案5】:

      我认为可能有帮助的是将静默期(Jenkins > 管理 Jenkins > 配置系统)设置为 0,并将 SCM 轮询设置为非常短的时间。但即使在这么短的时间间隔内,也可能有两次提交。截至目前,Jenkins 没有将构建拆分为多个 SVN 提交的单个构建的功能。

      这是关于该主题的教程:Quiet Period Feature

      【讨论】:

        【解决方案6】:

        正如Issue 673 中的某人所指出的,您可以尝试使用参数是您要构建的实际 git 提交来启动参数化构建。这与 VCS 提交挂钩相结合。

        【讨论】: