はじめに
GitHub ActionsでReactアプリをFirebaseにCI/CDする手順をまとめます。
この記事のゴール
masterブランチにgit pushされたらビルドしてFirebaseにデプロイするまでがゴールです。
事前準備
当記事ではFirebaseにホスティング済みのReactアプリがあることを前提に解説を進めます。アプリの開発環境、各種バージョンは以下になります。
- React 19.2.8
- Vite 8.3.0
- Node.js 24.22.1
- Firebase 12.19.0
- @supabase/supabase-js 2.117.1
ReactアプリをFirebaseへホスティングしたことがない方は以下の記事を参考に準備をしてください。
Step.1 Firebaseのサービスアカウントを作成
GitHub ActioinsからFirebaseへデプロイするにはGoogle Cloudのサービスアカウントの作成が必要です。
サービスアカウントとは、人間のユーザーではなく、アプリケーションや仮想マシン(Compute Engineなど)といった「プログラムやシステム」がGoogle Cloudのリソースにアクセスするための特殊なGoogleアカウントです。
Google Cloudにアクセスして「コンソール」をクリックします。

コンソールページに遷移するので、「IAMと管理」をクリックします。

「IAMと管理」ページに遷移したら、サイドメニューの「サービスアカウント」をクリックします。

サービスアカウント画面に遷移するので「サービスアカウントを作成」をクリックします。

「サービスアカウント名」は分かりやすい名前であれば何でも良いですが、今回は「firebase-cicd」とします。サービスアカウントIDはサービスアカウントと同名で問題ありません。
次にサービスアカウントの権限を設定します。ロールのセレクトボックスから「Firebase 管理者」を選択してください。ここまで進んだら、「完了」をクリックします。「アクセス権を持つプリンシパル」の設定は不要です。

サービスアカウントの画面に今作成したサービスアカウントが追加されています。「操作」の下にある3点マークをクリックし、「鍵を管理」をクリックします。
鍵ファイルの作成画面に遷移するので「キーを追加」をクリックして「新しい鍵を作成」をクリックします。

ポップアップが表示されるので「JSON」を選択して、「作成」をクリックするとJSONファイルがダウンロードされます。このJSONファイルは鍵ファイルとなり、後ほどGitHub Actionsで使用します。

最後にサイドメニューの「IAM」をクリックしてサービスアカウントの鉛筆マークをクリックします。

権限の編集画面が開くので、「別のロールを追加」をクリックして、セレクトボックスから「サービスアカウントのユーザー」を選択します。
「保存」をクリックしてサービスアカウントが以下のように表示されていればStep.1は完了です。
Step.2 GitHubのRepository Secretsに鍵ファイルを追加
作成したサービスアカウントの鍵ファイルをGitHubのRepository Secretsに追加します。
Repository SecretはAPIキーやパスワードなどの機密情報を安全に保管し、GitHub Actionsなどのワークフロー内で利用するための暗号化された環境変数です。
envファイルなどをリポジトリにアップロードすることなく、外部サービスのAPIキーを参照できます。
GitHubにアクセスして以下の手順でRepository Secretsへ行きます。
- 対象のリポジトリ画面を開いた状態で「Setting」タブをクリック
- サイドバーにある「Secrets and variables」をクリック
- 「Actions」が出てくるのでクリック
- 「Actions secrets and variables」へ遷移

「New Repository secret」をクリックして「New Secret」画面を開きます。

「Name」にはFIREBASE_KEYと入力します。「Name」はワークフローから参照する際の識別子となります。
「Secret」にはサービスアカウントを作成した時にダウンロードしたJSONファイルを入力します。ただ、GitHubは構造化データをそのまま貼り付けるのは非推奨としているので、Base64にエンコードしたものを入力します。
変換ツールを使用しなくてもWindowsとMacのどちらでもコマンドでBase64にエンコード出来ます。私はMacを使っているのでターミナルを開いて以下のコマンドを入力しました。
base64 -i エンコードするファイル.json -o エンコードして書き出すファイル.json
Windowsの場合は以下を参考にして行なってください。
注意点として「Secret」にエンコードしたJSONファイルをコピペすると最後に空行が出来ます。この空行は消すとデコード出来なくなってしまうので残してください。

「Add secret」をクリックしてサービスアカウントの鍵ファイルを追加します。
Step.3 Repository SecretsにFirebaseのプロジェクトIDと外部サービスのAPIキーを追加する
まずはRepository SecretsにFirebaseのプロジェクトIDを追加します。
Firebaseにアクセスして「コンソールへ移動」をクリックします。

プロジェクトの管理画面に移動するので、サイドメニューの「設定」から「全般」を選択します。

