0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【GitHub Actions】CIの導入方法

0
Posted at

はじめに

こんにちは。アメリカ在住で独学エンジニアを目指している Taira です。

CI/CD を導入するために GitHub Actions を学習中ですが、開発中に CI があることで、ミスのあるソースコードをマージするリスクが減ります。
「だったら早い段階で導入したほうがいいのでは?」と思い、さっそく CI を導入することに決めました。

本日は、Rails アプリケーションに CI を導入する方法について簡単にまとめていきたいと思います。

実行環境

  • Rails 8.0.4
  • devcontainer (Docker)
  • Minitest

CI の導入方法

まず、CI を導入したいリポジトリを GitHub 上で開き、Actions タブをクリックします。
その中にある New workflow をクリックします。

image.png

「Choose a workflow」の画面に移動するので、使用しているフレームワークを選択します。
私は Ruby on Rails を使用しているので、「Configure」をクリックしました。
image.png

次の画面で「Commit changes」をクリックすると、.github/workflows/rubyonrails.ymlmain ブランチに作成されます。
大枠のCI導入はこんな簡単にすることができます

image.png

詳細設定

以下は、デフォルトでコミットされる CI の内容です。

name: "Ruby on Rails CI"
on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]
jobs:
  test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:11-alpine
        ports:
          - "5432:5432"
        env:
          POSTGRES_DB: rails_test
          POSTGRES_USER: rails
          POSTGRES_PASSWORD: password
    env:
      RAILS_ENV: test
      DATABASE_URL: "postgres://rails:password@localhost:5432/rails_test"
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Install Ruby and gems
        uses: ruby/setup-ruby@78c01b705fd9d5ad960d432d3a0cfa341d50e410
        with:
          bundler-cache: true
      - name: Set up database schema
        run: bin/rails db:schema:load
      - name: Run tests
        run: bin/rake

  lint:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Install Ruby and gems
        uses: ruby/setup-ruby@78c01b705fd9d5ad960d432d3a0cfa341d50e410
        with:
          bundler-cache: true
      - name: Generate binstubs
        run: bundle binstubs bundler-audit brakeman rubocop
      - name: Security audit dependencies
        run: bin/bundler-audit --update
      - name: Security audit application code
        run: bin/brakeman -q -w2
      - name: Lint Ruby files
        run: bin/rubocop --parallel

ただし、上記のままだと私の環境ではうまく動作しませんでした。
そこで、以下のように調整した設定にしました。

修正した CI ファイル

name: "Ruby on Rails CI"
on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]
  # 手動で実行可能(任意)
  workflow_dispatch:

# pipefail を有効化(任意)
defaults:
  run:
    shell: bash
    
jobs:
  test:
    runs-on: ubuntu-latest
    # タイムアウトを5分に設定(任意)
    timeout-minutes: 5
    services:
      # database.ymlのhostと合わせる(必須)
      db:
        image: postgres:15-alpine
        ports:
          - 5432:5432
        env:
          POSTGRES_DB: todo_app_test
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: password
        # ヘルスチェックを追加(任意)
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    env:
      RAILS_ENV: test
      # データベース接続情報を環境変数で設定(必須)
      DATABASE_URL: postgres://postgres:password@localhost:5432/todo_app_test
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install Ruby and gems
        uses: ruby/setup-ruby@v1 #v1 にしないとbundler-cacheが有効化しない(必須)
        with:
          ruby-version: 3.3 # 自分が使用しているruby のバージョン(任意)
          bundler-cache: true

      - name: Set up database schema
        run: bin/rails db:schema:load

      - name: Run tests
        run: bin/rake

  lint:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Install Ruby and gems
        uses: ruby/setup-ruby@v1 # v1 にしないとbundler-cacheが有効化しない(必須)
        with:
          ruby-version: 3.3
          bundler-cache: true
        # binstubs bundler-audit brakeman rubocop をGem に入れてbundle install まで実行する(必須)
      - name: Generate binstubs
        run: bundle binstubs bundler-audit brakeman rubocop
  
      - name: Security audit dependencies
        run: bin/bundler-audit --update
      - name: Security audit application code
        run: bin/brakeman -q -w2
      - name: Lint Ruby files
        run: bin/rubocop --parallel

設定のポイント(必須項目)

db(サービス名)と database.yml の一致

# config/database.yml
test:
  <<: *default
  database: todo_app_test
  host: db

host: db と書いてある場合、CI 側でもサービス名を db にする必要があります。

DATABASE_URL の書式

以下の形式で書く必要があります:

postgres://{POSTGRES_USER}:{POSTGRES_PASSWORD}@localhost:5432/{POSTGRES_DB}

ruby/setup-ruby@v1 を使う理由

デフォルトの ruby/setup-ruby@xxxx のような特定コミット指定だと、bundler-cache: true が効きませんでした。
安定して bundler-cache を有効化するためには、@v1 と明示的に書くのがよさそうです(原因は不明)。

Generate binstubs の注意点

以下の gem を Gemfile に追加し、bundle install を忘れずに。
なお、私の場合はbrakeman rubocopはデフォルトで入っていました

# Gemfile

gem "bundler-audit"
gem "dotenv-rails"

bundle install を実行しないと Gemfile.lock が更新されず、CI 上でエラーになります。

CI 実行前にやるべきこと

以下の作業をローカルで確認してからプッシュしないと、CI が通らない可能性があります。

  • 手動で bin/rake を実行し、テストが通ることを確認
  • rubocop を実行し、指摘があれば rubocop -A で自動修正
  • bundler-audit --update で脆弱性情報を更新

まとめ

今回は、GitHub Actions を使って Rails アプリに CI を導入する手順を紹介しました。

本記事のポイント

  • GitHub Actions はテンプレートベースで簡単に導入できる
  • PostgreSQL や Ruby バージョンの指定、Gem の準備など、環境に応じた調整が必要
  • CI はミスの検知だけでなく、コード品質やセキュリティの担保にも有効

CI 導入前は「難しそう」と感じていたのですが、実際には「テストと Lint を自動で実行してくれる仕組み」だとわかれば、そこまで難しく考えなくてもよいと思います。

もし似たような構成で詰まった方がいれば、この記事が参考になれば嬉しいです。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?