CircleCIからGithubブランチ別にHerokuの本番環境とステージング環境に自動デプロイする

#初めに

CircleCIとGithubの連携によってテストとデプロイを自動化したい。

* Githubのstagingブランチにpush操作 → CircleCI上でテストを実施 → Herokuのステージング環境にデプロイ
* stagingブランチをmasterにマージ操作 → CircleCI上でテストを実施 → Herokuの本番環境にデプロイ

[サンプルソース （APIモードのRailsアプリ）](https://github.com/fukuyama012/reminder_api/tree/sample)

#前提

* HerokuにてWebアプリ作成コマンド実行済み(ステージング、本番環境の2つ)
* アプリ動作に必要なHerokuアドオン(DB等)追加コマンド実行済み
* アプリ動作に必要なHeroku環境変数(DBへの接続情報等)が設定されている
* Rails等でmigrationが必要な場合はHeroku用Procfileに記述済み
* CircleCIアカウントサインアップ済み

[前提状態への参考手順](https://qiita.com/fukuyama012/items/a09627e60718ee94bbe2)

#手順

## CircleCIにて対象Githubリポジトリを連携する

CircleCI管理画面にログイン後、対象リポジトリのSet Up Projectをクリックする。

![ci1.png](https://qiita-image-store.s3.amazonaws.com/0/307773/42804001-6aff-162d-2c8d-1b25bc400131.png)

Start buildingをクリックしリポジトリとの連携を開始する。

![ci2.png](https://qiita-image-store.s3.amazonaws.com/0/307773/2a40f882-c8db-ca16-dffd-d63d38fa1a7c.png)


## CircleCIの環境変数にHerokuへのアクセス情報を設定

Herokuの管理画面にログインしAccount Settingを開き、API Keyを確認しメモっておく。(Revealクリックで確認出来る)

![ci3.png](https://qiita-image-store.s3.amazonaws.com/0/307773/465e32e8-fc08-1f49-1310-f6546b612b13.png)

CircleCI管理画面にて連携済みリポジトリのプロジェクト設定を開き、環境変数を設定する。

![ci4.png](https://qiita-image-store.s3.amazonaws.com/0/307773/ad96c1e1-f4c3-bda2-ae20-b7a034b48866.png)


|名前|値|
|:-:|:-:|
|HEROKU_API_KEY|メモしたAPI Key情報|
|HEROKU_APP_NAME_PROD|Herokuで作成したアプリ名(本番環境)|
|HEROKU_APP_NAME_STAGING|Herokuで作成したアプリ名(ステージング環境)|

＊項目の名前は後述のconfig.ymlと合わせれば任意で良い。

## GithubリポジトリへCircleCIのconfig.ymlを追加する

```yaml:.circleci/config.yml
version: 2
jobs:
  build:
    machine:
      image: circleci/classic:edge # volume指定含めたdocker-composeが利用可能
    steps:
    - checkout
    - run:
        name: init_container.sh # rails newやbundle installしている（詳しくはリポジトリ確認して下さい）
        command: sudo bash init_container.sh
    - run:
        name: up_service.sh #　db create migrate後にdocker-compose up
        command: bash up_service.sh
    - run:
        name: exec rspec #　rspec実行 テスト結果をHTML出力
        command: docker-compose run app bundle exec rspec --format p --format html --out test-results/rspec.html
    - store_artifacts: #　テスト結果をビルド情報画面で確認出来る様に格納先を指定
        path: myapp/test-results/rspec.html
        destination: rspec.html
    - run:
        name: docker-compose down
        command: docker-compose down
  deploy-staging: # ステージング環境への実行内容
    machine:
      image: circleci/classic:edge
    steps:
    - checkout
    - run:
        name: heroku maintenance on
        command: heroku maintenance:on --app ${HEROKU_APP_NAME_STAGING}
    - run:
        name: heroku deploy # push方式でアップしている。アプリ本体はサブディレクトリに有るのでsubtreeやprefix指定する
        command: |
          git subtree push --prefix myapp  https://heroku:$HEROKU_API_KEY@git.heroku.com/$HEROKU_APP_NAME_STAGING.git master
    - run:
        name: heroku maintenance off
        command: heroku maintenance:off --app ${HEROKU_APP_NAME_STAGING}
  deploy-prod: #本番環境への実行内容　Herokuアプリ名の環境変数値だけが違う
    machine:
      image: circleci/classic:edge
    steps:
    - checkout
    - run:
        name: heroku maintenance on
        command: heroku maintenance:on --app ${HEROKU_APP_NAME_PROD}
    - run:
        name: heroku deploy
        command: |
          git subtree push --prefix myapp  https://heroku:$HEROKU_API_KEY@git.heroku.com/$HEROKU_APP_NAME_PROD.git master
    - run:
        name: heroku maintenance off
        command: heroku maintenance:off --app ${HEROKU_APP_NAME_PROD}
workflows:
  version: 2
  build_and_deploy:
    jobs:
    - build
    - deploy-staging:
        requires:
        - build # デプロイ前にテスト必須とする
        filters:
          branches:
            only: staging # stagingブランチの変更に対してのみdeploy-stagingジョブ実行
    - deploy-prod:
        requires:
        - build
        filters:
          branches:
            only: master # masterブランチの変更に対してのみdeploy-prodジョブ実行
```

以上でconfig.ymlにて指定したブランチにpushやpull request mergeが行われた時にテストとデプロイが自動実行される。

# その他

## テスト結果確認方法

CircleCIのbuild情報画面のArtifactsタブに表示されるリンクをクリックするとテスト結果が確認出来る。

![ci5.png](https://qiita-image-store.s3.amazonaws.com/0/307773/1fa035c5-3ae8-e614-560d-ecc2cfea0186.png)


## CircleCIでの結果ログ閲覧権限について

Github publicリポジトリのcommitログに表示されるCircleCIへのリンクからbuild情報が誰でも確認出来る状態になっている。（HerokuアプリのURL情報等も公開状態となる）

上記build情報を非公開にする場合はCircleCI管理画面にて連携済みリポジトリのプロジェクト設定を開きAdvanced SettingからFree and Open Sourceの項目をoffにしておく。

![ci6.png](https://qiita-image-store.s3.amazonaws.com/0/307773/f86dcf4b-000d-665b-c5d3-07258440e3ba.png)


# 参考

[Configuring CircleCI]
(https://circleci.com/docs/2.0/configuration-reference/)

[CircleCI 2.0を利用してマージされた時にHerokuにデプロイする](https://www.takedajs.com/entry/2018/06/24/174658)

[docker-composeでRailsを開発しCircleCI 2.0でテストしてHerokuにdeployする](https://qiita.com/Kesin11/items/47079bc7f659e71b694c)