LoginSignup
0
0

BundlerのグループによるGitHub Actions (ruby/setup-ruby@v1) におけるRubocopの実行最適化

Last updated at Posted at 2023-08-26

TL;DR

GitHub Actions で RuboCop を実行する際,デフォルトでは Gemfile に記載されている gem を余剰にインストールする必要があり冗長性が生じる.そこでBundlerのグループ機能を使って最小限の gem をインストールし,ジョブの最適化を行う.

具体的な手順は次のとおりである,RuboCopの関連gemを:rubocopグループに入れる.bundle configコマンドを使用して,withwithoutを設定することで,:defaultグループに属するgemを除いて:rubocopグループのgemのみをインストールすることができる.GitHub Actionsでは,ruby/setup-ruby@v1アクションを使用してRubyを設定し,bundler-cacheフィールドの値をfalseに設定する.

以上の手順により,bundle installの所要時間が20秒程度に短縮された.

諸言

CI ツール (GitHub Actions,Circle CI など) で Rubocop を実行する場合,実行環境 (Ubunbu など) に Rubocop gem 群をインストールする必要がある.ただし,デフォルトでは Gemfile に記載された gem (または,RAILS_ENVなどの環境変数に指定された test などのグループに属する gem) がインストールされ,冗長性が生じる.本稿では,Bundler のグループ機能によってインストールする gem を最小化し,CI ジョブの実行最適化を図る.

Gemfile

本稿では,rubocop のほかに,rubocop-{capybara, factory_bot, performance, rails, rspec} gem をバンドルしている.これらの gem 群を rubocop グループに入れる.

Gemfile
- group :development, :test do
+ group :development, :test, :rubocop do
  gem "rubocop", require: false
  gem "rubocop-capybara", require: false
  gem "rubocop-factory_bot", require: false
  gem "rubocop-performance", require: false
  gem "rubocop-rails", require: false
  gem "rubocop-rspec", require: false
end

Bundler のドキュメントによれば,明示的にグループに属していない gem は, :default グループに属している.

# These gems are in the :default group
gem 'nokogiri'
gem 'sinatra'

したがって,:rubocop グループの gem 群のみをインストールするには,:default グループに属す gem 群を除き,:rubocop グループの gem 群のみをインストールするよう指定すればよい.
指定する方法には,次の2つがある.

1

編集後に気づいたが,この方法のほうが良い.

BUNDLE_WITHBUNDLE_WITHOUT を指定する

次のように,環境変数 BUNDLE_WITH の値に rubocop を, BUNDLE_WITHOUT の値に default を設定すれば,:default グループに属す gem 群を除き,:rubocop 群のみをインストールすることができる.

rubocop ジョブは次のようになる.

ci.yml
# (省略)

jobs:
  rubocop:
    runs-on: ubuntu-latest
    env:
      BUNDLE_WITHOUT: "default development test production"
      BUNDLE_WITH: rubocop
    steps:
    - uses: actions/checkout@v3
    - uses: ruby/setup-ruby@v1  
    - name: Install dependencies
      run: bundle install --jobs 4 --retry 3
    - name: Run rubocop
      run: bundle exec rubocop

2

bundle config で withwithout を指定する

次のように,bundle config の with の値に rubocop を, without の値に default を設定すれば,:default グループに属す gem 群を除き,:rubocop 群のみをインストールすることができる.local オプションは,設定がローカルに行われるよう指示する.

bundle config set --local without default
bundle config set --local with rubocop

ruby/setup-ruby@v1 の bundler-cache を偽に設定する

GitHub Actions で Ruby を利用可能するためのアクション ruby/setup-ruby@v1 を用いることにする.
デフォルトでは,ruby/setup-ruby@v1 は Gemfile 及び Gemfile.lock を参照して
:default を除かずに bundle install してしまうため,bundler-cache フィールドの値を false に設定する必要がある. (bundle コマンドは,ruby/setup-ruby@v1 を実行したのちに利用可能になる.)

- uses: ruby/setup-ruby@v1  
  with:
    bundler-cache: false

rubocop ジョブ

以上から,rubocop ジョブは次のようになる.

ci.yml
# (省略)

jobs:
  rubocop:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - uses: ruby/setup-ruby@v1  
      with:
        bundler-cache: false 
    - name: Set up Ruby
      run: |
        bundle config set --local without "default development test production"
        bundle config set --local with rubocop
    - name: Install dependencies
      run: bundle install --jobs 4 --retry 3
    - name: Run rubocop
      run: bundle exec rubocop

結語

これによって,1分以上掛かっていた bundle install が 20秒ほどに短縮された.

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0