It most cases it's not necessary to add a version constraint next to your gems in the Gemfile
. Since all versions are saved in the Gemfile.lock
, everyone running bundle install
will get exactly the same versions.
There are some exceptions, where you can consider adding a version constrain to the Gemfile
:
- You are not checking in the
Gemfile.lock
into the version control (not recommended) - A specific gem has a bug in a more recent version (adding a comment for the reason is highly recommended)
- You want to ensure no one upgrades a library with
bundle update
An drawback of this approach is, that adding new gems might also upgrade existing gems. So check your Gemfile.lock
carefully when submitting a commit. Note that the approach in this card works best, if you use bundle outdated together with bundle update some_gem --convervative
for major updates, before running bundle update
on all minor and patch updates.
Examples
Bad
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby "2.7.6"
gem "rails", "~> 7.0.6"
gem "sqlite3", "~> 1.4"
gem "puma", "~> 5.0"
- This blocks automatic updates of
rails
,sqlite3
andpuma
withbundle update
Note: bundle add
will automatically add ~>
with the current version of the new gem and you need to take care to remove this version constraint afterwards again.
Good
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby "2.7.6"
gem "rails"
gem "sqlite3"
gem "puma"
- All gems are easily updateable with
bundle update
Good
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby "2.7.6"
gem "rails", "~> 7.0.6"
gem "sqlite3"
gem "puma"
-
bundle update
will never perform a majorrails
update unless you change this line
Okay
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby "2.7.6"
gem "rails"
gem "sqlite3", ">1.4.0" # CVE-XYZ
gem "puma"
- Downgrades with bundler happens only in rare cases and will emit a warning
Note: some_gem version regressed from a to b
. Checking theGemfile.lock
carefully when submitting a commit should be good enough to prevent reintroducing previous issues. - If you have big concerns, that a downgrade might reintroduce a security issue again, you still might add this contraint
- On the other hand, if you consequently enforce this, your rails line would have a long line of comments with CVEs
Good
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby "2.7.6"
gem "rails"
gem "sqlite3"
gem "puma", "<5.0" # Puma 5.0 does not work with our HMR middleware yet (see story #1234)
- Preventing upgrades in case the newest version has a bug or is for some reason not working within the project