Closed10

Github Actions導入にあたってのメモ

なかじなかじ

GitHub Actions のクイックスタート - GitHub Docs

Github Actionsとはそもそも何か?

  • ビルド、テスト、デプロイのパイプラインを自動化できる継続的インテグレーション(CI)と継続的デリバリー (CD) のプラットフォーム
  • CI:変更のマージ、ビルド、およびテストを自動化
  • CD:CIで行う変更のマージ、ビルド、およびテストに追加してデプロイとリリースを自動化

CI/CDの導入目的は?

  • ヒューマンエラーの減少
  • リリース速度の向上
  • バグの早期発見

参考資料

なかじなかじ

デモやってみる

ディレクトリとファイルの作成方法

  • .github/workflowsディレクトリの作成。その配下に、ymlファイルを作成する。
name: GitHub Actions Demo
run-name: ${{ github.actor }} is testing out GitHub Actions 🚀
on: [push] #=>今回のトリガーアクションはpush
jobs:
  Explore-GitHub-Actions:
    runs-on: ubuntu-latest
    steps:
      - run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
      - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
      - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
      - name: Check out repository code
        uses: actions/checkout@v4
      - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
      - run: echo "🖥️ The workflow is now ready to test your code on the runner."
      - name: List files in the repository
        run: |
          ls ${{ github.workspace }}
      - run: echo "🍏 This job's status is ${{ job.status }}."

実行結果

ざっと流れ

なかじなかじ

CDの導入(デプロイ先はheroku)

.github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: akhileshns/heroku-deploy@v3.13.15 # This is the action
        with:
          heroku_api_key: ${{secrets.HEROKU_API_KEY}}
          heroku_app_name: ${{secrets.HEROKU_APP_NAME}} #Must be unique in Heroku
          heroku_email: ${{secrets.HEROKU_EMAIL}}

リポジトリ内シークレット

  • 各リポジトリのSettings→Secrets and variables→Actions(Actions Secrets and variables)→Repository secrets→左上のRepository secretsで作成
  • HEROKU_API_KEY:アイコン→Account Settings→API KeyをReveal
  • HEROKU_APP_NAME:アプリの名前
  • HEROKU_EMAIL:heroku登録のEメールアドレス
  • GitHub Actions でのシークレットの使用 - GitHub Docs]

Dockerのオプションについて

  • ローカルではDockerだけど本番環境はDockerでデプロイしてない?
なかじなかじ

Rspec実行時のエラー

参考の資料

.github/workflows/deploy.yml
  rspec:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    services:
      mysql:
        image: mysql:8.0
        ports:
          - 3307:3306
        env:
          MYSQL_ROOT_PASSWORD: password
          MYSQL_ROOT_HOST: '%'
        options: --health-cmd "mysqladmin ping -h 127.0.0.1" --health-interval 20s --health-timeout 10s --health-retries 10

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          bundler-cache: true

      - name: Bundler and gem install
        run: |
          gem install bundler
          bundle install --jobs 4 --retry 3 --path vendor/bundle

      - name: Wait for MySQL
        run: sleep 15

      - name: Database create and migrate
        run: |
          cp config/database.ci.yml config/database.yml
          bundle exec rails db:create RAILS_ENV=test
          bundle exec rails db:migrate RAILS_ENV=test
  
      - name: Run rspec
        run: bundle exec rspec
config/database.ci.yml
test:
  adapter: mysql2
  charset: utf8mb4
  collation: utf8mb4_bin
  encoding: utf8mb4
  database: rails7-mysql
  host: 127.0.0.1
  username: root
  password: password
  reconnect: false
config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  host: db

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test

production:
  <<: *default
  database: myapp_production
  username: myapp
  password: <%= ENV["MYAPP_DATABASE_PASSWORD"] %>

エラー内容

Please check your database configuration and ensure there is a valid connection to your database.
Couldn't create 'rails7-mysql' database. Please check your configuration.
bin/rails aborted!
ActiveRecord::DatabaseConnectionError: There is an issue connecting with your hostname: 127.0.0.1. (ActiveRecord::DatabaseConnectionError)
なかじなかじ

DB関連のエラー解消

DEPRECATION WARNING: #fog_provider is deprecated and has no effect (called from block in <main> at /home/runner/work/metime-meals/metime-meals/config/initializers/carrierwave.rb:7)
DEPRECATION WARNING: Calling warn on ActiveSupport::Deprecation is deprecated and will be removed from Rails (use your own Deprecation object instead) (called from block in <main> at /home/runner/work/metime-meals/metime-meals/config/initializers/carrierwave.rb:7)
WARNING: MYSQL_OPT_RECONNECT is deprecated and will be removed in a future version.
WARNING: MYSQL_OPT_RECONNECT is deprecated and will be removed in a future version.
There is an issue connecting with your hostname: 127.0.0.1.