設定の「全般」にプロジェクトIDがあるのでこれをコピーします。あとは先ほどと同様にRepository Secretsに以下を追加します。
- Name:
FIREBASE_PROJECT_ID - Secret:
プロジェクトID
外部サービスのAPIキーを追加する
アプリで外部サービスを利用している場合はAPIキーなどもRepository Secretsに追加しましょう。
GitHub Actionsはワークフローを実行する際にリモートリポジトリのファイルを参照しますが、APIキーなどの機密情報はセキュリティリスクのためGit管理から除外するのが基本です。
Repository SecretsにAPIキーなどを追加しておくことで、第三者から機密情報を秘匿しつつワークフローから参照することが出来ます。
私はアプリのデータの保存にSupabaseを利用しているのでSupabeseのAPIキーとプロジェクトのURLをRepository Secretsに追加しました。手順はサービスアカウントの時とほぼ同じなので割愛します。
これを行わないとデプロイが成功しているのにアプリが表示されないといったことが起きて苦しみます。
Step.4 ワークフローの作成
ここからはワークフローを作成していきます。
ルートディレクトリに.github/workflowsディレクトリを作成し、その中にfirebase-cicd.ymlを作成します。
firebase-cicd.ymlに以下の記述をします。
name: Firebase deploy
on:
push:
branches:
- master
jobs:
build:
name: build
runs-on: ubuntu-latest
env:
VITE_SUPABASE_URL: ${{ secrets.VITE_SUPABASE_URL }}
VITE_SUPABASE_PUBLISHABLE_KEY: ${{ secrets.VITE_SUPABASE_PUBLISHABLE_KEY }}
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version-file: "package.json"
- name: Install dependencies
run: npm install
- name: Run build
run: npm run build
- name: Upload build-artifacts
uses: actions/upload-artifact@v7
with:
name: build-artifacts
path: dist
deploy:
name: deploy
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Setup Node.js and cache
uses: actions/setup-node@v7
with:
node-version-file: "package.json"
cache: "npm"
- name: Download build artifacts
uses: actions/download-artifact@v7
with:
name: build-artifacts
path: dist
- name: Install firebase-tools
run: npm install --save-dev firebase-tools
- name: Decode Firebase service account key
run: |
echo "${{ secrets.FIREBASE_KEY }}" | base64 -d > ./firebase-key.json
echo "GOOGLE_APPLICATION_CREDENTIALS=${{ github.workspace }}/firebase-key.json" >> $GITHUB_ENV
- name: change space
run: ./node_modules/.bin/firebase use ${{ secrets.FIREBASE_PROJECT_ID }}
- name: Deploy to Firebase Hosting
run: |
./node_modules/.bin/firebase deploy
- name: delete GOOGLE_APPLICATION_CREDENTIALS
run: rm $GOOGLE_APPLICATION_CREDENTIALS
if: ${{ always() }}
ビルドとデプロイのジョブはそれぞれ分けています。
ビルド(CI)ではnpm run buildを行なっているだけで特に難しいことはないですが、デプロイ(CD)では鍵ファイルのデコードとFirebaseへのデプロイを行なっています。CDについて詳しく見ていきます。
鍵ファイルをデコードしてワークフローの環境変数に追加
Step.2でBase64にエンコードしてRepository Secretsに追加したサービスアカウントの鍵ファイルをデコードしています。
${{ secrets.FIREBASE_KEY }}はRepository Secretsに追加したサービスアカウントです。
- name: Decode Firebase service account key
run: |
echo "${{ secrets.FIREBASE_KEY }}" | base64 -d > ./firebase-key.json
続いて、デコードしたJSONファイルをワークフローの環境変数として$GITHUB_ENVで定義します。
echo "GOOGLE_APPLICATION_CREDENTIALS=${{ github.workspace }}/firebase-key.json" >> $GITHUB_ENV
環境変数として定義することで、ジョブの後続のステップから参照できるようになります。
Firebaseへデプロイ
いよいよFirebaseへのデプロイです。
${{ secrets.FIREBASE_PROJECT_ID }}はRepository Secretsに追加したFirebaseのプロジェクトIDです。
- name: change space
run: ./node_modules/.bin/firebase use ${{ secrets.FIREBASE_PROJECT_ID }}
- name: Deploy to Firebase Hosting
run: |
./node_modules/.bin/firebase deploy
Step.5 ワークフローが成功しているか確認
masterブランチにgit pushしてワークフローが成功しているか確認します。
GitHubのリポジトリのActionsタブをクリックすると、ワークフローが追加されているのが確認出来ます。
問題が無ければfirebase-cicd.ymlにname: Firebase deployと書いているのでFirebase deployでワークフローが追加されています。
履歴を確認し、緑のチェックマークが付いていればワークフローの実行が成功しています。履歴をクリックするとワークフローの詳細が確認できます。

ワークフローの実行が確認できたらアプリにアクセスして問題無く動作するかも確認しましょう。
ワークフローが成功していても、ビルドしたファイルの受け渡しが出来ていなかったりNode.jsのバージョン違いなどでアプリ側の表示に問題が出ている可能性があります。
おわりに
初めてのCI/CDだったので最初は苦戦しましたが、それぞれのステップで具体的に何を行なっているのかを深堀することで仕組みを理解することが出来ました。
今回はビルドとデプロイですが、次は自動テスト導入してCIにテスト実行のコマンドを追加したいです。
参考






