GitHub Actionsで React + Firebase のプロジェクトをCI/CDで自動デプロイした話

先日のWebサービスを作った際に2020年にリリースされた`GitHubActions`でCI/CD (継続的インテグレーション/継続的デリバリー)をしてみたので、軽く流れを投稿します。

# CI/CDすることになった経緯

- プロジェクトを修正した後に毎回ビルドとかデプロイを実行するのが面倒なので、自動化したい
- トレンドのCI/CDを使ったことがないので勉強したい

# GitHub Actions設定の流れ
## CI/CDサーバーがFirebaseにアクセスするためのトークンの取得＆環境変数に設定
1. `firebase login:ci`コマンドを実行する。<br>
コンテナや WSL でコマンドを実行する場合は`--no-localhost`オプションを付けておく。
1. ブラウザが立ち上がるのでgoogleアカウント認証する。
1. トークンが表示されるので、コマンドラインにトークンを入力する。
1. コマンドラインにCI/CDサーバーに登録するトークンが表示される。
1. GitHubの`Settings`タブ → `Secrets` から`Name=FIREBASE_TOKEN_PROD,value=コマンドラインに表示されたトークン`を追加する。

## CI/CDの設定ファイル作成
1. GitHubの`Actions`タブ → ファイル名を deploy.yml に変更する →`Start Commitボタン`を押す。
1. ワークツリー(GItの作業ディレクトリ)でGit pullし、作業環境にdeploy.ymlを取り込む。
1. ワークツリーで"./.github/workflows/deploy.yml"を開いて設定ファイルを修正する。<br>

```yaml:deploy.yml
# This is a basic workflow to help you get started with Actions
# これは、アクションを開始するのに役立つ基本的なワークフローです。

name: React Firebase CICD

# Controls when the action will run.
# アクションが実行されるタイミングを制御します。
on:
  # Triggers the workflow on push or pull request events but only for the master branch
  # プッシュまたはプル リクエスト イベントでワークフローをトリガーしますが、マスター ブランチのみを対象とします
  push:
    branches: [master]
  pull_request:
    branches: [master]

  # Allows you to run this workflow manually from the Actions tab
  # [アクション] タブからこのワークフローを手動で実行できます
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
# ワークフローの実行は、順次または並行して実行できる 1 つ以上のジョブで構成されます。
jobs:
  # This workflow contains a single job called "build"
  # このワークフローには、「ビルド」と呼ばれる単一のジョブが含まれています
  build:
    # The type of runner that the job will run on
    # ジョブが実行されるランナーのタイプ
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    # ステップは、ジョブの一部として実行される一連のタスクを表します
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      # $GITHUB_WORKSPACE の下にあるリポジトリをチェックアウトして、ジョブがアクセスできるようにします
      - name: Checkout
        uses: actions/checkout@v2

      # Runs a single command using the runners shell
      # runners シェルを使用して単一のコマンドを実行します
      - name: Run a one-line script
        run: echo Start Deploy!

      # Nodeのインストール
      - name: Install Node
        uses: actions/setup-node@v1
        with:
          node-version: 14.16.1

      # runners 依存関係のインストール
      - name: Install Dependencies
        run: |
          npm install
        working-directory: ./

      # ビルド実行
      - name: Build
        run: |
          npm run build
        working-directory: ./

      # テスト実行（テストコードが無い場合はエラーが発生するので、コメントアウトすること。）
       - name: Test
         run: |
           npm test
         working-directory: /

      # デプロイ準備
      - name: Install Firebase Tools
        run: |
          npm install -g firebase-tools
        working-directory: ./

      # デプロイ実行
      # FIREBASE_TOKEN_PRODはGitの環境変数から呼び出される
      - name: Deploy
        env:
          FIREBASE_TOKEN_PROD: ${{ secrets.FIREBASE_TOKEN_PROD }}
        run: |
          firebase deploy --only hosting --token $FIREBASE_TOKEN_PROD
        working-directory: ./

```

## CI/CD実行
1. ワークツリーでgit pushする。
1. GitHubの`Actions`タブを開くと設定したスクリプトが実行されているのが見えるので、コミット名をクリックする。
1. 全てのタスクが成功すると、こんな表示になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/44a1169d-c035-0bcf-916e-fb6f9c1003ee.png)

# 感想など

- CI/CDって名前だけ聞くと難しそうに感じるが実際にやってみると、最低限の機能を動かすだけであれば、そんなに難しくなさそうなことが分かった。
- 設定ファイルはdocker-composeファイルに似ているので既視感を感じる。
- 試していないが、工夫するとデプロイ完了時とか失敗時にSlackとかで通知を送ることができそう。
- 自分の場合、テストコードを書いていなかったので、近日中に試してみたい。