今回はCI/CDサービス「CircleCi」を使い、Railsで作成したアプリをGitiHubへpushした際に自動テストおよびHerokuへの自動デプロイが行われるようにする手順を書いていきたいと思います。

実現したいもの

Railsでアプリを開発→ GitiHubへpushする → CircleCiで自動的にテストが行われる → テストに通過した場合、自動的にHerokuへのデプロイが行われる

前提条件

  • GitiHubとCircleCIが連携済みである事
  • Heroku側にアプリが作成済みである事

※それぞれの詳しい方法についてはここでは触れませんので、各自ググるなりして準備しておいてください。

実際の手順

では、具体的な手順について解説していきます。

デプロイキーの確認

念のため、GitHubに登録されているデプロイキーとCircleCIに登録されているデプロイキーが一致するかを確認しておきます。

GitHub

CircleCI

 

両者の「Fingerprint」という項目が一致していればOKです。

HerokuのAPIキーなどをCircleCIへ登録

次に、HerokuへアクセスするためのAPIキーやアプリ名などを環境変数としてCircleCI側へ埋め込んでいきます。

Heroku

Herokuへログインし、右上のユーザーアイコンをすると「Account settings」という項目が出てくるのでこちらをクリック。すると下の方に「API Key」があるのでこちらの値をメモしておきましょう。

※右の「Reveal」というボタンを押すと値が表示されます。

 

CircleCI

CircleCIへログインし、該当のリポジトリ内のsettings → Environment Variablesから先ほどのAPIキーとアプリ名をそれぞれ「HEROKU_API_KEY」「HEROKU_APP_NAME」といった形で埋め込みます。

.circleci/config.ymlを作成

最後に、ルートディレクトリに「.circleci」という隠れディレクトリを作成し、その中に「config.yml」というファイルを記述していきます。

 

人によって書き方は違うかと思いますが、僕の場合はこんな感じで中身を書きました。 内容が良く分からない場合はそのままコピペでOKです。

version: 2
jobs:
  build:
    parameters:
      assets_precompile:
        description: "Whether or not do assets:precompile"
        type: boolean
        default: false
    docker:
      - image: circleci/ruby:2.6.3-node # バージョンについては適宜変更
        environment:
          BUNDLE_PATH: vendor/bundle
          BUNDLER_VERSION: 2.0.1
      - image: circleci/mysql:5.7
        environment:
          MYSQL_DATABASE: base_project_test
    steps:
      - run: gem install bundler -v $BUNDLER_VERSION
      - checkout
      - restore_cache:
          keys:
            - bundle-v2-{{ checksum "Gemfile.lock" }}
            - yarn-v1-{{ checksum "yarn.lock" }}
      - run: bin/bundle check || bin/bundle install --deployment
      - run:
          name: install yarn dependencies
          command: bundle exec yarn install
      - save_cache:
          key: bundle-v2-{{ checksum "Gemfile.lock" }}
          paths:
            - vendor/bundle
      - save_cache:
          key: yarn-v1-{{ checksum "yarn.lock" }}
          paths:
            - node_modules
      - run:
          command: bin/rake db:create db:migrate
          environment:
            RAILS_ENV: test

      - run: bin/bundle exec rubocop
      - run: bin/bundle exec rails_best_practices
      - run: bundle exec brakeman -5 -A -w 1 -e -z
      - run:
          name: run tests
          command: |
            bundle exec rspec --format progress \
                            --format RspecJunitFormatter \
                            --format progress
      - store_artifacts:
          path: coverage

      - persist_to_workspace:
          root: .
          paths:
            - .

  deploy:
    docker:
      - image: circleci/ruby:2.6.3-node # バージョンについては適宜変更
    working_directory: /tmp/repo
    steps:
      - checkout
      - run:
          name: 'Install Heroku CLI, if necessary'
          command: |
            if [[ $(command -v heroku) == "" ]]; then
              curl https://cli-assets.heroku.com/install.sh | sh
            else
              echo "Heroku is already installed. No operation was performed."
            fi
      - run:
          name: heroku maintenance on
          command: heroku maintenance:on --app ${HEROKU_APP_NAME}
      - run:
          name: Deploy to Heroku_Production
          command: |
            git push https://heroku:$HEROKU_API_KEY@git.heroku.com/$HEROKU_APP_NAME.git master
      - run:
          name: heroku maintenance off
          command: heroku maintenance:off --app ${HEROKU_APP_NAME}

workflows:
  version: 2
  build-deploy:
    jobs:
      - build
      - deploy:
          requires:
            - build # デプロイ前に必ずテストを行う
          filters:
            branches:
              only:
                - master # masterブランチが変更された場合のみデプロイを実行

 

以上の設定により、GitHubへプッシュした際には自動テストが走り、変更点がmasterブランチへ反映されるたびにHerokuへの自動デプロイが行われるようになります。

 

 

なお、デプロイの最中にアプリへアクセスすると次のような画面が現れますが、これはHerokuがメンテナンスモードに切り替わっているだけなのでご安心ください。エラーではないので、時間経過とともに元に戻ります。

おすすめの記事