【问题标题】:How to handle Gemfile.lock with local gem repositories?如何使用本地 gem 存储库处理 Gemfile.lock?
【发布时间】:2017-05-31 02:10:26
【问题描述】:

简介

我们有一个 Rails5 应用程序,它分为大约 10 多个引擎和一个核心应用程序,它安装这些引擎。

在我们的例子中,引擎是一个普通的旧 Rails 引擎,被定义为一个 gem,并位于一个专用的 git 存储库中。核心应用程序中的Gemfile 指的是所有引擎(见下文)。

必需的行为

  • 对于部署,应使用特定版本的 gem/engine(由核心)。
  • 对于本地开发,应使用本地克隆存储库的HEAD(由核心)。

当前设置

我们通过对核心应用中的每个引擎执行以下步骤来实现这一点:

  • 添加gem 'nice_engine1', '~> 0.0.1', branch: :develop, git: '[...]', tag: 'v0.0.1'
  • 设置捆绑器配置条目:bundle config local.nice_engine1 ../nice_engine1

这似乎可行,但我们尚未尝试使用该设置运行部署。

该设置的问题

每次本地更新其中一个存储库并且我们在核心中运行 bundle install 时,bundler 会将 Gemfile.lock 更新为本地引擎存储库的新 HEAD 引用。我们曾经提交过Gemfile.lock 的更改。

不幸的是,这会导致一些问题:

  1. 如果有人在不更新引擎的情况下更新了核心应用程序,则可能会发生核心Gemfile.lock 指的是引擎的git commit,它在本地不存在。如果尝试使用 rails 应用程序,则会导致错误。
  2. 在部署时(我认为)Gemfile.lock 可能指的是提交 ID,它比我要部署的标记/版本的提交更新。我不确定在这种情况下会发生什么,但我担心这只会给我们带来麻烦。
  3. 我们在内核中有很多提交更改了Gemfile.lock(可能针对其中一个引擎中的每次更改)。
  4. 在本地使用另一个引擎分支然后master 强制开发人员更改主应用程序中的分支名称Gemfile

问题

在给定情况下管理GemfileGemfile.lock 以避免这些问题的正确/最佳方法是什么?

关于最佳实践、改进建议等的一些提示,如何使用 bundler 和 git 来满足我们的要求,我将不胜感激。

【问题讨论】:

  • Gemfile 仍然是一颗普通的老红宝石。我会为所有子引擎(pleudocode)添加`git fetch` if Rails.dev?
  • 这听起来像是一个相当复杂的设置。我看到的一个问题是,人们将针对与生产环境不同的提交哈希进行开发,因此很难确定您正在处理的内容与实际内容以及在什么情况下兼容。我可能会尝试对 gems 进行版本化,并将它们与开发模式分开升级,作为不同的提交。
  • 添加了另一个问题(引擎分支)。

标签: ruby-on-rails ruby git bundler rails-engines


【解决方案1】:

如果有人更新核心应用程序,而不更新引擎,它可能 发生,核心 Gemfile.lock 指的是一个 git commit 引擎,它在本地不存在。如果尝试会导致错误 使用 rails 应用程序。

这里有几个选项:

1) 使用像 git-bundle 这样的 gem,这样您就可以运行像 gitb pull 这样的单个命令来更新主应用程序和引擎。

2) 在 RubyMine 等 IDE 中打开主应用程序和引擎,因为如果单击 VCS -> 更新项目,它会更新所有存储库。

3) 创建一个类似于 git-bundle 的脚本,同时更新所有存储库。

在部署时(我认为) Gemfile.lock 可能指的是 提交 id,比我提交的标签/版本更新 想部署。我不确定在这种情况下会发生什么,但我 害怕,这只会给我们带来麻烦。

假设主应用程序的特定版本被标记为 1.0。该版本的 Gemfile.lock 指定引擎的哪些版本用于 1.0。除了 Gemfile.lock 中指定的内容之外,无法将主应用程序的标签 1.0 部署到运行引擎修订版的地方。

我们在更改 Gemfile.lock 的核心中有很多提交 (可能针对其中一个引擎的每次更改)。

是的,这是正确的。该文件有效地将不同的 git 存储库和修订版绑定到一个应用程序中。它位于版本控制文件中,这一事实使其美观且可追溯。

管理 Gemfile 和 Gemfile.lock 在给定的情况下可以避免这些问题吗?

