【问题标题】:Mercurial: Automatically tagging a buildMercurial:自动标记构建
【发布时间】:2013-02-18 13:44:55
【问题描述】:

在一个多变的设置中,我想根据持续集成脚本自动标记某些构建。例如,每当部署一个分支的构建时,就可以使用诸如 branchName-buildId 之类的标签,或者每当构建通过所有集成测试时使用 latest-stable

但是,我担心简单地调用 hg tag 的直接方法会导致问题:

  • 某些标签可能重复 - 即latest-stable。我真的不在乎在这种情况下标记了哪个构建,但我不希望任何冲突,因为脚本无法解决这些问题。
  • 标签导致提交。然而,这意味着这些提交需要被推送,并且它们需要在面对人类和其他脚本的并发推送时保持稳健。特别是,自动推送会产生额外的正面,这是不好的。但是,当检测到额外的头(在推送时)时,本地标签提交已经发生,即使新的头可能很容易合并,有时标签也会导致冲突。

我怎样才能自动让 CI 服务器标记一个健壮的构建?在这里,更重要的是最终结果是一致的(即它不会弄乱 CI 服务器或 repo),并且在面对重复或冲突时可靠地应用标签就不那么重要了(无论如何这应该是不太可能的) )。

【问题讨论】:

    标签: mercurial continuous-integration tagging


    【解决方案1】:

    我认为你的谨慎是对的。机器人并不总是最好的公民,而且经常会做一些愚蠢的事情。

    您最终会做什么取决于您看到的标签的用途。例如,如果您只看到 CI 系统使用它们,那么我建议将它们保留在本地。完全没有拉/推/合并问题。

    有些标签可能是重复的 - 即最新稳定。我真的不在乎在这种情况下标记了哪个构建,但我不想要任何冲突,因为脚本无法解决这些问题。

    如果已经定义了一个标签,并且您再次调用hg tag,除非您强制它,否则它将失败,但是这样做是添加一个更新的、稍后定义的相同标签,并且最新的一个获胜。一方面这很好,因为合并很简单,但是在你这样做的时候考虑一​​下情况:

    hg update -r latest-stable
    hg update -r latest-stable
    hg update -r latest-stable
    hg update -r latest-stable
    

    每次您更新到该版本时,您都会获得一个在创建标记之前的版本(正常情况下),并且在该版本中,latest-stable 将指向之前的latest-stable。结果就是这一系列命令会让你穿越时空。

    因此我会说最好要么有唯一的标签(即stable-2013-02-18),要么在两个提交中添加标签;一个删除旧标签,一个添加新标签。

    hg update -r latest-stable # You're now at the commit that removed the tag.
    hg update -r latest-stable # This one will error because tag doesn't exist
    

    标签导致提交。然而,这意味着这些提交需要被推送,并且它们需要在面对人类和其他脚本的并发推送时保持稳健。特别是,自动推送会产生额外的正面,这是不好的。但是当检测到额外的头(在推送时)时,本地标签提交已经发生,即使新的头很可能可以简单地合并,有时标签也会导致冲突。

    CI 机器人应该tag; pull; merge (if necessary); push。如果合并失败,不要推送,发出警报。如果推送失败(即在合并的时间内有更多变更集),请再次拉取并合并。我只是确保您的脚本非常明确地说明了它正在合并的修订。这个过程应该不会让你有多余的头脑。

    我相信 Mercurial 对 .hgtags 文件的合并处理不同,因为它知道内容,因此冲突应该非常罕见。此外,标签提交通常很容易合并,因为所有更改都是.hgtags,因此来自 CI 头部的合并永远不会发生冲突。它可能的唯一原因是因为其他人使用与 CI 服务器相同的标签名称,如果他们这样做,那么他们需要在键盘上倒蜂蜜,这样他们才能造成更多伤害。

    我可以看到导致问题的情况是,如果您在多个具有相同标签名称的磁头上进行 CI 标记。例如开发和发布分支都在其上运行 CI,都分配了 tests-clean 标记,但分配给不同的修订版,然后稍后合并。解决方案是,不要那样做。

    希望其中一些有用。

    【讨论】:

    • 我不能很好地将它们保留在 CI 的本地,因为它并行执行许多构建 - 即有许多 CI 存储库。我想我可以有一个中间“缓冲区”回购,但这使得推/拉故事更加复杂(例如,它们仍然需要相互合并)。此外,对于开发人员来说,看到哪些变更集在哪里运行是非常好的 - 花费所有这些精力让基础设施运行,并让一切都在变化无常,但没有走到最后一英里并实际传达这些信息,这是一种耻辱。
    • 当您使用hg update latest-stable 时,mercurial 不会查看 工作副本 标签,而是查看所有头像的标签的联合。所以迭代 hg update latest-stable 命令没有问题 - 工作正常。
    • 关于合并:.hgtags 只是追加,这意味着 every 标签更改冲突 - 不仅仅是更改到同一个标签!所以不同的 CI 建设者会互相冲突;如果其他人添加了一个不相关的标签,也会发生冲突。本质上,这意味着每个标签编辑都需要可序列化和原子全局,以使琐碎的自动更新工作。
    【解决方案2】:

    如果您关心构建历史,请考虑为构建过程创建一个命名分支。在 Mercurial 中,所有分支的所有标签都在整个存储库中可见。

    如果您不关心历史,bookmarks 应该可以解决问题。构建过程可以在测试运行后设置书签latest-stable,然后执行hg push --bookmark latest-stable将该书签推送到服务器。

    无论哪种方式,您都必须注意不要对已经测试过的子版本运行测试。 Mercurial revsets 是非常强大的查询语言,应该会有所帮助。

    【讨论】:

    • 是的,我查看了书签,它们看起来很有吸引力,除了它们默认处于活动状态。因此,如果我更新到 latest-stable 并进行提交,我将隐式移动书签!这是不好的。我找不到禁用该行为的方法(除非每次都明确停用它并说服所有开发人员这样做,从长远来看,这两件事听起来都不太可能正常工作)。
    • 我已经有一个用于构建过程的命名分支,这就是 CI 服务器知道在哪里部署什么以及如何测试(例如)的方式。但是关于部署的最终选择是人为的,所以不是该分支中的每个变更集都会导致部署,只有那些通过手动验证的变更集 - 以及 那些 我想要标记(或书签,或其他)。跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-12
    相关资源
    最近更新 更多