如何在不轮询的情况下使本地 git 镜像保持最新?

How to keep a local git mirror up-to-date without polling?

场景:我们的开发团队使用 Jenkins 进行持续集成,我们的一些代码是开源的,因此托管在 GitHub.com

我们有相关 GitHub 存储库的本地镜像,我们的本地 GitBlit 服务器设置为定期轮询 GitHub 存储库以更新本地镜像。

这个"sort of works";但问题场景是这样的:

  1. 一位开发人员意识到他需要对开源代码库进行更改,因此他将更改推送到 GitHub 存储库,并更新了我们闭源代码中的子模块 Git 存储库指向新的修订版。
  2. 然后本地开发人员在 Jenkins 上触发自动构建,这样他就可以test/verify让更改在所有平台上都有效
  3. Jenkins 自动构建失败,因为 GitHub 存储库的本地镜像尚未更新以反映原始镜像,因此当 Jenkins 尝试更新其各个工作区中的子模块时,本地镜像-mirror 无法识别闭源 git 存储库指向的修订 ID。

我们目前解决此问题的方法是将 GitBlit 设置为更频繁地轮询 GitHub,但我不喜欢将其作为解决方案,因为它会导致更多 periodic/unnecessary 互联网上的流量,但仍然不能完全避免构建失败的可能性,例如在开发人员推送更改然后立即触发构建的情况下。

是否有针对此问题的已知 "best-practice" 解决方案可以自动为我们提供可靠的 Jenkins-build-behavior 并避免不断轮询 GitHub?

您可以使用 Github webhook 将以下事件通知您的本地基础设施:

  • A repository is pushed to
  • A pull request is opened
  • A GitHub Pages site is built
  • A new member is added to a team

请注意,这将最大限度地减少延迟,但在某些情况下,例如网络问题或 Github 基础设施部分中断它仍然可以使您的构建失败。

设置 Jenkins 自动构建以在构建之前更新本地镜像可能是唯一安全的解决方案。

我认为最好的解决方案是使用真正的 Git 存储库镜像,而不是尝试自己构建。如果无法访问 webhook(假设您不拥有 GitHub 存储库),您能做的最好的事情就是轮询。

有可用的开源解决方案(想到 Artifactory 和 Nexus)可以镜像 Git 存储库并提供缓存功能。我认为您会发现这些镜像比按特定时间间隔更新的脚本可靠得多。此外,我认为他们可以做一些事情,比如 运行 当用户尝试拉取时,对上游存储库进行快速哈希验证,这样他们就知道它们是否过时(并且会立即更新以提供正确的版本)。