2017-01-16 112 views
2

介绍

我们有一个Rails5应用程序,这是在约10+发动机splittend和核心应用,其安装这些引擎。如何处理Gemfile.lock与本地宝石资源库?

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

要求的行为

  • 对于部署宝石/引擎的特定版本应该使用(由核心)。
  • 对于本地开发,本地克隆存储库的HEAD应该被使用(由核心)。

当前设置

我们实现了通过执行以下步骤在核心应用程序的每个引擎:

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

这似乎工作,但我们没有尝试运行部署尚未安装。

问题与安装

每次存储库中的一个局部更新,我们运行的核心bundle install,捆绑更新Gemfile.lockHEAD裁判本地引擎存储库。我们曾经承诺改变Gemfile.lock

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

  1. 如果有人更新了核心应用程序,而不更新引擎,它可能发生,即核心Gemfile.lock指的是git的承诺发动机,这不在当地存在。如果试图使用rails应用程序,那会导致错误。
  2. 在部署时(我认为)Gemfile.lock可能引用一个提交id,这是更新的,然后提交我想要部署的标记/版本。我不确定在这种情况下会发生什么,但我担心,这只会导致我们陷入困境。
  3. 我们在更改Gemfile.lock的核心中有很多提交(可能针对其中一个引擎的每个更改)。
  4. 使用其他引擎分支机构本地然后master迫使开发商在主应用程序来改变分支名Gemfile

问题

什么是管理Gemfile并在Gemfile.lock正确的/最佳途径避免这些问题的给定情况?

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

+0

'Gemfile'仍然是一个普通的老红宝石。我会为所有的子引擎(pleudocode)添加'\'git fetch \'如果Rails.dev?' – mudasobwa

+0

这听起来像一个非常复杂的设置。我看到的一个问题是,人们将会针对与生产中不同的提交哈希进行开发,因此很难确定您正在处理的内容是否与实时内容以及在什么情况下兼容。我可能会尝试对gem进行版本升级,并将它们从开发模式分开升级为不同的提交。 – lobati

+0

增加了另一个问题(引擎分支)。 – phortx

回答

2

如果有人更新了核心应用程序,而不更新引擎,它可能 发生,该核心Gemfile.lock的指的是git的承诺的 引擎,它不存在于本地的。如果您尝试使用 来使用rails应用程序,则会导致错误。

这里有几个选项:

1)使用像git-bundle宝石,让您可以运行一个命令,如gitb pull更新主要应用和引擎。

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

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

在部署的时候(我认为)的Gemfile.lock的可能指的是 提交ID,这是新的,则提交的标签/版本我 要部署。我不确定在这种情况下会发生什么,但我担心,这只会让我们陷入麻烦。

可以说主应用程序的特定修订版标记为1.0。该版本的Gemfile.lock指定引擎的哪些版本用于1.0。无法在运行引擎修订版的主应用程序的标签1.0中部署非Gemfile.lock中指定的引擎版本。

我们在更改Gemfile.lock (可能用于其中一个引擎中的每个更改)的核心中提交了很多提交。

是的,这是正确的。这是有效地将不同的git存储库和修订版绑定到一个应用程序中的文件。它在版本控制文件中的事实使它更好,更易于追踪。

什么是正确/最好的方式来管理Gemfile和 Gemfile.lock在给定的情况下,以避免这些问题?

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

2)在主应用程序Gemfile中引用引擎时不要使用标签。如果在发动机正在创建新的功能做在一个特性分支的分支在本地覆盖所有库:

gitb checkout -b feature/branch_name 

如果需要,发布管理可以通过具有多个分支,如主,释放和稳定上完成所有的git仓库。在发动机或反之亦然

gitb checkout release 
gitb pull origin master 
gitb push 

3)如果您需要延长(装饰或猴补丁)班:从一个环境移动代码到接下来我们也做了activesupport-decorators寻找可用的各种选项之后。

+0

对不起,最近我一直很忙。 '只有当提交者在其bundle配置中的本地覆盖引擎上有引擎时,才会发生这种情况,并且他们已经在该引擎上提交了未提交的提交。' - 这是不正确的。主应用程序的具体修订是指引擎的具体修订。在不拉动本地覆盖引擎的情况下拉动主应用程序将导致主应用程序引用对本地不存在的引擎的修订。然而,我们有一个类似git-bundle的脚本,它也运行'bundle','yarn install','bower install'等等。 – phortx

+0

是的你是对的。我已经更新了答案。 –

+0

谢谢 - 我们实际上有一个脚本,它关心所有本地回购。这解决了问题#1。关于发布管理:我们不喜欢这样做与分支机构。我们有一个包含生产代码和版本标签的主分支。我们希望保留这个原因。问题#3感觉仍然很烦人,即使它是自动化的:(...我已经添加了一个问题#4到列表 – phortx

1

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

  1. 如果有人更新了核心应用程序,而不更新引擎,它可能发生,即核心Gemfile.lock的指的是git的承诺发动机,这在本地不存在。如果尝试使用Rails应用程序,则会导致错误。

为了解决这个问题(和不相关的这个线程其他一些问题),我们写了一个脚本,它关心更新引擎,并做一些其他必要的设置任务。对于每一个发动机下面的步骤将被执行:

  • 设置为主要应用的捆绑配置使用本地回购
  • git pull -r --autostash或克隆如果回购尚未
  • bundle install
  • yarn install克隆
  • bower install

之后,脚本拉和SE主应用程序。

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

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


  • 在部署时(我认为)的Gemfile.lock的可参照提交ID,这是较新的,则提交的标签/版本,我想部署。我不确定在这种情况下会发生什么,但我担心,这只会导致我们陷入困境。
  • 为了解决这个问题,我们告诉团队不要提交Gemfile.lock。相反,我们更新并提交Gemfile.lock,同时发布新版本的主应用程序。这样,主应用程序总是引用每个引擎的具体(通常最新)版本。然而Bundler通过本地覆盖确保本地引擎库的HEAD将独立于锁定版本使用。

    这样的部署是一致的,锁定对具体的版本,降级是容易实现和开发人员不必更动版本,commitIds等


  • 在更改Gemfile的核心中我们有很多提交。锁定(可能对于其中一个引擎的每次更改)。
  • 查看问题#2的解决方案:我们只是不提交这些更改。这并不完美,但它确实有效。


  • 使用其他发动机分支局部然后掌握迫使显影剂在主应用程序的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'