Skip to content

Properly pinning Ruby gems and having our own gem download mirror

Recent events in the world of Javascript reminded me how much GitLab relies on https://rubygems.org/ and how little we are protected against gems being removed (bit us at least once!) or modified.

Bundler has a feature for protecting against this: bundle package. This downloads all the .gem files (tarballs) that your Gemfile.lock asks for and sticks them in vendor/cache. With bundle install --local you can then force Bundler to only use your local downloaded copies of the gems.

What if start using bundle package and track the .gem files with Git LFS?

  • We would be storing full gem sets for GitLab revisions on gitlab.com (and dev.gitlab.org, and github.com) protecting against yanked gems
  • We can avoid relying on rubygems.org to do a build
  • We would track SHA256 checksums of each .gem we rely on in Git

To make this easy to use we would need two scripts: bin/install-gems and bin/update-gem-checksums.

The install-gems script would download gems (either via LFS or with 'bundle package' as a fallback), use git lfs status to verify the checksums, and then run bundle install --local.

The update-gem-checksums script would be used by developers when they change add/remove/update gems. It would run bundle package --all --no-install --all-platforms and commit the changes (with LFS).

cc @marin @dzaporozhets @DouweM