Firebase Hostingへデプロイする(GitHubActions/GitLab-CI)

# はじめに
gitlab-ciのログを眺めていると以下のような文言を見つけました．
```bash
$ firebase deploy --token $FIREBASE_TOKEN
⚠  Authenticating with `--token` is deprecated and will be removed in a future major version of `firebase-tools`. Instead, use a service account key with `GOOGLE_APPLICATION_CREDENTIALS`: https://cloud.google.com/docs/authentication/getting-started
```
トークンを使用したfirebase deployが将来廃止されるので，代わりにservice account keyを使用しなさいとのことでした．
今までトークンを使用していたのですが，廃止になってから対応するのでは遅いと思いますのでkeyを使った方法の調査および修正を行いました．

調査中，トークンを使用した方法を紹介しているページが多いように感じたので，自分用の備忘録も兼ねて記事の作成に至りました．
Web系開発を始めて2年目ですので，間違いや非効率な箇所がありましたらご指摘いただけますと幸いです．

# 前提条件
デプロイの前に以下が完了していることを確認してください．
- Firebaseでプロジェクトの作成が済んでいる
- Githubのリポジトリ/Gitlabのプロジェクトにdeployするアプリがあり，トークンを使用する方法でdeployが可能

# Google Service Accountからkeyを発行する(共通)
1. firebaseのプロジェクトにアクセスし，プロジェクトの設定ページを開く
1. 画面上部のタブから`サービスアカウント`を選択
1. 右上にある`サービスアカウント権限の管理`をクリック
![firebaseConsole.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736836/ea832f66-f2b9-0900-2a8b-b2eea74048c2.png)
1. 画面上部の`＋サービスアカウントの作成`をクリック
1. サービスアカウント名を入力し，`作成して続行`をクリック
![serviceAccount.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736836/44447c80-5d18-d791-e760-39574dd45739.png)
1. ロールには`Firebase Hosting 管理者`を設定
    - Hostingに使用するアカウントの権限を決めているだけという認識なので，Authenticationの機能を使用していてもこのロールだけで運用しています．問題があるならばご指摘いただきたいです． 
![スクリーンショット 2024-04-20 224535.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736836/6ba1ad51-afa1-4931-2bd4-661f91277fb6.png)
1. `続行`をクリックし，そのまま`完了`をクリック
1. 作成したサービスアカウントの`操作`の項目から，`鍵を管理`を選択
![スクリーンショット 2024-04-20 235246.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736836/0e1a21e6-fc31-24e3-c700-3f9c7322a942.png)
1. `鍵を追加` > `新しい鍵を作成`をクリックし，`JSON`が選択されていることを確認し，`作成`をクリック
1. 鍵が自動でダウンロードされるので，任意の場所に移動させる
1. ダウンロードしたJSONファイルをbase64でエンコードする
    ```bash
    // Ubuntu
    base64 --wrap=0 < {ファイル名}.json
    // Windows
    certutil -f -encode {ファイル名}.json {出力ファイル名}.txt
    ```
1. エンコードした内容は，secret(Github)やCI/CD変数(Gitlab)に保存しておく

# Github Actions
Workflow fileに以下のような内容を記述/追記. private-key.jsonは任意の名称で問題ありません．
```yaml
jobs:
  build_and_deploy:
    runs-on: ubuntu-latest
    env:
      GOOGLE_APPLICATION_CREDENTIALS: pribate-key.json
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v4
      - name: Install Dependencies and Build
        run: yarn install && yarn run build
      - name: Setup Firebase 
        run: yarn global add firebase-tools
      - name: Prepare Google Application Credentials
        shell: bash
        run: |
          echo "${{ secretsに登録した名称 }}" | base64 --decode > "private-key.json"
      - name: Deploy Firebase functions
        shell: bash
        run: firebase deploy --only hosting

      - name: Remove Credentials File
        if: success() || failure()
        run: |
          rm private-key.json
```

# Gitlab CI
gitlab-ci.ymlに以下のような内容を記述/追記．private-key.jsonは任意の名称で問題ありません．
```yaml
firebase:
 stage: deploy
 before_script:
 - echo -n $登録したCI/CD変数の名前 | base64 -d > private-key.json
 - export GOOGLE_APPLICATION_CREDENTIALS="private-key.json"
 script:
 - firebase deploy - only hosting
```

# 感想
業務ではGitLabを使用していますが、自学用にGitHubでコード管理しているので、両方でのHostingについて書いてみました。
どちらか一方についてしか触れていないページが多く感じたので、両方に触れている人にとって有益な投稿になればと思います。

初投稿かつ、初アウトプットをやってみましたが、自分でよくわかっていない箇所が明確になった気がするので今後も続けていけたらと思っています。

# 参考
[How to Deploy Firebase Functions in CI using a Service Account Key with GOOGLE_APPLICATION_CREDENTIALS](https://medium.com/@jankir/how-to-deploy-firebase-functions-in-ci-using-a-service-account-key-with-801be78251cf)