🌈

【Ruby】プライベートリポジトリにある共有ライブラリ(gem)を組み込んで確認する方法

2024/04/02に公開

はじめに

こんにちは、okumudです。
弊社プロダクトのバックエンドは全て Ruby on Rails で実装していますが、異なるプロダクト間の共通の処理は共有ライブラリとして非公開の gem へ集約しています。
共有ライブラリへ影響の大きな変更を入れるとき、リリース前に組み合わせて動作確認を行いたいことがありました。
この記事ではリリース前の共有ライブラリをプロダクトと組み合わせて動作確認を行う方法を書きます。

この記事の対象

この記事は次のような環境を使用している人を対象としています。

  • 共有ライブラリをプライベートリポジトリ経由で配布している
  • 検証環境等へのデプロイは Docker イメージを使用している
  • ライブラリの管理は bundler を用いて gem の依存関係やバージョンの管理を行っている

なお、弊社のリポジトリはプロダクト・ライブラリごとに独立しており、共有ライブラリは、各プロダクトに組み込んでいます。
各プロダクトは AWS EKS を使っており、 Docker イメージをビルドする際に、プライベートリポジトリから共有ライブラリを取得しています。

共有ライブラリの準備

まず、動作確認したい gem を手動でビルドしておきます。

$ bundle exec gem build common-gem.gemspec
  Successfully built RubyGem
  Name: common-gem
  Version: 0.1.0
  File: common-gem-0.1.0.gem

作成した 共有ライブラリ を組み込む

Gemfile や Dockerfile の一部を抜粋して説明します。
次のように共有ライブラリ(common-gem)を取り込んでいる箇所があります。

Gemfile
source 'https://rubygems.pkg.github.com/organization_name' do
  gem 'common-gem'
end
Dockerfile
WORKDIR /app

COPY Gemfile* /app/
# Docker イメージ内にトークンを残したくないので、環境変数を一時的に使用する
RUN --mount=type=secret,id=BUNDLE_GITHUB_TOKEN <<-EOT
    set -xe

    # ローカルリポジトリの設定
    bundle config --local https://rubygems.pkg.github.com/organization_name `cat /run/secrets/BUNDLE_GITHUB_TOKEN`

    # 共有ライブラリを含むライブラリのインストール
    bundle install

    bundle config --delete https://rubygems.pkg.github.com/organization_name
EOT

生成した gem をサービスへ追加する

生成した gem を組み合わせて確認したいプロダクトへ追加します。
vendor/common-gem-0.1.0.gem

指定したパスの gem を参照する

Gemfile を以下のように変更してください。
共有ライブラリの場所を path で記述することで bundler はそのパスを参照するようになります。

Gemfile
- source 'https://rubygems.pkg.github.com/organization_name' do
-   gem 'common-gem'
- end
+ gem 'common-gem', path: '/usr/local/bundle_vendor/gems/common-gem-0.1.0'

Dockerfile は bundle install (ライブラリのインストール) ブロックの前に次のコマンドを追加します。
依存関係は bundler で解決できるので、 --ignore-dependencies を指定するところがポイントです。

Dockerfile
+ COPY vendor/common-gem-0.1.0.gem /tmp/
+ RUN <<-EOT
+     set -xe
+     mkdir -p /usr/local/bundle_vendor/
+     gem install --ignore-dependencies -N \
+       --local /tmp/common-gem-0.1.0.gem --install-dir /usr/local/bundle_vendor/
+ EOT

ライブラリをインストールすることで、Gemfile.lock も更新します。

$ bundle install

bundle install により、GEM で記載されてライブラリが PATH へ切り替わります。

参考: Gemfile.lock の差分

Gemfile.lock

+ PATH
+   remote: /usr/local/bundle_vendor/gems/common-gem-0.1.0
+   specs:
+     common-gem (0.1.0)
+       actionpack (>= 6.1)
+       activejob (>= 6.1)
+       activesupport (>= 6.1)
+       railties (>= 6.1)

- GEM
-   remote: https://rubygems.pkg.github.com/organization_name/
-   specs:
-     common-gem (0.1.0)
-       activesupport (>= 6.1)

あとは、検証環境等へデプロイすると、動作を確認できます☺️

まとめ

ローカル環境で gem をビルドしたものをインストール (gem install --ignore-dependencies -N --local /tmp/common-gem-0.1.0.gem --install-dir /usr/local/bundle_vendor/) することで、プライベートリポジトリを経由せずに動作確認ができました。

参考になれば、嬉しいです😄 他にもっと良い方法があれば、コメント欄にお寄せください。

SocialPLUS Tech Blog

Discussion