LoginSignup
3
3

More than 3 years have passed since last update.

【Github Actions】Rails × PostgreSQL環境作ってHerokuにデプロイするCIとその解説

Posted at

Github Actionsを使ってRails×PostgreSQL環境のCIを作りました。
Github Actionsは普段触らなかったので、作ったCIについてコードの解説をここに書いていきます。

まずはCIでやっていることと、そのコードの全体像を書いていきます。そのあとにCIのコードについて説明を書いていきます。

今回のCIでやっていること

  1. Pull Requestが作られたタイミングで、RSpecによるテスト
  2. Masterブランチにマージされたタイミングで、Herokuにデプロイ
  3. テストが完了したら、Slackに通知する

書いたCI

name: Build And Test
on:
  pull_request:
  push:
    branches:
      - master
jobs:
  build_and_test:
    name: Exec RSpec rubocop brakeman
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:11.5
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    env:
      RAILS_ENV: test
      BUNDLE_PATH: ./vendor/bundle
      DATABASE_NAME: covid19_line_bot_test
      DATABASE_USER: postgres
      DATABASE_PASSWORD: ""
      DATABASE_HOST: 127.0.0.1
      DATABASE_PORT: 5432
      TZ: Asia/Tokyo
      RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
    steps:
      - name: Check out code
        uses: actions/checkout@v2
      - name: Cache Gemfile.lock
        uses: actions/cache@v2
        with:
          path: ./vendor/bundle
          key: ${{ runner.os }}-rails-bundle-v1-${{ hashFiles('**/Gemfile.lock') }}
          restore-keys: |
            ${{ runner.os }}-rails-bundle-v1-
      - name: Ruby 2.6.5のセットアップ
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 2.6.5
      - name: pg gem の依存関係のインストール
        run: |
          sudo apt-get update; sudo apt-get install libpq-dev
      - name: node v10のセットアップ
        uses: actions/setup-node@v1
        with:
          node-version: '10.x'
      - name: yarn install
        run: |
          yarn install --check-files
      - name: gem install
        run: |
          gem install bundler -v 1.17.3
      - name: bundler install
        run: |
          bundle check || bundle install --path vendor/bundle --jobs 4 --retry 3
      - name: Setup Database
        run: |
          bundle exec rails db:create db:schema:load --trace
      - name: Exec RSpec
        run: |
          bundle exec rspec --format documentation --force-color --backtrace
      - name: Exec Brakeman
        run: |
          bundle exec brakeman -A
      - name: Exec rubocop
        run: |
          bundle exec rubocop --extra-details --display-style-guide --parallel --display-cop-names
  test_slack_notification:
    name: 【Test Result】Slack Notification by Github Actions
    runs-on: ubuntu-latest
    needs: build_and_test
    env:
      SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
      SLACK_USERNAME: Github Actions Result
    steps:
      - name: Slack Notification on Success
        uses: rtCamp/action-slack-notify@v2
        if: success()
        env:
          SLACK_MESSAGE: Pass rubocop, rspec, brakeman
          SLACK_TITLE: Test Complete!🎉✨
      - name: Slack Notification on Failure
        uses: rtCamp/action-slack-notify@v2
        if: failure()
        env:
          SLACK_MESSAGE: Fail rubocop, rspec, brakeman
          SLACK_TITLE: Test Failure!👾
          SLACK_COLOR: "#dc3545"
  deploy_production:
    name: Herokuにデプロイ
    needs: build_and_test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/master'
    steps:
      - name: Check out code
        uses: actions/checkout@v2
      - name: Deploy to Heroku Production
        uses: akhileshns/heroku-deploy@v3.6.8
        with:
          heroku_api_key: ${{ secrets.HEROKU_API_KEY }}
          heroku_app_name: ${{ secrets.HEROKU_APP_NAME }}
          heroku_email: ${{ secrets.HEROKU_EMAIL }}

解説

name

name: Build And Test

ワークフローの名前GitHub リポジトリの [Actions] タブに表示されるワークフローの名前
スクリーンショット 2020-12-16 14.39.36.png

on

ワークフローを実行するタイミングを指定

on:
  pull_request:
  push:
    branches:
      - master

上記の例では、以下のタイミングでワークフローが走ります。

  • Pull Requestが作られたとき
  • MasterブランチにPushされたとき

他にもデプロイがされたとき、ブランチが作られたとき、プルリクにレビューが投げられたとき、など様々なタイミングを指定することが可能。

