注: GitHub ホステッド ランナーは、現在 GitHub Enterprise Server でサポートされていません。 GitHub public roadmap で、今後の計画的なサポートの詳細を確認できます。
はじめに
このガイドでは、Rubyアプリケーションのビルドとテストを行う継続的インテグレーション(CI)ワークフローの作成方法を紹介します。 CIテストにパスしたなら、コードをデプロイしたりgemを公開したりすることになるでしょう。
前提条件
Ruby、YAML、ワークフローの設定オプションと、ワークフローファイルの作成方法についての基本的な知識を持っておくことをおすすめします。 詳細については、次を参照してください。
Ruby ワークフロー テンプレートの使用
To get started quickly, add a workflow template to the .github/workflows
directory of your repository.
GitHub では、ほとんどの Ruby プロジェクトで動作する Ruby 用のワークフロー テンプレートが提供されています。 このガイドの以降のセクションでは、このワークフロー テンプレートをカスタマイズする方法の例を示します。
-
GitHub で、リポジトリのメイン ページに移動します。
-
リポジトリ名の下にある [アクション] をクリックします。
-
ワークフローが既にリポジトリ内にある場合は、 [新しいワークフロー] をクリックします。
-
[ワークフローの選択] ページには、推奨されるワークフロー テンプレートの選択が表示されます。 「ruby」を検索します。
-
[継続的インテグレーション] をクリックして、ワークフローの選択をフィルター処理します。
-
"Ruby" ワークフローで、[構成] をクリックします。
「Ruby」ワークフロー テンプレートが見つからない場合は、次のワークフロー コードをリポジトリの
.github/workflows
ディレクトリでruby.yml
を呼び出した新しいファイルにコピーします。YAML name: Ruby on: push: branches: [ "main" ] pull_request: branches: [ "main" ] permissions: contents: read jobs: test: runs-on: ubuntu-latest strategy: matrix: ruby-version: ['2.6', '2.7', '3.0'] steps: - uses: actions/checkout@v4 - name: Set up Ruby # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby, # change this to (see https://github.com/ruby/setup-ruby#versioning): # uses: ruby/setup-ruby@v1 uses: ruby/setup-ruby@55283cc23133118229fd3f97f9336ee23a179fcf # v1.146.0 with: ruby-version: ${{ matrix.ruby-version }} bundler-cache: true # runs 'bundle install' and caches installed gems automatically - name: Run tests run: bundle exec rake
name: Ruby on: push: branches: [ "main" ] pull_request: branches: [ "main" ] permissions: contents: read jobs: test: runs-on: ubuntu-latest strategy: matrix: ruby-version: ['2.6', '2.7', '3.0'] steps: - uses: actions/checkout@v4 - name: Set up Ruby # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby, # change this to (see https://github.com/ruby/setup-ruby#versioning): # uses: ruby/setup-ruby@v1 uses: ruby/setup-ruby@55283cc23133118229fd3f97f9336ee23a179fcf # v1.146.0 with: ruby-version: ${{ matrix.ruby-version }} bundler-cache: true # runs 'bundle install' and caches installed gems automatically - name: Run tests run: bundle exec rake
-
必要に応じてワークフローを編集します。 たとえば、使用する Ruby のバージョンを変更します。
注:
- このスターター ワークフローでは、GitHub によって認定されていないアクションが使われます。 サード パーティによって提供されるアクションには、個別のサービス使用条件、プライバシー ポリシー、およびサポート ドキュメントが適用されます。
- サード パーティのアクションを使用するには、コミット SHA で指定されたバージョンを使用する必要があります。 アクションが変更された新しいバージョンを使用する場合は、SHA を更新する必要があります。 タグまたはブランチを参照してバージョンを指定できますが、アクションは警告なしに変更される可能性があります。 詳しくは、「GitHub Actions のセキュリティ強化」を参照してください。
-
[変更をコミットする] をクリックします。
Rubyのバージョンの指定
Ruby のバージョンを指定する最も簡単な方法は、Ruby 組織によって GitHub で提供されている ruby/setup-ruby
アクションを使用することです。 このアクションにより、ワークフロー内の各ジョブ実行に対する PATH
に、サポートされている Ruby のバージョンが追加されます。 詳細と使用可能な Ruby のバージョンについては、ruby/setup-ruby
を参照してください。
GitHub Actions で Ruby を使用する場合、Ruby の ruby/setup-ruby
アクションを使用すると、異なるランナーおよび Ruby の異なるバージョンの間で一貫した動作が保証されるため、この方法をお勧めします。
setup-ruby
アクションは Ruby のバージョンを入力として受け取り、ランナー上でそのバージョンを構成します。
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
with:
ruby-version: '3.1' # Not needed with a .ruby-version file
- run: bundle install
- run: bundle exec rake
または、リポジトリのルートに .ruby-version
ファイルをチェックインすると、そのファイルで定義されているバージョンが setup-ruby
で使われます。
複数のバージョンの Ruby でのテスト
複数バージョンのRubyでワークフローを実行するように、マトリクス戦略を追加できます。 たとえば、バージョン 3.1、3.0、2.7 の最新のパッチ リリースに対してコードをテストできます。
strategy:
matrix:
ruby-version: ['3.1', '3.0', '2.7']
ruby-version
配列で指定されている Ruby の各バージョンで、同じ手順を実行するジョブが作成されます。 現在のジョブのバージョンにアクセスするには、${{ matrix.ruby-version }}
コンテキストが使われます。 マトリックスの戦略とコンテキストの詳細については、「GitHub Actions のワークフロー構文」および「Accessing contextual information about workflow runs」を参照してください。
マトリクス戦略を持つ更新された完全なワークフローは、以下のようになるでしょう。
# このワークフローはGitHubによって認定されていないアクションを使用します。
# それらはサードパーティによって提供され、
# 別個の利用規約、プライバシーポリシー、
# ドキュメントを参照してください。
# GitHub では、コミット SHA にアクションをピン留めすることが推奨されます。
# 新しいバージョンを取得するには、SHA を更新する必要があります。
# タグまたはブランチを参照することもできますが、アクションは警告なしに変更される可能性があります。
name: Ruby CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
ruby-version: ['3.1', '3.0', '2.7']
steps:
- uses: actions/checkout@v4
- name: Set up Ruby ${{ matrix.ruby-version }}
uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
with:
ruby-version: ${{ matrix.ruby-version }}
- name: Install dependencies
run: bundle install
- name: Run tests
run: bundle exec rake
Bundlerでの依存関係のインストール
setup-ruby
アクションにより、バンドルが自動的にインストールされます。 バージョンは gemfile.lock
ファイルによって決まります。 ロックファイルにバージョンがなければ、互換性のある最新のバージョンがインストールされます。
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
with:
ruby-version: '3.1'
- run: bundle install
依存関係のキャッシング
setup-ruby
アクションによって実行間で gem のキャッシュを自動的に処理する方法が提供されます。
キャッシングを有効にするには、以下の設定をしてください。
steps:
- uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
with:
bundler-cache: true
これにより、gem を vendor/cache
にインストールするように Bundler が構成されます。 ワークフローの実行が成功するたびに、このフォルダーは GitHub Actions によってキャッシュされ、それ以降のワークフローの実行の際に再ダウンロードされます。 キャッシュのキーとしては、gemfile.lockのハッシュとRubyのバージョンが使われます。 新しいgemをインストールしたり、バージョンを変更したりすると、キャッシュは無効になり、bundlerは新しくインストールを行います。
setup-ruby を使用しないキャッシュ
キャッシュをより詳細に制御するために、actions/cache
アクションを直接使用できます。 詳しくは、「依存関係をキャッシュしてワークフローのスピードを上げる」を参照してください。
steps:
- uses: actions/cache@v3
with:
path: vendor/bundle
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gems-
- name: Bundle install
run: |
bundle config path vendor/bundle
bundle install --jobs 4 --retry 3
マトリクスビルドを使っているなら、キャッシュのキーにマトリクスの変数を含めたくなるでしょう。 たとえば、Ruby のさまざまなバージョン (matrix.ruby-version
) とさまざまなオペレーティング システム (matrix.os
) に対してマトリクス戦略を使用している場合、ワークフローの手順は次のようになります。
steps:
- uses: actions/cache@v3
with:
path: vendor/bundle
key: bundle-use-ruby-${{ matrix.os }}-${{ matrix.ruby-version }}-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
bundle-use-ruby-${{ matrix.os }}-${{ matrix.ruby-version }}-
- name: Bundle install
run: |
bundle config path vendor/bundle
bundle install --jobs 4 --retry 3
コードのマトリクステスト
以下の例のマトリクスは、すべての安定リリースとヘッドバージョンのMRI、JRuby、TruffleRubyをUbuntu及びmacOSでテストします。
# このワークフローはGitHubによって認定されていないアクションを使用します。
# それらはサードパーティによって提供され、
# 別個の利用規約、プライバシーポリシー、
# ドキュメントを参照してください。
# GitHub では、コミット SHA にアクションをピン留めすることが推奨されます。
# 新しいバージョンを取得するには、SHA を更新する必要があります。
# タグまたはブランチを参照することもできますが、アクションは警告なしに変更される可能性があります。
name: Matrix Testing
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ${{ matrix.os }}-latest
strategy:
fail-fast: false
matrix:
os: [ubuntu, macos]
ruby: [2.5, 2.6, 2.7, head, debug, jruby, jruby-head, truffleruby, truffleruby-head]
continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }}
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
with:
ruby-version: ${{ matrix.ruby }}
- run: bundle install
- run: bundle exec rake
コードの文法チェック
次の例では、rubocop
がインストールされ、それを使ってすべてのファイルがリントされます。 詳細については、RuboCop を参照してください。 特定のリンティング規則を決定するように、Rubocop を構成することができます。
# このワークフローはGitHubによって認定されていないアクションを使用します。
# それらはサードパーティによって提供され、
# 別個の利用規約、プライバシーポリシー、
# ドキュメントを参照してください。
# GitHub では、コミット SHA にアクションをピン留めすることが推奨されます。
# 新しいバージョンを取得するには、SHA を更新する必要があります。
# タグまたはブランチを参照することもできますが、アクションは警告なしに変更される可能性があります。
name: Linting
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
with:
ruby-version: '2.6'
- run: bundle install
- name: Rubocop
run: rubocop -f github
-f github
を指定すると、RuboCop の出力は GitHub の注釈形式になります。 リンティング エラーは、そのエラーが発生したプル リクエストの [ファイルの変更] タブにインラインで表示されます。
gemの公開
CIテストにパスしたなら、Rubyパッケージを任意のパッケージレジストリに公開するようにワークフローを設定できます。
パッケージを公開するのに必要なアクセストークンや認証情報は、リポジトリシークレットを使って保存できます。 次の例では、パッケージが作成されて、GitHub Package Registry
と RubyGems
に発行されます。
# このワークフローはGitHubによって認定されていないアクションを使用します。
# それらはサードパーティによって提供され、
# 別個の利用規約、プライバシーポリシー、
# ドキュメントを参照してください。
# GitHub では、コミット SHA にアクションをピン留めすることが推奨されます。
# 新しいバージョンを取得するには、SHA を更新する必要があります。
# タグまたはブランチを参照することもできますが、アクションは警告なしに変更される可能性があります。
name: Ruby Gem
on:
# Manually publish
workflow_dispatch:
# Alternatively, publish whenever changes are merged to the `main` branch.
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
name: Build + Publish
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- uses: actions/checkout@v4
- name: Set up Ruby 2.6
uses: ruby/setup-ruby@ec02537da5712d66d4d50a0f33b7eb52773b5ed1
with:
ruby-version: '2.6'
- run: bundle install
- name: Publish to GPR
run: |
mkdir -p $HOME/.gem
touch $HOME/.gem/credentials
chmod 0600 $HOME/.gem/credentials
printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
gem build *.gemspec
gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem
env:
GEM_HOST_API_KEY: "Bearer ${{secrets.GITHUB_TOKEN}}"
OWNER: ${{ github.repository_owner }}
- name: Publish to RubyGems
run: |
mkdir -p $HOME/.gem
touch $HOME/.gem/credentials
chmod 0600 $HOME/.gem/credentials
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
gem build *.gemspec
gem push *.gem
env:
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"