【ブランチ毎】Cloud Functions for FirebaseをGitHub Actionsで本番環境・検証環境に自動デプロイする

スマホアプリのバックエンドとして使っているFirebaseのCloud FunctionsをGitHub Actionsで自動デプロイできるようにしましたので、その方法を共有したいと思います。
今回行ったのは、mainブランチにpushすると本番環境のプロジェクトにデプロイ、stagingブランチにpushすると検証環境のプロジェクトにするようなワークフローです。

「このやり方の方がいい！」「間違っている！」等ございましたら、コメントでぜひお知らせください。

# 前提

以下のような前提で話を進めていきたいと思います。

- Firebaseで本番環境用・検証環境用のプロジェクトがそれぞれ作成されていること
- Cloud Functionsは既に作成して手動でデプロイをしたことがあること
- FunctionsのプロジェクトがGitHubに置いてあること

また、以下のようなディレクトリ構成で行いました。

``` ディレクト構成:ディレクトリ構成
├─functions
|  ├─eslintrc.json
|  ├─.gitignore
|  ├─index.json
|  ├─package-lock.json
│  └─package.json
├─.firebaserc
├─.gitignore
└─firebase.json            
```

# Workflowファイルの作成

1. GitHubでFunctionsのコードを置いてあるリポジトリのページにいく
1. Actionsタブから新しくworkflowを作成するページを開く
(自分の場合は以下の画像の赤枠の箇所をクリックで開きました) 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486544/132c116d-77d8-546a-b430-f5a3b350a010.png)
1. `main.yml`ファイルのエディタが出てくるのでこれを編集して自動デプロイが行えるようにする。

# Actions secretsの設定
Workflowを書いていく上で必要なFirebaseトークンと、プロジェクトIDをActions secretsに設定します。

1. リポジトリの設定タブを開く
1. Secretsから`New repository secrets`をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486544/f7ce9f4e-0f21-a675-166a-bb3fbb5a21c1.png)
1. Nameに`FIREBASE_TOKEN`、Valueに`firebase login:ci`によって取得したトークンを入力
1. 同様に`PROJECT_ID_MAIN`、`PROJECT_ID_STAGING`をそれぞれ設定する。
(プロジェクトIDの確認方法: [Firebase プロジェクトについて理解する](https://firebase.google.com/docs/projects/learn-more?hl=ja#:~:text=%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%20ID%20%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B,%E3%83%9A%E3%82%A4%E3%83%B3%E3%81%AB%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82))

# Workflowを書いていく
最終的に以下のようなコードを書きました。

```yml:.github/workflows/main.yml
name: CI

# 起動のトリガーをmainかstagingブランチにpushされた時としている
on:
  push:
    branches:
      - main
      - staging

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

jobs:
  deploy:
    name: Deploy
    # 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
      - uses: actions/checkout@v2
      - name: Install npm packages
        run: |
          cd functions
          npm install
      # pushがあったのがstagingの時に、PROJECT_IDにPROJECT_ID_STAGINGの値をセット
      - name: Set project id (staging)
        if: contains(toJSON(github.ref), 'staging')
        run: |
          echo PROJECT_ID=${{ secrets.PROJECT_ID_STAGING }} >> $GITHUB_ENV

     # pushがあったのがstagingの時に、PROJECT_IDにPROJECT_ID_STAGINGの値をセット
      - name: Set project id (main)
        if: contains(toJSON(github.ref), 'main')
        run: |
          echo PROJECT_ID=${{ secrets.PROJECT_ID_MAIN }} >> $GITHUB_ENV
    # w9jds/firebase-actionを利用してfirebaseにデプロイ
      - name: Deploy to Firebase
        uses: w9jds/firebase-action@master 
        with:
            args: deploy --only functions
        env:
          FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
          PROJECT_ID: ${{env.PROJECT_ID}}
```

# 参考

https://mdabdulhalimrafi.medium.com/automate-firebase-functions-deployment-with-github-actions-ci-a0eb10fa308d

https://zenn.dev/uta_mory/articles/14e358a2dbf6e47400dc

https://dev.classmethod.jp/articles/github-actions-workflow-for-each-branch-into-one/