Firebase、GitHub Actions連携
背景
- 以前にReact(TypeScript) + Firebaseでメモアプリ開発でReactで作ったメモアプリをFirebaseにホスティングした
- ただ、ホスティングの手順は以下のようになっており少々面倒(さらに言えば、これとは別にGitHubへのPushも行っている)
- ローカルでReactをビルド(
npm run build
) - firebase initを行ったディレクトリ直下の公開用ディレクトリ(dist)に、/distディレクトリの中身をコピー
-
firebase deploy
コマンドでデプロイ
- ローカルでReactをビルド(
- なので、GitHubにPushすると、そのままFirebaseにデプロイするようにする(GitHub Actionsを使って)
手順
Firebase公式のGitHub pull リクエストによるライブチャネルとプレビュー チャネルへのデプロイに従い作業しました。
-
firebase init hosting
は実行済だったので初めにfirebase init hosting:github
を実行 - GitHubのリポジトリー名を聞かれるので予め利用していたリポジトリー
shoji9x9/memo-app
を入力 -
Set up the workflow to run a build script before every deploy?
はReactのビルドをするためY(Yes)
-
What script should be run before every deploy?
はnpm ci && npm run build
-
Set up automatic deployment to your site's live channel when a PR is merged?
はY(Yes)
-
What is the name of the GitHub branch associated with your site's live channel?
はmain
上記質問の意味はFirebase公式のGitHubとHostingのインテグレーションが熱いがわかりやすかったです。
上記手順の結果どうなる?
これもFirebase公式のGitHubとHostingのインテグレーションが熱いに書かれていますが、次の2つが行われます。
- GitHub Actionsの定義ファイル(.yml)を作成してくれる
- GitHub Actions用の認証情報を生成、登録してくれる
早速Pushしてみる
ご参考:実行時のディレクトリ構成
memo-app
├── README.md
├── package-lock.json
├── package.json
├── public
├── src
└── firebase
├── firebase.json
Push時に動くワークフローは?
Push時にはfirebase-hosting-merge.ymlのワークフローのみが動き、firebase-hosting-pull-request.yml(Pull request作成時にプレビューサイトにデプロイする処理)は動きませんでした(Pull requestを作成していないので当たり前ですが)。
firebase.jsonが見つからないエラーが発生
ビルド時に Error: firebase.json file not found. If your firebase.json file is not in the root of your repo, edit the entryPoint option of this GitHub action.
というエラーが発生したため、firebase-hosting-merge.ymlにentryPointを追加しました。firebase-hosting-pull-request.ymlも念のため同様に修正しています。
# This file was auto-generated by the Firebase CLI
# https://github.com/firebase/firebase-tools
name: Deploy to Firebase Hosting on PR
"on": pull_request
jobs:
build_and_preview:
if: "${{ github.event.pull_request.head.repo.full_name == github.repository }}"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: npm ci && npm run build
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: "${{ secrets.GITHUB_TOKEN }}"
firebaseServiceAccount: "${{ secrets.FIREBASE_SERVICE_ACCOUNT_VITE_REACT_F4C90 }}"
projectId: vite-react-f4c90
entryPoint: "firebase" # ここを追加
publicディレクトリーが見つからないエラーが発生
ビルド時に "error": "Directory 'dist' for Hosting does not exist."
というエラーが発生しました。firebase.jsonは以下のように定義されており、"hosting"."public"
の値は
fierbase init
を実行したディレクトリ(今回だとfirebase)を基準としたときの相対パスとなるため、これを "../dist"
(npm run build
の実行結果が格納されるディレクトリ)に変更したくなります。ただ、その場合エラーとなってしまうため、反対に npm run build
の実行結果を firebase/dist
に格納するようvite.config.tsにoutDirを追加しました。
"hosting": {
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
build: {
outDir: "firebase/dist", // ここを追加
},
});
デプロイはできたが実行時にエラーが発生
ブラウザのコンソールに Uncaught FirebaseError: Firebase: Error (auth/invalid-api-key).
というエラーが出力されました。元々React(SPA)アプリをFirebase Hostingにデプロイなどを参考にfirebaseConfigの値は環境変数として別ファイルで管理し、そのファイルはGitHubにはPushしていませんでした。そのためこれらの値を利用できずエラーが発生していました。
Firebase apiKey ってさらしていいの? ほんとに?を見ると一応このファイルをGitHubにPushしてもよさそうではありますが、不必要なリスクは犯したくないのでNext.jsで作ったポートフォリオにLAPRASのプレビューを追加で学んだばかりのシークレットを利用することにしました。GitHubのリポジトリーのSettingsからRepository secretsを追加し、firebase-hosting-merge.ymlとfirebase-hosting-pull-request.ymlに以下のようにenvを追加しました。
# This file was auto-generated by the Firebase CLI
# https://github.com/firebase/firebase-tools
name: Deploy to Firebase Hosting on merge
"on":
push:
branches:
- main
jobs:
build_and_deploy:
runs-on: ubuntu-latest
env: # ここを追加
VITE_FIREBASE_API_KEY: ${{ secrets.VITE_FIREBASE_API_KEY }}
VITE_FIREBASE_AUTH_DOMAIN: ${{ secrets.VITE_FIREBASE_AUTH_DOMAIN }}
VITE_FIREBASE_PROJECT_ID: ${{ secrets.VITE_FIREBASE_PROJECT_ID }}
VITE_FIREBASE_STORAGE_BUCKET: ${{ secrets.VITE_FIREBASE_STORAGE_BUCKET }}
VITE_FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.VITE_FIREBASE_MESSAGING_SENDER_ID }}
VITE_FIREBASE_APP_ID: ${{ secrets.VITE_FIREBASE_APP_ID }}
VITE_FIREBASE_MEASUREMENT_ID: ${{ secrets.VITE_FIREBASE_MEASUREMENT_ID }}
steps:
- uses: actions/checkout@v3
- run: npm ci && npm run build
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: "${{ secrets.GITHUB_TOKEN }}"
firebaseServiceAccount: "${{ secrets.FIREBASE_SERVICE_ACCOUNT_VITE_REACT_F4C90 }}"
channelId: live
projectId: vite-react-f4c90
entryPoint: "firebase"
今回はこのように対応しましたが、自動で登録されたシークレットFIREBASE_SERVICE_ACCOUNT_VITE_REACT_F4C90
から上記環境変数の情報を取得できそうな気もします。また調べてみます。
2023/10/1追記:上記シークレットの内容を確認したがAPI Keyなどは含まれていなかったため、当初通りAPI Keyなどを個別にシークレットに登録する必要がありそう。
コード
アプリケーション
今後の予定
- React Hook Form、Zodの利用
- Functions、Messagingなどのまだ利用していないFirebaseの機能を試す
Discussion