Please check your database configuration and ensure there is a valid connection to your database.
Couldn't create 'myapp_test' database. Please check your configuration.
bin/rails aborted!
ActiveRecord::DatabaseConnectionError: There is an issue connecting with your hostname: 127.0.0.1. (ActiveRecord::DatabaseConnectionError)
#...
Caused by:
Mysql2::Error::ConnectionError: Can't connect to MySQL server on '127.0.0.1:3306' (111) (Mysql2::Error::ConnectionError)
  • 一生このエラー出てた

下記資料を参考にした

ファイルの中身

#.github/workflows/deploy.yml
name: rubocop, rspec, deploy

on:
  push:
    branches:
  
jobs:
  rspec:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    services:
      mysql:
        image: mysql:8.0
        ports:
          - 3306:3306
        env:
          MYSQL_ALLOW_EMPTY_PASSWORD: yes
        options: --health-cmd "mysqladmin ping" --health-interval 10s --health-timeout 5s --health-retries 10

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          bundler-cache: true
      
      - name: Cache node modules
        uses: actions/cache@v2
        with:
          path: node_modules
          key: ${{ runner.os }}-node-${{ hashFiles('**/yarn.lock') }}
          restore-keys: |
            ${{ runner.os }}-node-

      - name: Bundler and gem install
        run: |
          gem install bundler
          bundle install --jobs 4 --retry 3 --path vendor/bundle

      - name: Yarn install
        run: yarn install --check-files

      - name: Wait for MySQL
        run: sleep 15

      - name: Database create and migrate
        run: |
          cp config/database.ci.yml config/database.yml
          bundle exec rails db:create RAILS_ENV=test
          bundle exec rails db:migrate RAILS_ENV=test
  
      - name: Run rspec
        run: bundle exec rspec

  rubocop:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          bundler-cache: true

      - name: Run rubocop
        run: bundle exec rubocop -a

  deploy:
    if: github.ref == 'refs/heads/main'
    needs: 
      - rubocop
      - rspec
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: akhileshns/heroku-deploy@v3.13.15
        with:
          heroku_api_key: ${{secrets.HEROKU_API_KEY}}
          heroku_app_name: ${{ secrets.HEROKU_APP_NAME }}
          heroku_email: ${{ secrets.HEROKU_EMAIL }}
#config/database.yml.ci
test:
  adapter: mysql2
  encoding: utf8mb4
  database: myapp_test
  host: 127.0.0.1
  username: root
  password: 
なかじなかじ

テスト実行前エラー(画像関連①)

DEPRECATION WARNING: #fog_provider is deprecated and has no effect (called from block in <top (required)> at /home/runner/work/metime-meals/metime-meals/config/initializers/carrierwave.rb:7)
DEPRECATION WARNING: Calling warn on ActiveSupport::Deprecation is deprecated and will be removed from Rails (use your own Deprecation object instead) (called from block in <top (required)> at /home/runner/work/metime-meals/metime-meals/config/initializers/carrierwave.rb:7)

An error occurred while loading ./spec/models/user_spec.rb.
Failure/Error: require_relative '../config/environment'

ArgumentError:
  Missing required arguments: aws_access_key_id, aws_secret_access_key
  • S3関連のaws_access_key_idとかaws_secret_access_keyがないですよ〜というエラー
  • GitHubのRepository secretsに環境変数を一通り追加してみる
  • 引き続きエラー

テスト時の画像アップロード無効化(失敗)

#uploaderファイル
CarrierWave.configure do |config|
  if Rails.env.test?
    config.storage = :file
    config.enable_processing = false
  else
    config.storage = :fog
  end
end

config/initializers/carrierwave.rbで無効化

#config/initializers/carrierwave.rb
config.enable_processing = false if Rails.env.test?

環境ごとのエラー

なかじなかじ

テスト実行前エラー(画像関連②)

  • GitHubのRepository secretsに環境変数を一通り追加している
#ruby
      - name: Run rspec
        run: RAILS_ENV=test bundle exec rspec
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }}
  • 戻してみた
#config/initializers/carrierwave.rb
config.enable_processing = false if Rails.env.test?
  • test環境でスキップできるらしいが、ArgumentError: Missing required arguments: aws_access_key_id, aws_secret_access_keyと一生うるさいので追加した
An error occurred while loading ./spec/models/user_spec.rb.
Failure/Error: config.enable_processing = false

NameError:
  undefined local variable or method `config' for PostImageUploader:Class
# ./app/uploaders/post_image_uploader.rb:11:in `<class:PostImageUploader>'
  • 元々uploaderにも分岐書いてたのだけどそれが悪さしてそうなので消す
#uploader
  if Rails.env.development?
    storage :file
  elsif Rails.env.test?
    storage :file
  else
    storage :fog
  end

結果

  • できました。感動。
このスクラップは2ヶ月前にクローズされました