🤙

【React】GitHub ActionsでFirebase Hostingに自動デプロイしてみた

2021/12/06に公開約11,700字1件のコメント

GitHub ActionsでFirebase Hostingに自動デプロイする記事はたくさんあります。
ですが、多くの記事では自分でGitHubのsecret変数にトークンを登録したり、ymlファイルを作成したり、と初学者にはなかなか難しい内容です。
この記事では超簡単に出来る方法を書きました。いくつかの注意すべき点を気をつければ誰でもできます。

環境

macOS : Monterey 12.0.1
Node : 14.18.1
npm : 6.14.15
Firebase CLI : 9.23.0

Firebase CLIのインストールはこちら

npm
npm install -g firebase-tools
yarn
yarn global add firebase-tools

1.プロジェクトを用意する

CreateReactApp

まずはReactのプロジェクトを用意しましょう。

npx create-react-app firebase-hosting-deploy

Firebaseのインストール

プロジェクトができたら作成したプロジェクトのディレクトリに移動してFirebaseをインストールしておきましょう。

npm
npm install firebase
yarn
yarn add firebase

2.Firebaseのプロジェクトを作成する

新しいプロジェクトを作成

FIrebaseの公式サイトからプロジェクトを作成します。

FirebaseNewProject
今回はfirebase-hosting-deployというプロジェクトにしました。

Googleアナリティクス
Googleアナリティクスが必要な人は有効にしてプロジェクトを作成してください。

アプリの追加

