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
と指摘されてしまいます。
CircleCIの値上がりによって、CircleCIからfirebaseにデプロイしていたサイトのCI/CDをGitHub Actionsに乗り換えていたのですが、せっかくなのでこちらの警告にも対応したいと思います。
材料
- GitHab Actionsのworkflowの設定ファイル(yamlファイル)
- GCPのサービス アカウントの認証キー(JSONファイル)
workflowの設定ファイルはFIREBASE_TOKENですでにデプロイ可能になっていることを前提としています。
レシピ
1. GCPのサービス アカウントを作成する
firebaseと紐付いているgoogleアカウントで[サービス アカウントの作成] ページを開きます。すでに、Firebaseでプロジェクト作成済みの方は、「Firebaseコンソール」から[プロジェクトの設定] > [サービス アカウント] > [新しい秘密鍵の生成]からでも次のキーを取得まで実施可能です。
アカウント名もサービスアカウント説明も全部適当でOKです。
アカウントの権限は「Firebase Develop 管理者」にしました。
2. 作成したアカウントからキーを取得
アカウント一覧から作成したアカウントの[キーの管理]を開きます。
キーの管理を開いたら中断にある[鍵を追加]を選択
新しい鍵を作成を選択して、作成形式をJSONにしてください。
作成したらダウンロードが始まるのでローカルの適当なところに保存。
3. キー(JSON)をbase64でエンコード
JSONファイルの扱いですが、認証情報なのでGitHub repositoryのsecretsに登録したいのでbase64で文字列にエンコードします。
cat 〇〇〇〇.json | base64
結果はクリップボードにコピーしておきます。
4. GitHub repositoryのsecretsにエンコード後の認証情報とJSONファイルの生成先を登録
ここからややこしくなっていきます。
対象のレポジトリの[settings]→[secrets]→[actions]から、[New repository secret]を選択して新しいsecretを2つ登録します。
secret | 内容 |
---|---|
GCLOUD_SERVICE_KEY | 先程コピーしたエンコード後の認証情報の文字列 |
GOOGLE_APPLICATION_CREDENTIALS | エンコード後の認証情報をデコードして生成する認証用JSONファイルの保存先・任意で設定できますが今回は先人に習って/tmp/credentials.json と指定しました |
GCLOUD_SERVICE_KEYは任意の名前で利用可能です。GOOGLE_APPLICATION_CREDENTIALSはこの名前で認証時にローカル変数として読まれるため、この時点からこの名前を使うことをおすすめします。
5. workflowの設定ファイルで4で設定したsecretを環境変数として読み込み
環境変数を設定するためにYAMLファイルの上段で以下のコードを記述して下さい。
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
GCLOUD_SERVICE_KEY: ${{ secrets.GCLOUD_SERVICE_KEY }}
するとこんな感じなります。
jobs:
deploy:
env:
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
GCLOUD_SERVICE_KEY: ${{ secrets.GCLOUD_SERVICE_KEY }}
runs-on: ubuntu-latest
6. CI/CD実行時にエンコード後の認証情報をデコードしてJSONに変換
一番面倒なところです。ローカルでエンコードしたJSONファイルをデコードして復活します。
以下の記述をデプロイ直前に追加してください。
# 認証情報を保持するjsonファイルをGOOGLE_APPLICATION_CREDENTIALSで指定したpassに生成
- name: make GOOGLE_APPLICATION_CREDENTIALS
run: echo $GCLOUD_SERVICE_KEY | base64 -d > $GOOGLE_APPLICATION_CREDENTIALS
7. 普通にデプロイ
ここまでやれば認証情報は勝手に読み込まれてくれるみたいなので普通にデプロイしてみましょう
- name: change environments
run: firebase use environment
- name: deploy to hosting
run: firebase deploy
最後に一応認証情報を環境から削除しておきます。
- name: delete GOOGLE_APPLICATION_CREDENTIALS
run: rm $GOOGLE_APPLICATION_CREDENTIALS
if: ${{ always() }}
お疲れさまでした。
まとめるとこんな感じになると思います。
jobs:
deploy:
env:
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
GCLOUD_SERVICE_KEY: ${{ secrets.PROD_GCP_KEY }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
(省略)
- name: install firebase
run: npm install --save-dev firebase-tools
# 認証情報を保持するjsonファイルをGOOGLE_APPLICATION_CREDENTIALSで指定したpassに生成
- name: make GOOGLE_APPLICATION_CREDENTIALS
run: echo $GCLOUD_SERVICE_KEY | base64 -d > $GOOGLE_APPLICATION_CREDENTIALS
- name: change environments
run: |
./node_modules/.bin/firebase use aitcweb-prod
- name: deploy to hosting
run: |
./node_modules/.bin/firebase deploy
# 認証用jsonファイルを削除
- name: delete GOOGLE_APPLICATION_CREDENTIALS
run: rm $GOOGLE_APPLICATION_CREDENTIALS
if: ${{ always() }}
軽くまとめていますが、自分が設定した際はかなり手こずりました。CircleCIからの移行は対したことなかったのですが、思ってなかったところでコケましたね。
それでは。