Feedforce Developer Blog

フィードフォース開発者ブログ

GitHub Packages を使ってプライベート gem を社内限定で公開した

こんにちは、id:daido1976 です。

先日 GitHub Packages を使ってプライベート gem を社内限定で公開したので、その方法をご紹介します。

GitHub Packages とは

github.co.jp

GitHub Packages はライブラリ(パッケージ)のホスティングサービスです。

Ruby の場合 https://rubygems.org の代わりに https://rubygems.pkg.github.com に公開するイメージで、認証には GitHub の personal access token などを使います。

既存のプライベート gem と GitHub Packages との違い

既存のプライベート gem は主に git のタグやブランチを指定する方法が用いられますが、以下のようにいくつかの問題があります。

# main ブランチの先端を使うのは再現性がない(ブランチ指定した場合も同じ)
gem 'my_rubygem', github: 'my_name/my_rubygem'
# タグを指定しても書き換えられる可能性がある
gem 'my_rubygem', github: 'my_name/my_rubygem', tag: 'v1.0.0'
# コミットの参照を指定するのはシンプルに見づらい
gem 'my_rubygem', github: 'my_name/my_rubygem', ref: '4aded'

GitHub Packages は rubygems.org と同じように、バージョン指定が明確かつ一度リリースしたバージョンは変更できないので安全です。

GitHub Packages を使ってプライベート gem を社内限定で公開する

ここからは実際に GitHub Packages を使ってプライベート gem を社内限定で公開する方法(主にリリースとインストールの仕方)を説明していきます。

今回は Organization は feedforce、gem の名前は socialplus-rails という想定です。

日本語版のドキュメントは文章やサンプルコードが古いケースがあるので、以下の英語版ドキュメントを参照した方が良いです。

Working with the RubyGems registry - GitHub Docs

認証に使う personal access token の権限については以下のドキュメントが詳しいです。

About permissions for GitHub Packages - GitHub Docs

gem をリリース(Publish)する方法

まずは作成した gem をリリースする方法について説明します。

ローカルからリリースする

まとめると以下のような手順になります。

  1. 〜/.gem/credentials に GitHub の personal access token を追加
    • 権限は repowrite:packages が必要
  2. $ gem build socialplus-rails.gemspec で gem をビルド
    • SocialplusRails::VERSION0.1.0 を想定
  3. $ gem push --key github --host https://rubygems.pkg.github.com/feedforce socialplus-rails-0.1.0.gem で push する
    • この時に personal access token の権限が足りないとエラーになる

Push が成功すると https://github.com/orgs/feedforce/packages のような Packages のページに反映されます 👏

f:id:daido1976:20211104160709p:plain

CI からリリースする

gem のソースコードを更新した際に毎回上記のようにローカルからリリースしても良いのですが、できれば CI からリリースできるように仕組み化したいものです。

CircleCI の場合、以下のような release コマンドを定義して、リリース用のブランチがマージされた時に実行されるようにすれば OK です。

# .circleci/config.yml

version: 2.1
# ...
commands:
  release:
    description: Release to GitHub Packages
    steps:
      - run:
          name: Create GitHub Packages Credentials
          command: |
            mkdir ~/.gem || true
            echo -e "---\n:github: Bearer ${GITHUB_ACCESS_TOKEN}" > ~/.gem/credentials
            chmod 0600 ~/.gem/credentials
      - run:
          name: Release Gem
          command: |
            gem build socialplus-rails.gemspec
            release_version=$(find . -name "socialplus-rails-*.gem" | sed -E 's/\.\/socialplus-rails-(.*).gem/\1/')
            gem push --key github --host https://rubygems.pkg.github.com/feedforce "socialplus-rails-${release_version}.gem"

各環境へのインストール方法

ここからはリリースした gem を各環境へインストールする方法を説明します。

Gemfile への記述は以下のようにします。*1

# Gemfile
source 'https://rubygems.pkg.github.com/feedforce' do
  gem 'socialplus-rails', '0.1.0'
end

ローカルや本番環境でのインストール

以下のように bundle config コマンドで認証情報をセットしてから bundle install を行います。*2

# `USERNAME:TOKEN` は `{GitHubのユーザ名}:{Personal access token}` という形です(例: `daido1976:7axxx`)
$ bundle config https://rubygems.pkg.github.com/feedforce USERNAME:TOKEN
$ bundle install

※ インストール時の認証に利用する personal access token には read:packages の権限のみあれば OK です

Dependabot でのインストール

GitHub Packages のプライベート gem をDependabot の更新対象にしたい場合は追加の設定が必要です。

以下のように設定ファイルで GitHub Packages の認証情報を渡す準備をします。*3

# .github/dependabot.yml

version: 2
registries:
  rubygems-pkg-github:
    type: rubygems-server
    url: https://rubygems.pkg.github.com
    # BUNDLE_GITHUB_TOKEN の値は `USERNAME:TOKEN` という形式です
    token: "${{secrets.BUNDLE_GITHUB_TOKEN}}"

以下ドキュメントを参考に GitHub Packages の認証情報(今回の例なら BUNDLE_GITHUB_TOKEN)を Dependabot 用の Secret として登録すれば完了です。*4

Managing encrypted secrets for Dependabot - GitHub Docs

関連記事