1) 有一个宝石。它被称为git-bundle。我写了它,我们已经在不同的应用程序中使用它大约 5 年了,并且取得了巨大的成功。欢迎提出请求或反馈。

2) 在主应用程序 Gemfile 中引用引擎时不要使用标签。如果在引擎中创建新功能,请在功能分支中通过在本地覆盖上分支所有存储库来实现:

gitb checkout -b feature/branch_name

如果需要,可以通过在所有 git 存储库上拥有多个分支(例如 master、release 和 stable)来完成发布管理。将代码从一个环境移动到另一个环境:

gitb checkout release
gitb pull origin master
gitb push

3) 如果您需要在引擎中扩展(装饰或猴子补丁)类,反之亦然:在查看了可用的各种选项后,我们还创建了activesupport-decorators

【讨论】:

  • 抱歉,最近比较忙。 This will only happen if the committer has the engine on a local override in their bundle config and they have made commits on that engine which isn't pushed yet. - 这不是真的。主应用程序的具体修订是指引擎的具体修订。拉动主应用程序而不拉动本地覆盖的引擎,将导致主应用程序引用一个引擎的修订版,该引擎在本地不存在。但是我们有一个类似的脚本,比如 git-bundle,它也运行 bundleyarn installbower install 等等。
  • 谢谢 - 我们实际上有一个脚本,它关心拉取所有本地 repos。这解决了问题 #1。关于发布管理:我们不喜欢在分支上这样做。我们有一个包含生产代码和版本标签的主分支。由于几个原因,我们希望保留这一点。即使是自动化的,问题 #3 仍然令人讨厌 :( ...我已将问题 #4 添加到列表中
  • 您是否考虑过使用带有路径的 git 子模块的替代方法:"engines/..." 来引用您的 gemfile 中的 gem,而无需任何 git repo 或分支?
【解决方案2】:

经过良好的answer from Pierre Pretorius,一些研究和新经验,我设法解决了所有4个问题。我将解释每个问题的设置和解决方案:

  1. 如果有人在不更新引擎的情况下更新核心应用程序,可能会发生核心 Gemfile.lock 引用引擎的 git 提交,而该引擎在本地不存在。如果尝试使用 rails 应用程序,则会导致错误。

为了解决这个问题(以及其他一些与此线程无关的问题),我们编写了一个脚本,它关心更新引擎并执行一些其他必要的设置任务。对于每个引擎,将执行以下步骤:

  • 设置主应用的捆绑器配置以使用本地存储库
  • git pull -r --autostash 或者如果 repo 尚未克隆,则克隆
  • bundle install
  • yarn install
  • bower install

之后,脚本会拉取并设置主应用程序。

对于更简单的设置,您可以使用git-bundle gem,它可以让您在所有引擎上执行命令。

这最终解决了问题,堆栈中的某些内容不是最新的。


  1. 在部署时(我认为)Gemfile.lock 可能指的是提交 id,它比我要部署的标记/版本的提交更新。我不确定在这种情况下会发生什么,但我担心这只会给我们带来麻烦。

为了解决这个问题,我们告诉团队不要提交 Gemfile.lock。相反,我们在发布主应用程序的新版本时更新并提交 Gemfile.lock。这样,主应用程序总是引用每个引擎的具体(通常是最新的)版本。然而,Bundler 通过本地覆盖确保本地引擎存储库的 HEAD 将独立于锁定版本使用。

通过这种方式,部署是一致的并针对具体版本进行锁定,降级很容易,开发人员不必弄乱版本、提交 ID 等。


  1. 我们在内核中有很多提交更改了 Gemfile.lock(可能针对其中一个引擎中的每次更改)。

请参阅问题 #2 的解决方案:我们只是不提交这些更改。这不是很出色,但确实有效。


  1. 在本地使用另一个引擎分支,然后 master 会强制开发人员更改主应用程序 Gemfile 中的分支名称。

为了解决这个问题,我们将捆绑器配置 disable_local_branch_check 设置为 true:

bundle config disable_local_branch_check true

这样,我们可以从 Gemfile 中删除引擎的分支名称,并且开发人员可以使用他们可能想要在本地使用的任何分支(例如,在开发/审查时的功能分支)。


之后我们的一个引擎的 Gemfile 条目如下所示:

gem 'nice_engine1', '0.0.1', git: '[...]', tag: 'v0.0.1'

【讨论】:

    猜你喜欢
    • 2012-12-10
    • 2020-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-22
    • 1970-01-01
    • 2011-04-15
    • 1970-01-01
    相关资源
    最近更新 更多