Firebase と GitHub Actions の連携で実現する自動デプロイ|設定手順とサービスアカウント認証
Firebase Hosting は firebase deploy で手動公開できますが、更新のたびに手元で叩くとコマンドの打ち忘れやローカル依存の混入が起きます。GitHub のリポジトリに push した内容を GitHub Actions から自動でデプロイすれば、公開手順が1本のワークフローに固定され、レビュー用のプレビューURLも自動で発行できます。この記事では Firebase と GitHub Actions の連携による自動デプロイを、最短セットアップ・認証方式の選択・失敗時の対処まで整理します。GitHub Actions 自体の基礎はGitHub Actionsとは?できること・使い方とCI/CD自動化の活用例を参照してください。
まとめ:連携の要点
- 最短ルートは
firebase init hosting:github。サービスアカウント作成・GitHub Secrets 登録・ワークフロー2本の生成までを対話1回で自動化する。 - Firebase と GitHub Actions は競合しない。Firebase は公開先(ホスティング)、GitHub Actions はデプロイを走らせる実行基盤。両者は役割分担で組み合わせる。
- 認証はサービスアカウント鍵が既定、本番は鍵レスの Workload Identity Federation(WIF)を推奨。
firebase login:ciのトークン認証は非推奨で将来削除予定のため新規採用しない。 - main へのマージで本番公開、プルリクエストでプレビュー公開という2ワークフロー構成が標準。
Firebase と GitHub Actions の関係|連携でできること
「firebase vs github actions」で検索されることがありますが、この2つは比較して片方を選ぶものではありません。Firebase Hosting は静的サイトや SPA の公開先(デプロイ先のホスティング)、GitHub Actions は push などのイベントで処理を走らせるCI/CD の実行エンジンです。連携とは「GitHub Actions が Firebase CLI を実行して Firebase Hosting へ公開する」ことを指します。
連携で自動化されるのは次の2点です。
- 本番デプロイ:main ブランチへマージしたタイミングで
liveチャンネルへ公開する。 - プレビューデプロイ:プルリクエストごとに一時的なプレビューURLを発行し、マージ前に実物を確認できる。プレビューURLは PR にコメントとして自動で貼られる。
手元から firebase deploy を直接叩く運用でも公開自体はできます。GitHub Actions を挟む利点は、公開手順がリポジトリに定義され属人性が消えること、そしてレビュー段階でプレビューを共有できることにあります。CI 側でビルドと自動テストを通してから公開したい場合は、GitHub Actionsでビルド・自動テストを設定する方法と同じワークフローにデプロイ手順を足す形になります。
連携の最短手順:firebase init hosting:github
Firebase CLI には GitHub 連携を自動構成するサブコマンドがあり、認証情報の作成からワークフロー生成までを一度に済ませられます。手作業で鍵を作る前に、まずこれを使うのが最短です。
Firebase CLI の導入とプロジェクト初期化
Firebase CLI を導入し、対象プロジェクトにログイン・初期化しておきます。
npm install -g firebase-tools
firebase login
firebase init hosting
GitHub 連携の実行
Hosting を初期化済みのディレクトリで次を実行します。
firebase init hosting:github
対話に沿って連携先の GitHub リポジトリ(例:your-org/your-repo)を指定すると、CLI が自動で次の3つを行います。
- デプロイ権限を持つサービスアカウントを作成し、その JSON 鍵を生成する。
- 鍵を暗号化してGitHub の Secrets に登録する(
FIREBASE_SERVICE_ACCOUNT_...という名前で保存される)。 .github/workflows/にワークフローファイル2本(本番用・プレビュー用)を生成する。
「main にマージしたら自動デプロイするか」を尋ねられるので Yes を選ぶと、本番用ワークフローも同時に作られます。これで push するだけで公開される状態になります。
サービスアカウント認証とGitHub Secretsの設定
CLI に任せず手動で構成する場合や、既存リポジトリに後から足す場合は、サービスアカウントを自分で作って Secrets に登録します。Firebase のサービスアカウントは Firebase プロジェクトと同じ Google Cloud プロジェクト上の IAM で管理されます(Firebase Admin SDKとは?導入・初期化からユーザー管理までで扱う Admin SDK 用の鍵と同じ仕組み)。
- Firebase コンソールの「プロジェクトの設定 > サービスアカウント」から新しい秘密鍵を生成し、JSON をダウンロードする。デプロイには
Firebase Hosting 管理者相当の権限が必要。 - GitHub リポジトリの
Settings > Secrets and variables > Actionsで、JSON の中身をそのままFIREBASE_SERVICE_ACCOUNTという名前の Secret に貼り付ける。 - ワークフローからは
secrets.FIREBASE_SERVICE_ACCOUNTとして参照する。
JSON 鍵はコミット履歴や Slack に貼らず、必ず Secrets 経由で渡します。鍵を平文で扱う運用は漏洩時の被害が大きいため、後述の鍵レス方式への移行も検討してください。
ワークフローファイルの構成とトリガー設定
デプロイの実体は FirebaseExtended/action-hosting-deploy という公式アクション(最新は v0.10.0、参照は @v0)です。本番用とプレビュー用でトリガーと公開先チャンネルだけが異なります。
本番デプロイ用(main マージ時)
name: Deploy to Firebase Hosting on merge
on:
push:
branches:
- main
jobs:
build_and_deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm run build
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: ${{ secrets.GITHUB_TOKEN }}
firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
channelId: live
projectId: your-project-id
channelId: live が本番公開の指定です。React や Vite などビルドが必要なプロジェクトでは、デプロイ前に npm run build を通し、生成された dist/ や build/ を firebase.json の public に合わせておきます。
プレビューデプロイ用(プルリクエスト時)
on:
pull_request:
jobs:
build_and_preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm run build
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: ${{ secrets.GITHUB_TOKEN }}
firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
projectId: your-project-id
channelId を省くと一時プレビューチャンネルが作られ、PR に URL がコメントされます。プレビューチャンネルには有効期限があり(既定7日)、expires で延長できます。同じ手順を複数リポジトリで使い回すなら、共通部分をReusable Workflows(GitHub Actions)に切り出すと保守が楽になります。なお action-hosting-deploy の更新が停滞して GitHub Actions のランナー更新に追従しなくなった場合は、後述の WIF 章のように firebase-tools を直接叩く構成へ寄せると、ランタイム変更の影響を受けにくくなります。
サービスアカウント鍵をやめる:Workload Identity Federation(鍵レス認証)
ここは旧記事に無い論点です。サービスアカウントの JSON 鍵は「一度作ると失効しない長寿命の資格情報」で、Secrets から漏れれば第三者がデプロイできてしまいます。本番運用では、鍵そのものを持たない Workload Identity Federation(WIF) を推奨します。判断としては、個人の検証はサービスアカウント鍵で十分、チームの本番リポジトリは WIF に寄せる、が現実的な線引きです。
WIF は、GitHub Actions が発行する OIDC トークンを Google Cloud が信頼し、その場限りの短命トークンを払い出す仕組みです。鍵の保管もローテーションも不要になります。認証部分を google-github-actions/auth@v2 に置き換え、鍵を Secrets に保存する代わりに Workload Identity Provider の識別子を指定します(この識別子は機密ではないため平文で書いても問題ありませんが、値を隠したい場合は Secrets 化してもかまいません)。
permissions:
contents: read
id-token: write # OIDCトークン発行に必須
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: google-github-actions/auth@v2
with:
workload_identity_provider: projects/123456789/locations/global/workloadIdentityPools/POOL/providers/PROVIDER
service_account: [email protected]
- run: npx firebase-tools deploy --only hosting --project your-project-id
ポイントは id-token: write の権限指定です。これが無いと OIDC トークンを発行できず認証に失敗します。事前に Google Cloud 側で Workload Identity プールとプロバイダを作り、対象リポジトリからのみ認証を許可するよう属性条件を絞っておきます。firebase login:ci で取得するトークン認証(--token)は非推奨となり将来のメジャーバージョンで削除予定のため、新規構成では選ばないでください。
デプロイが失敗するときの原因と対処
連携直後によく出る失敗は、ほぼ認証・権限・ビルド出力の3系統に収まります。
| 症状 | 主な原因 | 対処 |
|---|---|---|
| Permission denied / 403 | サービスアカウントの権限不足 | Firebase Hosting 管理者ロールを付与。WIF なら service_account の紐付けを確認 |
| projectId 不一致でデプロイ先が違う | with の projectId 未指定・誤り | Firebase プロジェクトIDを明示。.firebaserc のエイリアスと突き合わせる |
| 公開されるが中身が古い/空 | ビルド未実行・public ディレクトリ不一致 | デプロイ前に build を実行し、firebase.json の public を出力先に合わせる |
| OIDC 認証エラー(WIF) | id-token: write 未設定・属性条件不一致 |
permissions を追加し、プロバイダの許可リポジトリ条件を確認 |
ログは GitHub Actions の該当ジョブで action-hosting-deploy または firebase deploy のステップを開くと、CLI が出力した具体的なエラー行が読めます。まず認証(誰として実行しているか)、次に権限(そのアカウントに Hosting 権限があるか)の順で切り分けると早いです。
よくある質問
Firebase と GitHub Actions はどちらを使うべきですか?
二択ではありません。Firebase Hosting が公開先、GitHub Actions が公開を自動実行する仕組みで、組み合わせて使います。手動の firebase deploy でも公開はできますが、手順の固定化とプレビュー共有のために GitHub Actions を挟みます。
firebase login:ci のトークン認証はまだ使えますか?
動作はしますが --token 認証は非推奨で、将来の firebase-tools メジャーバージョンで削除予定です。新規構成ではサービスアカウント鍵、または鍵レスの Workload Identity Federation を使ってください。
サービスアカウントの鍵はどこで作りますか?
Firebase コンソールの「プロジェクトの設定 > サービスアカウント」で秘密鍵(JSON)を生成します。firebase init hosting:github を使えば、この作成と GitHub Secrets への登録が自動で行われます。
プレビューURLはいつ消えますか?
プレビューチャンネルには既定で7日の有効期限があり、期限切れで自動的に無効化されます。ワークフローの expires 入力で期間を変更できます。
GitHub Actions の無料枠でデプロイできますか?
パブリックリポジトリは実行時間が無料、プライベートリポジトリも毎月の無料実行時間の範囲内なら追加費用なくデプロイできます。ビルドとデプロイは数分で終わるため、通常の更新頻度なら無料枠で足りることが多いです。