参考:Events that trigger workflows

jobs

ワークフローは1つ以上のJobからなる。
複数のジョブはデフォルトでは、並行に実行される。

jobs.job_id

JobにはJobを一意に判別するIDが必要

jobs:
  build_and_test:
    name: Exec RSpec rubocop brakeman
    runs-on: ubuntu-latest
    services: ~~~
    [省略]
  test_slack_notification:
    name: 【Test Result】Slack Notification by Github Actions
    runs-on: ubuntu-latest
    needs: build_and_test
    env:
      SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
      SLACK_USERNAME: Github Actions Result
    steps: ~~
    [省略]
  deploy_production:
    name: Herokuにデプロイ
    needs: build_and_test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/master'
    [省略]

上記のコードではこれらがJobのIDのキーに該当します。

  • build_and_test
  • test_slack_notification
  • deploy_production

jobs.job_name

Jobの名前

  build_and_test:
    name: Exec RSpec rubocop brakeman
  test_slack_notification:
    name: 【Test Result】Slack Notification by Github Actions
  deploy_production:
    name: Herokuにデプロイ

jobs.runs_on

Jobを実行するマシンを指定します。

  build_and_test:
    name: Exec RSpec rubocop brakeman
    runs-on: ubuntu-latest

2020年12月16日現在は、このような環境が用意されています

Virtual environment YAML workflow label
Windows Server 2019 windows-latest or windows-2019
Ubuntu 20.04 ubuntu-20.04
Ubuntu 18.04 ubuntu-latest or ubuntu-18.04
Ubuntu 16.04 ubuntu-16.04
macOS Big Sur 11.0 macos-11.0
macOS Catalina 10.15 macos-latest or macos-10.15

参考:Github Actions Supported runners and hardware resources

jobs.services

ジョブのためのサービスコンテナをホストするために使用

[サービスコンテナ]
Jobを実行するのに必要になるDBやRedisなどのサービスを提供できるDockerコンテナ

jobs:
  build_and_test:
    name: Exec RSpec rubocop brakeman
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:11.5
        ports:
          - 5432:5432
        # ↓postgresが起動するまで待つヘルスチェックの設定
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

jobs.env

Job中で使える環境変数を定義
Stepの中に書けば、そのStepでのみ利用可能な環境変数を定義できる

jobs:
  build_and_test:
    name: Exec RSpec rubocop brakeman
    [省略]
    env:
      RAILS_ENV: test
      BUNDLE_PATH: ./vendor/bundle
      DATABASE_NAME: covid19_line_bot_test
      DATABASE_USER: postgres
      DATABASE_PASSWORD: ""
      DATABASE_HOST: 127.0.0.1
      DATABASE_PORT: 5432
      TZ: Asia/Tokyo
      RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}

jobs.needs

ジョブの実行前に正常に完了する必要があるジョブを指定できる
以下の例だと、 build_and_testが正常に完了しないと、test_slack_notificationdeploy_productionも実行され

jobs:
  [省略]
  test_slack_notification:
    name: 【Test Result】Slack Notification by Github Actions
    runs-on: ubuntu-latest
    needs: build_and_test
  deploy_production:
    name: Herokuにデプロイ
    needs: build_and_test

jobs.if

ジョブを実行する条件を書くことができる

  deploy_production:
    name: Herokuにデプロイ
    needs: build_and_test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/master'
github.refとは

ワークフローの実行をトリガーしたブランチまたはタグ ref。 ブランチの場合、これはrefs/heads/ の形式で、タグの場合は refs/tags/ です

参考:GitHub Actions のコンテキストおよび式の構文

steps

Jobで実行するコマンドなどを書いていく

    steps:
      - name: Check out code
        uses: actions/checkout@v2
      - name: Cache Gemfile.lock
        uses: actions/cache@v2
        with:
          path: ./vendor/bundle
          key: ${{ runner.os }}-rails-bundle-v1-${{ hashFiles('**/Gemfile.lock') }}
          restore-keys: |
            ${{ runner.os }}-rails-bundle-v1-
      - name: Ruby 2.6.5のセットアップ
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 2.6.5
      - name: pg gem の依存関係のインストール
        run: |
          sudo apt-get update; sudo apt-get install libpq-dev
      - name: node v10のセットアップ
        uses: actions/setup-node@v1
        with:
          node-version: '10.x'
      - name: yarn install
        run: |
          yarn install --check-files
      - name: gem install
        run: |
          gem install bundler -v 1.17.3
      - name: bundler install
        run: |
          bundle check || bundle install --path vendor/bundle --jobs 4 --retry 3
      - name: Setup Database
        run: |
          bundle exec rails db:create db:schema:load --trace
      - name: Exec RSpec
        run: |
          bundle exec rspec --format documentation --force-color --backtrace
      - name: Exec Brakeman
        run: |
          bundle exec brakeman -A
      - name: Exec rubocop
        run: |
          bundle exec rubocop --extra-details --display-style-guide --parallel --display-cop-names

