我应该在 Gemfile 中设置显式版本吗?

Should I set explicit versions in a Gemfile?

我习惯于使用简单的命令来定义 gemfile,例如 gem 'devise'。我现在通过 AWS 上的 dockerized 容器将我的应用程序投入生产,同时还有一个管道,该管道根据对 Git 上我的主分支的推送来拉取和构建新容器。这意味着每次我推送新版本时,AWS 都会从头开始重建整个应用程序,同时安装所有最新版本的 gems。

我有点担心当有新版本的 gems 时会发生什么。这当然意味着如果包含的 gem 改变了它们的行为或方法,我的代码可能会停止工作。

这种情况下的最佳做法是什么?我应该开始明确定义我想要的 Gems 版本吗?如果是这样,我如何确保我确实从提供的修复程序中获利?

我正在考虑像这样定义我的所有宝石:

gem 'devise', '~> 4.6.0'
# Or
gem 'devise', '~> 4.6'

什么是最灵活的,但是"ensuring"我不运行进入任何长运行的问题?

通常应通过 Gemfile.lock 来防止意外的版本更改,它包含最后 installed/upgraded 的确切版本并与 gem 文件一起提交,可用于确保生产可以每次建造都完全一样。首先,我会调查为什么您的构建管道不使用它。

即使您有 CI 和良好的测试覆盖率可以防止生产中断,但最好还是确保出现问题不是因为您的更改,而是因为 gem 更新。因此 gem 更新,即使是次要版本和补丁版本,也应该单独提交。

至于 gem 文件本身的版本 - 您应该根据特定 gem 的版本策略指定版本依赖性(即使依赖 lock-file)。大多数 gem 使用 semantic versioning,因此 gem 不应在一个主要版本中破坏任何内容(~>4.6 选项)并且更新不应要求对您的应用进行重大更改(但无论如何可能会有大量弃用日志或一些回归,因此无论如何最好在生产前测试一个版本。

保持有关新版本依赖项的更新 - 定期 运行 bundle outdated 查看有哪些 gem 更新。