Netlify → Firebas Hosting に引っ越した際の Github Actions の設定メモ(デプロイ、Slack 通知、キャッシュ、[skip ci])

📆October 02, 2020🔖 Github Actions

Netlify から Firebase Hosting に引っ越しをしました。いままで使用していた Netlify では GUI でポチポチすれば設定完了だったのですが、Netlify を使わなくなってその恩恵を受けられなくなってしまったということもあり、GitHub Actions を用いて CI/CD フローの再構築を行いました。

本記事はその際に行った設定(Firebase Hosting へのデプロイ、Slack 通知、node_modules のキャッシュ、[skip ci])のメモです。細かい GitHub Actions の初期設定に関しては説明するつもりはなく、具体的な各々のワークフローの設定方法について書きます。

デプロイ

Firebase Hosting へのデプロイの覚書です。ここが本記事のメインです。package.json にデプロイスクリプトを書いて、それを実行するようにしました。基本的には GitHub Actions 上でデプロイを行いますが、手元から緊急リリースを作業する際のヒューマンエラー(検証環境用にビルドしたものを本番にデプロイしてしまった、等)の防止の役割も果たしてくれます。

"scripts": {
    "deploy:dev": "yarn generate:dev && firebase deploy --only hosting:dev-admin",
    "deploy:prod": "yarn generate:prod && firebase deploy --only hosting:prod-admin"
  },

手元からデプロイする際は、手元の CLI で Firebase にログイン済の状態であればデプロイできるのですが、GitHub Actions 上のマシンからデプロイするには、キーが必要になります。キーは firebase login:ci コマンドで取得できます。キーのセットは、GitHub 上で行います。今回は FIREBASE_TOKEN という名前でキーをセットしました。

GitHub 上で Secrets を登録
GitHub 上で Secrets を登録

そして、yml を書いていきます。途中は省略しますが、以下のような 2STEP で、依存パッケージのインストールを行い、ビルド・デプロイを走らせます。yarn workspace を用いたモノレポ構成になっているので、以下のように、都度パッケージを移動しています。

- name: SETUP
  run: |
    cd ./packages/[package-name]
    yarn install
    yarn global add firebase-tools
- name: BUILD & DEPLOY
  run: |
    cd ./packages/[package-name]
    yarn deploy:prod --only hosting:prod-[package-name] --token $FIREBASE_TOKEN
  env:
    FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}

env でさきほどセットした secrets から FIREBASE_TOKEN を読み込むようにしており、実行時に —token を付けて渡しています。

develop ブランチへの push の際は検証環境、master ブランチへの push の際は本番環境にデプロイされるようにしています。prod-[package-name] の部分で切り替えられるようにしていますfirebasercfirebase.json にその設定が書かれています(本記事の主旨とは外れるので割愛)

キャッシュを挟む

actions/cache@v2 という Action を使用することで、キャッシュを効かせられるようになります。これによって、ビルド・デプロイにかかっていた時間が、1/3 程度まで短縮することができました。幸せ。

ビルド・デプロイ時間が削減された
ビルド・デプロイ時間が削減された

以下のようなアクションを yarn install よりも前に書いておくとキャッシュが効くようになります。

- uses: actions/cache@v2
  id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
  with:
    path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
    key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
    restore-keys: |
      ${{ runner.os }}-yarn-

Slack 通知

Netlify は通知時に failure と cancel の区別ができなかったのですが、Github Actions だと出来るっぽくて幸せでした(GitHub Actions だと failure のときだけ通知を飛ばせる)。

Slack 通知は以下のように rtCamp/action-slack-notify を使わせてもらい、アクションを設定しました。例によって、env で secrets から Slack の Webhook URL を読み込んでいます。

- name: Slack Notification Success
  uses: rtCamp/action-slack-notify@v2.0.0
  if: success()
  env:
    SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
    SLACK_CHANNEL: ci_dev_deploy_front
    SLACK_USERNAME: DEPLOY PRODUCTION (calchez-frontend)
    SLACK_COLOR: good
    SLACK_TITLE: 🚀 Deploy Success!!
- name: Slack Notification Failure
  uses: rtCamp/action-slack-notify@v2.0.0
  if: failure()
  env:
    SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
    SLACK_CHANNEL: ci_dev_deploy_front
    SLACK_USERNAME: DEPLOY DEVELOPMENT (calchez-frontend)
    SLACK_COLOR: danger
    SLACK_TITLE: 🤮 Deploy Failure!!

success()failure() は GitHub Actions が用意してくれている関数で、それぞれ名前の通りですが成功時と失敗時にのみ実行させるアクションを定義することができます(最高)

参考: ジョブステータスのチェック関数

[skip ci]

他の CI ツールにあるような、コミットメッセージに [skip ci] と付けると、ワークフローの実行を skip するという設定を入れました。

以下のように、 skipci がどうかをログに出力するようにしたのと、build 内で判定して、[skip ci] という文字列が入っていれば、ビルドをスキップするというプロセスにしてあります。これ地味に便利なのでオススメ。

skipci:
  runs-on: ubuntu-18.04
  steps:
    - run: echo "[skip ci] ${{ contains(github.event.head_commit.message, '[skip ci]') }}"
build:
  runs-on: ubuntu-latest
  if: contains(github.event.head_commit.message, '[skip ci]') == false


GitHub Actions 便利なのでみなさんもぜひ🙌