firebaseでホスティングしたNext.jsをGithubActionsでCI/CDする

VercelやNetlifyは使ったことありますが、
最近はGoogleCloudが提供しているfirebaseでホスティングするのが主流と聞いて、
せっかくなのでNext.jsで作ったWebアプリをホスティングしてみようと思いました。

さらにGitHub Actionsを使えば本番ブランチにプッシュされると同時にFirebaseにデプロイもされるということなので
この機会に全部やってしまおうと思った次第です。

# Firebaseでプロジェクトを作成する

Firebaseのコンソールにアクセスしてプロジェクトを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/5404fc16-f8e3-6b4d-86b9-8e95fbc67c10.png)
<br>

プロジェクト名を決める
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/191607e9-442a-446b-a14f-b65df8cc4938.png)
<br>

GoogleAnalyticsの設定をする（やらなくても良い）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/864c1bb9-4874-3286-7b7d-e35d29379f1d.png)
<br>

GAのアカウント名を決める
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/ee36e242-81f3-b820-00e9-bc677e93311d.png)
<br>

地域と設定、規約への同意を入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/752289d9-d7c5-cb5f-a5eb-d1b3ef9a6684.png)
<br>

プロビジョニングが終わるまで待つ（1分くらい）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/0673e5d8-7af1-bf67-4788-88f42a79e1d0.png)
<br>

Webアプリをホスティングする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/5fb213be-bc49-f18a-2796-f535014afebc.png)
<br>

Webアプリ名を入力する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/9cdafe2b-56a1-cf1b-c743-d7f676cd1a4e.png)
<br>

# Next.jsをFirebaseにデプロイする
ターミナルでNext.jsのプロジェクトを作成する
```
% npx create-next-app@latest --typescript PROJECT_NAME
...
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like your code inside a `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to use Turbopack for next dev? … No / Yes
✔ Would you like to customize the import alias (@/* by default)? … No / Yes
...
Success! Created 〜〜〜
```
<br>

ターミナルでFirebase CLIをインストールする
```
% npm install -g firebase-tools

changed 642 packages in 24s

69 packages are looking for funding
  run `npm fund` for details
%
```
<br>

ターミナルでFirebaseにログインする
```
% firebase login
```
<br>

プロジェクトを開始する
```
% firebase init

# 「→」の先の文言が選択した選択肢です
? Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter to confirm
your choices. 
→Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys

=== Project Setup

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 an existing project
? Select a default Firebase project for this directory: →my-pf-site (my-pf-site)
i  Using project my-pf-site (my-pf-site)

=== Hosting Setup
? Detected an existing Next.js codebase in the current directory, should we use this? →Yes

? In which region would you like to host server-side content, if applicable? →asia-east1 (Taiwan)
# 日本から一番近い場所を選んだ方が遅延も少なくなるので台湾を選択

? Set up automatic builds and deploys with GitHub? No
# ここは後で設定する

i  Writing configuration info to firebase.json...
i  Writing project information to .firebaserc...

✔  Firebase initialization complete!
```
<br>

FirebaseにWebフレームワークであること（=デプロイ時にビルドが必要なプロジェクト）を認識させる
```
firebase experiments:enable webframeworks
```
<br>

デプロイできるかここで確認する
```
% firebase deploy

Error: Your project my-pf-site must be on the Blaze (pay-as-you-go) plan to complete this command. Required API artifactregistry.googleapis.com can't be enabled until the upgrade is complete. To upgrade, visit the following URL:
```
無料プランじゃデプロイできないみたいなのでBlaze（従量課金プラン）に変更する
続きに記載されているURLからプランを変更する
<br>
<br>

プラン変更後、再度デプロイする
```
% firebase deploy

✔  Deploy complete!
Project Console:〜〜〜
Hosting URL:〜〜〜
```
Hosting URLからデプロイ結果を確認できる
<br>

Next.jsのプロジェクトがデプロイできた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/fbd5d574-bf22-de6c-7fb1-f7183db2726d.png)


# GitHub ActionsでCI/CDを設定する

GitHubでリポジトリを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/71213f71-913b-7373-bc33-0f6fab96b573.png)
<br>

Firebase HostingでGithub Actionsを有効化する
```
% firebase init hosting:github

? For which GitHub repository would you like to set up a GitHub workflow? (format: user/repository) nekihcom/REPO_NAME

# デプロイされる前に毎回ビルドしますか？
? Set up the workflow to run a build script before every deploy? Yes

# ビルド前にどのようなスクリプトを実行しますか？
? What script should be run before every deploy? npm ci && npm run build

# プルリクがマージsれるときに本番環境に自動デプロイしますか？
? Set up automatic deployment to your site's live channel when a PR is merged? Yes

# 本番環境に適用するブランチは何ですか？
? What is the name of the GitHub branch associated with your site's live channel? main

✔  Firebase initialization complete!
```
<br>

プロジェクトに作成された.firebaseを追跡対象外にする
容量がかなり多いのでコミットに含めないようにする
```diff:.gitignore
+ /.firebase/
```
<br>

試しに適当にpage.tsxを編集してみる（デプロイ確認用）
```diff:src/app/page.tsx
          <li>
            Get started by editing <code>src/app/page.tsx</code>.
          </li>
          <li>Save and see your changes instantly.</li>
+          <li>デプロイテストします。</li>
```
ここまでできたらコミット&プッシュする
<br>

# トラブルシュート
GitHubでデプロイ結果を確認する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/dc98c382-6ec9-24a2-0fc0-a455ad934775.png)
う〜ん、、、失敗しているので結果を確認する
<br>

設定変数が足りないよって言われている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/5aa744fc-a9fc-8dfe-5ea3-def93e5defc7.png)

```
Error: Cannot deploy a web framework from source because the experiment webframeworks is not enabled. To enable add a FIREBASE_CLI_EXPERIMENTS environment variable to .github/workflows/firebase-hosting-merge.yml, like so: 
  
  - uses: FirebaseExtended/action-hosting-deploy@v0
    with:
      ...
    env:
      FIREBASE_CLI_EXPERIMENTS: webframeworks
```
<br>

.github/workflowsにあるCI/CDの設定ファイルを編集する
```diff:firebase-hosting-merge.yml
    with:
     ...
+   env:
+    FIREBASE_CLI_EXPERIMENTS: webframeworks
```
firebase-hosting-pull-request.ymlも同様に編集する
<br>

再度コミット＆プッシュ
しかしまた失敗
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/5d25ed69-737d-d206-9c97-194d9057307e.png)

```
Cloud Billing API has not been used in project 817697110686 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/cloudbilling.googleapis.com/overview?project=817697110686 then retry. 
If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
```
Cloud Billing APIを有効化する必要があるらしい
記載のURLにアクセスする
<br>

APIを有効にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/d59b407d-2507-6b42-cc48-671d7a2b1906.png)
<br>

保存して再度デプロイ
→デプロイ成功！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/1f816f6d-ea2d-a3f8-f4cd-c40798d1f262.png)
<br>

アプリの本番環境へアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/d7d9eab5-2419-41f0-dee4-24a626915404.png)
先ほどのpage.tsxの修正が反映されていることも確認できた！


# 参考

https://firebase.google.com/docs/hosting/quickstart?hl=ja

https://siamcats.hateblo.jp/entry/2023/12/19/210226

https://zenn.dev/watarukun/articles/8f3e318bacf97cabf879