steps.name

GitHubで表示されるステップの名前

    steps:
      - name: Check out code
        uses: actions/checkout@v2

steps.uses

ステップとして実行するアクションを選択

    steps:
      - name: Check out code
        uses: actions/checkout@v2
      - name: Cache Gemfile.lock
        uses: actions/cache@v2
        with:
          path: ./vendor/bundle
          key: ${{ runner.os }}-rails-bundle-v1-${{ hashFiles('**/Gemfile.lock') }}
          restore-keys: |
            ${{ runner.os }}-rails-bundle-v1-
      - name: Ruby 2.6.5のセットアップ
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 2.6.5

使っているusersの説明

actions/checkout@v2

リポジトリをチェックアウトする

      - name: Check out code
        uses: actions/checkout@v2

参考:https://github.com/actions/checkout

actions/cache@v2

キャッシュできる

      - name: Cache Gemfile.lock
        uses: actions/cache@v2
        with:
          path: ./vendor/bundle
          key: ${{ runner.os }}-rails-bundle-v1-${{ hashFiles('**/Gemfile.lock') }}
          restore-keys: |
            ${{ runner.os }}-rails-bundle-v1-

path: ~~はキャッシュする、復元するファイルやディレクトリを指定する
key: ~~はキャッシュを保存/復元するためのキー
restore-keys: ~~はキーのキャッシュヒットが発生しなかった場合にキャッシュを復元するために使用するキーの順序付きリスト

参考:https://github.com/actions/cache

ruby/setup-ruby@v1
      - name: Ruby 2.6.5のセットアップ
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 2.6.5

ruby-version:~~で使用するRubyのバージョンを指定できる
参考:https://github.com/ruby/setup-ruby

actions/setup-node@v1
      - name: node v10のセットアップ
        uses: actions/setup-node@v1
        with:
          node-version: '10.x'

node-version:~~で使用するNodeのバージョンを指定できる
参考:https://github.com/actions/setup-node

rtCamp/action-slack-notify@v2

Slackに通知を送ることができる

      - name: Slack Notification on Success
        uses: rtCamp/action-slack-notify@v2
        if: success()
        env:
          SLACK_MESSAGE: Pass rubocop, rspec, brakeman
          SLACK_TITLE: Test Complete!🎉✨

SLACK_WEBHOOK:$ {{secrets.SLACK_WEBHOOK}} SlackのWebHockのURL設定は必須

参考:https://github.com/rtCamp/action-slack-notify

akhileshns/heroku-deploy@v3.6.8

Herokuにデプロイできる

      - name: Deploy to Heroku Production
        uses: akhileshns/heroku-deploy@v3.6.8
        with:
          heroku_api_key: ${{ secrets.HEROKU_API_KEY }}
          heroku_app_name: ${{ secrets.HEROKU_APP_NAME }}
          heroku_email: ${{ secrets.HEROKU_EMAIL }}

heroku_api_key:、heroku_app_name:、heroku_emailは必須

参考:https://github.com/AkhileshNS/heroku-deploy

steps.run

コマンドラインプログラムを実行する

      - name: yarn install
        run: |
          yarn install --check-files
      - name: gem install
        run: |
          gem install bundler -v 1.17.3
      - name: bundler install
        run: |
          bundle check || bundle install --path vendor/bundle --jobs 4 --retry 3
      - name: Exec RSpec
        run: |
          bundle exec rspec --format documentation --force-color --backtrace

runの中では、bundle installやyarn install、Rspecの実行などを行うようにしました。

終わりに

Rails×PostgreSQL環境を使うことが多くていままでCircleCIを利用していましたが今回GithubActionsを書いてみました。CIとしてそれほど大きな違いはなく感じたので、個人的には学習コストは低かったです。
ドキュメントも非常に分かりやすく日本語で書かれていてよかったです。

3
3
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
3
3