我们有一个Rails5应用程序,它在大约10多个引擎中分离,并且是一个核心应用程序,可以安装这些引擎。
我们的案例中的引擎是一个普通的旧轨道引擎,定义为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
时,bundler会将Gemfile.lock
更新为本地引擎存储库的新HEAD
ref。我们曾经提交过Gemfile.lock
。
不幸的是,这会导致一些问题:
Gemfile.lock
引用引擎的git提交,该引擎在本地不存在。如果尝试使用rails app,则会导致错误。Gemfile.lock
可能引用了一个提交ID,这比我想要部署的标记/版本的提交更新。我不确定在那种情况下会发生什么,但我担心,这只会让我们陷入困境。Gemfile.lock
(可能是其中一个引擎中的每个更改)。master
强制开发人员更改主要应用Gemfile
中的分支名称在给定情况下管理Gemfile
和Gemfile.lock
以避免这些问题的正确/最佳方法是什么?
有关最佳实践,改进建议等的一些提示,如何使用bundler和git来满足我们的要求,我将非常感激。
答案 0 :(得分:2)
如果有人更新核心应用程序,而不更新引擎,则可能 发生了,核心Gemfile.lock引用了一个git提交 引擎,在本地不存在。如果有人尝试,那会导致错误 使用rails app。
这里有几个选项:
1)使用类似git-bundle的gem,以便您可以运行gitb pull
之类的单个命令来更新主应用程序和引擎。
2)在像RubyMine这样的IDE中打开主应用程序和引擎,因为如果你单击VCS,它会更新所有存储库 - >更新项目。
3)创建一个类似于git-bundle的脚本,它同时更新所有存储库。
在部署时(我认为)Gemfile.lock可能指的是a 提交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。
答案 1 :(得分:1)
在好answer from Pierre Pretorius,一些研究和新经验之后,我设法解决了所有4个问题。我将解释每个问题的设置和解决方案:
- 如果有人更新核心应用程序,而不更新引擎,则可能会发生核心Gemfile.lock引用引擎的git提交,该引擎在本地不存在。如果尝试使用rails app,则会导致错误。
醇>
要解决该问题(以及与此线程无关的其他一些问题),我们编写了一个脚本,该脚本关注更新引擎并执行一些其他必要的设置任务。对于每个引擎,将执行以下步骤:
git pull -r --autostash
或克隆,如果尚未克隆回购bundle install
yarn install
bower install
之后,脚本会拉出并设置主应用程序。
对于更简单的设置,您可以使用git-bundle gem,它允许您在所有引擎上执行命令。
这最终解决了这个问题,即堆栈中的某些东西不是最新的。
- 在部署时(我认为),Gemfile.lock可能引用了一个提交ID,这比我想要部署的标记/版本的提交更新。我不确定在那种情况下会发生什么,但我担心,这只会让我们陷入麻烦。
醇>
为了解决这个问题,我们告诉团队不要提交Gemfile.lock。相反,我们在发布主应用程序的新版本时更新并提交Gemfile.lock。这样,主应用程序总是引用每个引擎的具体(最新的)版本。但是,Bundler通过本地覆盖确保本地引擎存储库的HEAD将独立于锁定版本使用。
这种方式部署是一致的,并且与具体版本相关联,降级很容易,开发人员不必乱用版本,commitIds等。
- 我们在核心中有很多提交更改了Gemfile.lock(可能是其中一个引擎中的每个更改)。
醇>
请参阅问题2的解决方案:我们只是不提交这些更改。这并不完美,但确实有效。
- 在本地使用另一个引擎分支,然后master强制开发人员更改主应用程序Gemfile中的分支名称。
醇>
为了解决这个问题,我们将bundler config 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'