FirebaseProject
プロジェクトが作成できたらアプリにFirebaseを追加します。
今回はReactなのでウェブを選択します。(赤枠のボタンをクリック

newApp
アプリ名を入力してアプリを登録をクリックします。
「このアプリのFirebase Hostingも設定します。」のチェックも入れておいてください。

FirebaseSDK
続いてFirebaseをインストールするように言われますが、これはもう実施したので飛ばします。
FireStore等の機能を使用する人はfirebaseConfig(赤枠の部分)をコピーしておいてください。
今回のHostingでは使用しません。

FirebaseCLI
まだFirebase CLIをインストールしていない人はインストールしてください。

FirebaseHosting
最後にFirebase Hostingへのデプロイのやり方が書いています。
こちらは次の項目で詳しくやっていきます。

3.Firebase CLIを使ってGitHub Actionsを設定する

Firebaseに接続する

まずはプロジェクトのディレクトリをFirebaseプロジェクトに接続します。

firebase login

を実行すると次のように聞かれます。

Firebase optionally collects CLI usage and error reporting information to help improve our products. Data is collected in accordance with Google's privacy policy (https://policies.google.com/privacy) and is not used to identify you.
訳:FirebaseがCLI使用状況やエラー報告などの情報を勝手に集めて改善に役立てるんやけど、Googleのプライバシーポリシー的なやつに従って集めるし、ユーザー特定とかせんから安心して

Allow Firebase to collect CLI usage and error reporting information? (Y/n)
訳:FirebaseがCLIの使用状況とエラー報告を収集できるようにするけどええ?

あまりにもGoogleに不信感がある人以外はyを入力しましょう。
また、そのままEnterを押すとYesが選択されます。

Googleログイン
ブラウザが立ち上がるとGoogleアカウントでログインする画面が表示されます。
ログインしたらFirebase CLIのアクセスを許可してください。

Successful
この画面が出てくれば成功です。

プロジェクトの初期化

プロジェクトのディレクトリから次のコマンドを実行します。

firebase init

するとデカデカと書かれたFIREBASEに続いて色々と質問されるので順番に答えていきます。

Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter to confirm your choices.
訳:このディレクトリにはどのFirebase機能を使うんか? スペースを押して機能を選択し、Enterキーを押して確定できるで。

◯ Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision default instance
◯ Firestore: Configure security rules and indexes files for Firestore
◯ Functions: Configure a Cloud Functions directory and its files
❯◉ Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys
◯ Hosting: Set up GitHub Action deploys
◯ Storage: Configure a security rules file for Cloud Storage
◯ Emulators: Set up local emulators for Firebase products
(Move up and down to reveal more choices)

今回はFirebase Hostingを目的にしているのでHostingを選びます
2つあるHostingの違いは以下の通りです。

Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys
訳:Firebase Hostingのファイル構成するし、ついでにGitHub Actionのデプロイも設定しとくで

Hosting: Set up GitHub Action deploys
訳:GitHubActionsのデプロイ設定しかせぇへんよ

とりあえず今回は前者のHostingを選択してEnterを押しましょう。

First, let's associate this project directory with a Firebase project.You can create multiple project aliases by running firebase use --add, but for now we'll just set up a default project.
Please select an option: (Use arrow keys)
❯ Use an existing project
Create a new project
Add Firebase to an existing Google Cloud Platform project
Don't set up a default project
訳:最初はこのプロジェクトディレクトリをFirebaseプロジェクトに関連付けるとこからやで。
firebase use --addを実行したら複数のプロジェクトを作成できるけど、とりあえずデフォルトのプロジェクトを設定するだけでええよ。
オプションを選択してくれへん:(矢印キーを使用)
❯既存のプロジェクトを使用する
新しいプロジェクトを作成する
Firebaseを既存のGoogleCloudPlatformプロジェクトに追加します
デフォルトのプロジェクトを設定しないでください

すでにFirebaseのプロジェクトを作成済みなので既存のプロジェクトを使用するを選択します。

Select a default Firebase project for this directory: (Use arrow keys)
訳:このディレクトリのデフォルトのFirebaseプロジェクトを選択してくれへん:(矢印キーを使用)

先程作成したFirebaseのプロジェクトを選択します。

What do you want to use as your public directory?(public)
訳:パブリックディレクトリとして何使う?

デフォルトではpublicフォルダを選択しようとするのですが、Reactなどの事前にビルドが必要なアプリではbuildフォルダに設定しておかないと画面が真っ白になります。
必ずbuildを入力してEnterを押してください。

Configure as a single-page app (rewrite all urls to /index.html)? (y/N)
訳:シングルページアプリとして構成する(すべてのURLを/index.htmlに書き換える)?

Reactの場合、SPAとして構成するのでyと答えます。
そのままEnterするとNoが選択されるので注意してください。

Set up automatic builds and deploys with GitHub? (y/N)
訳:GitHubを使って自動ビルドとデプロイを設定する?

GitHub Actionsの設定をするかどうか聞かれているのでもちろんyと答えます。
そのままEnterするとNoが選択されるので注意してください。

File public/index.html already exists. Overwrite? (y/N)
訳:public/index.htmlはすでに存在してるけど上書きしてええんか?

この質問で上書きしてしまうとindex.htmlがFirebase仕様になり、Reactには欠かせない<div id="root"></div>が削除されてしまいます。
これは大問題なのでnを選択します。そのままEnterでも大丈夫です。

もしYesを選択してしまった場合の対処法

public/index.htmlの<body>タグ内に以下のコードを記述し、それ以外の<body>タグ内のコードを全て削除(orコメントアウト)する。

index.html
<body>
  <div id="root"></div>
</body>

参考記事 React+Firebaseで「Error: Target container is not a DOM element.」

Detected a .git folder at /users/hoge/hoge/firebase-hosting-deploy
Authorizing with GitHub to upload your service account to a GitHub repository's secrets store.
訳:/Users/hoge/hoge/firebase-hosting-deployで.gitフォルダーを見つけたんやけど。
GitHubを使ってアカウントをGitHubリポジトリのシークレットストアにアップロードすることを承認するで。

よくわからないですが、GitHubのアカウント認証を要求されますので指示に従い認証を行ってください。

Successful
この画面が出てくれば成功です。

For which GitHub repository would you like to set up a GitHub workflow? (format: user/repository)
訳:どのGitHubリポジトリをワークフローに設定するねん

フォーマットに合わせて[GitHubのアカウント名]/[リポジトリ名]を入力してEnterを押します。

Created service account github-action-********* with Firebase Hosting admin permissions.
Uploaded service account JSON to GitHub as secret FIREBASE_SERVICE_ACCOUNT_FIR_HOSTING_DEPLOY.
You can manage your secrets at https://github.com/*****/firebase-hosting-deploy/settings/secrets.
訳:FirebaseHostingの管理者権限でgithub-action-*******を勝手に作ったで。
ついでにFIREBASE_SERVICE_ACCOUNT_FIR_HOSTING_DEPLOYとしてGitHubのsecretsにアップロードもしといたわ。
URLでsecrets確認できるで。

この一瞬で結構すごいことをしてくれています。
要約すると「GitHub Actionsがいい感じに動くようにして、さらにGitHubのsecrets(環境変数)にFirebaseとの接続に必要なキー情報を登録したからもう面倒なことは全部終わったで。」って感じです。すごい。

Set up the workflow to run a build script before every deploy? (y/N)
訳:デプロイする前にビルドするように設定しとく?

Reactなどの事前にビルドが必要な場合はyを選択します。
そのままEnterするとNoが選択されるので注意してください。

What script should be run before every deploy? (npm ci && npm run build)
訳:デプロイする前にどのスクリプトを実行したらええん?

npmを使用する場合はそのままEnterを押してください。
yarnを使用する場合はyarn install && yarn run build入力してEnterを押してください

すると自動で.github/workflows/firebase-hosting-pull-request.ymlが作成されます。すごい。

Set up automatic deployment to your site's live channel when a PR is merged? (Y/n)
訳:プルリクエストがマージされたときに本番用のサイトにマージすんのかい?

これは好きなように設定してください。今回はそのままEnterを押してyを選択します。

What is the name of the GitHub branch associated with your site's live channel? (main)
訳:本番用のサイトにマージする場合の対象となるブランチはどれやねん

mainの人もいればmasterの人もいると思いますが、本番環境のブランチを入力してEnterを押してください。

Action required: Visit this URL to revoke authorization for the Firebase CLI GitHub OAuth App:
https://github.com/settings/connections/applications/******
訳:このURLにアクセスしたらFirebaseCLIとGitHubの認証を解除できるで。
Action required: Push any new workflow file(s) to your repo
訳:新しいワークフローファイルをリポジトリにアップしてや。
Writing configuration info to firebase.json...
訳:firebase.jsonに色々書いたで。
Writing project information to .firebaserc...
訳:プロジェクトの情報は.firebasercに書いたで。

Firebase initialization complete!
訳:Firebaseの初期化が完了したで。お疲れさん。

これでやっとFirebaseの初期化が終わりました。

3.firebase deployしてみる

早くGitHub Actionsを使って自動デプロイしたい気持ちを抑えて、まずはfirebase deployコマンドを使って手動でデプロイしましょう。

その前にbuildしてみよう

npm
npm run build
yarn
yarn build

buildをするとbuildファイルが作成されますが、ファイル内のindex.htmlをブラウザで見てみると真っ白な画面になっていると思います。
white

これはpackage.json"homepage": ".",を追加することで解決します。

package.json
{
  "name": "firebase-hosting-deploy",
  "version": "0.1.0",
+ "homepage": ".",
  "private": true,
  // ... 略
}

一度作成したbuildファイルを削除して、もう一度buildしてみましょう。
今度はちゃんと表示されるはずです。

firebase deploy

buildファイルのindex.htmlで表示されることを確認したら実際にデプロイしてみましょう。

firebase deploy

デプロイできたらサイトを確認してみます。
ちゃんと表示されていたら喜んでください。やったー。

GitHubにpushしておく

ここまで出来たらすべての変更履歴をGitHubにpushしておきましょう。

4.GitHub ActionsでFirebase Hostingに自動デプロイしてみる

最後にGitHub ActionsでFirebase Hostingに自動デプロイされるか確認しましょう。
手順は以下の通りです。

  1. mainブランチからdevelopブランチを切る
  2. HTMLファイルを一部修正する
  3. GitHubにpushする
  4. developブランチからmainブランチへプルリクを送る
  5. mainブランチにプルリクをマージする

今回はApp.js<h1>タグを追加しました。

src/App.js
// ...略
  <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
+       <h1>GitHub ActionsでFirebase Hostingに自動デプロイしてみた</h1>
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
// ...略

Pull requests
React
おー!できました!!!
これでdevelopブランチからmainブランチへプルリクを送ったときにプレビューが確認できます。

merge deploy
さらにmainブランチにプルリクをマージしたら本番環境へデプロイされることが確認できました。

https://github.com/alpaca1231/firebase-hosting-deploy

5.おまけ

ESLint使ってるとよくわからないけど、.envファイルにこれ書かないとエラーが出るときありますよね。

.env
SKIP_PREFLIGHT_CHECK=true

これもGitHubのsecretsに登録してあげないとGitHub Actionsでエラー出ちゃうので忘れないように登録しておきましょうね。
(本当はESLintのバージョンに合わせてあげるのが一番いいんだけどね)

参考文献

https://firebase.google.com/docs/hosting/github-integration?hl=ja#:~:text=GitHubプルリクエストを介してライブチャンネルとプレビューチャンネルにデプロイする
https://classic.yarnpkg.com/en/docs/cli/install#:~:text=yarn install --frozen-lockfile
https://zenn.dev/watarukun/articles/8f3e318bacf97cabf879

Discussion

GitHub Actionsの設定部分がすごく参考になりました🙏

ログインするとコメントできます