Bundler vs RubyGems: CI で Ruby の依存関係はどう機能するか
これらは実際にはライバルではありません。RubyGems は gem を install し、Bundler はそれらを固定して解決します。そして CI ではほぼ常に Bundler を上に載せたいはずです。
RubyGems は Ruby のパッケージマネージャであり registry クライアントです(gem install)。Bundler はその上に載り、Gemfile から一貫した gem の集合を解決し、再現可能な install のために Gemfile.lock に固定します。
| RubyGems | Bundler | |
|---|---|---|
| 役割 | 個々の gem を install | 依存関係の集合を解決 + ロック |
| Lockfile | なし | Gemfile.lock |
| 再現可能な install | 手動で固定した場合のみ | あり (lock から) |
| CI コマンド | gem install <gem> | bundle install / bundle ci |
| 関係 | 基盤となる層 | RubyGems の上に構築 |
CI において
アプリケーションでは Bundler を使いたいはずです。Gemfile.lock を commit し、bundle install(--deployment / frozen 設定つき)を実行して、すべてのパイプラインが同一の gem バージョンを得るようにします。素の gem install は job 内でスタンドアロンな CLI ツールを install するには問題ありませんが、再現可能なプロジェクト環境は得られません。Bundler は内部で RubyGems を使っており、競合するのではなく協調します。
gem を cache する
vendor/bundle(または gem)ディレクトリを Gemfile.lock でキーづけして cache し、bundle path を設定して install が再取得ではなく復元されるようにします。どの Ruby バージョンを対象にしても install は CI runner 上で実行され、ネイティブ gem のコンパイルが支配的な場合はより高速なマネージド runner が役立ちます。
結論
Ruby アプリを構築するなら、再現可能な install のために commit した Gemfile.lock とともに Bundler を使ってください。job 内でスタンドアロンなツールが必要なだけなら gem install で十分です。これらは層であって代替ではありません。Bundler がプロジェクトにとって正しいデフォルトです。