はじめに
Vite でビルドしている Vue 3 アプリ(Firebase Authentication や Firestoreを使用)を Firebase Hosting にデプロイしており、GitHub Actions と統合して Pull Request / Merge 契機でプレビュー環境構築や本番デプロイを自動で行えるようにしています。
このとき、.env.localファイルで管理しているgit管理対象外の環境変数を GitHub Actions 上でのビルド環境に反映する方法がよくわからなかったので、とりあえず動く状態にするまでにしたことをメモしておきます。
主な環境変数は、以下のように使用している Firebase の config object の値なので、これを例として記載しています。
import { FirebaseOptions } from 'firebase/app';
export const firebaseConfig: FirebaseOptions = {
apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN,
projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
storageBucket: import.meta.env.VITE_FIREBASE_STORAGE_BUCKET,
messagingSenderId: import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID,
appId: import.meta.env.VITE_FIREBASE_APP_ID,
measurementId: import.meta.env.VITE_MEASUREMENT_ID
};
これらの値を.env.localファイルで管理しており、.env.localファイルは.gitignoreで管理対象外になっています。
ただ、Firebase の config object の値は結局クライアントバンドルには含まれますし、非公開にする必要はないようなので、.env.productionファイルに記述すればよいのかもしれません。
なので、機密情報ではないもののGitHubでそのまま公開はしたくない情報を扱う方法という感じです。
Firebase Hosting のランタイム環境に環境変数を設定する方法もなさそうですし、対応の方向性からおかしいかもしれないので、あくまで参考情報として見ていただければと思います。
事前準備
Firebase Hosting のセットアップ
以下のようにFirebase Hosting のセットアップが済んでおり、手動デプロイも問題なくできている状態となっています。
$ firebase login
$ firebase init hosting
$ npm run build
$ firebase deploy --only hosting
GitHub統合のセットアップ
以下のコマンドで、Firebase 側のサービスアカウント作成や github への Secrets の登録、GitHub Actions 用のyamlの生成などが自動で行われるはずです。
$ firebase init hosting:github
余談ですが、firebase-toolsをPCローカルに直接インストールせず、firebase-toolsをインストールしたDockerコンテナ上で実行していたため、GitHubからのリダイレクトができず、途中で止まってしまいました。
firebase login
時も同じようなことが起こるものの、その場合は firebase login -—no-localhost
で手動遷移させれば可能なのですが、ここについてはそういうオプションがあるのかわかりませんでした。
以下のように手動で設定する方法もあるようですが、面倒だったので、諦めてPCローカルにfirebase-toolsをグローバルインストールして実行してしまいました。その方がemulator等も使いやすそうですし。。。
成功時は以下です。
$ firebase init hosting:github
######## #### ######## ######## ######## ### ###### ########
## ## ## ## ## ## ## ## ## ## ##
###### ## ######## ###### ######## ######### ###### ######
## ## ## ## ## ## ## ## ## ## ##
## #### ## ## ######## ######## ## ## ###### ########
You're about to initialize a Firebase project in this directory:
/path/to/firebase-test
Before we get started, keep in mind:
* You are initializing within an existing Firebase project directory
=== 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.
i Using project firebase-test (firebase-test)
=== Hosting:github Setup
i Detected a .git folder at /path/to/firebase-test
i Authorizing with GitHub to upload your service account to a GitHub repository's secrets store.
Visit this URL on this device to log in:
https://github.com/login/oauth/authorize?client_id=......
Waiting for authentication...
✔ Success! Logged into GitHub as yngittest
? For which GitHub repository would you like to set up a GitHub workflow? (format: user/repository) xxxxxx/firebase-test
✔ Created service account github-action-xxxxxxxxxxxx with Firebase Hosting admin permissions.
✔ Uploaded service account JSON to GitHub as secret FIREBASE_SERVICE_ACCOUNT_COMIC_HISTORY.
i You can manage your secrets at https://github.com/xxxxxx/firebase-test/settings/secrets.
? 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
✔ Created workflow file /path/to/firebase-test/.github/workflows/firebase-hosting-pull-request.yml
? 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
✔ Created workflow file /path/to/firebase-test/.github/workflows/firebase-hosting-merge.yml
i Action required: Visit this URL to revoke authorization for the Firebase CLI GitHub OAuth App:
https://github.com/settings/connections/applications/xxxxxxxxxxxxxxxxxxxxxxx
i Action required: Push any new workflow file(s) to your repo
i Writing configuration info to firebase.json...
i Writing project information to .firebaserc...
✔ Firebase initialization complete!
# 以下2ファイルが追加されている
$ git status
On branch firebase_github_integration
Untracked files:
(use "git add <file>..." to include in what will be committed)
.github/workflows/firebase-hosting-merge.yml
.github/workflows/firebase-hosting-pull-request.yml
自動生成されたyamlは以下です。
# 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
steps:
- uses: actions/checkout@v2
- run: npm ci && npm run build
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: '${{ secrets.GITHUB_TOKEN }}'
firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_COMIC_HISTORY }}'
channelId: live
projectId: firebase-test
# 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@v2
- run: npm ci && npm run build
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: '${{ secrets.GITHUB_TOKEN }}'
firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_COMIC_HISTORY }}'
projectId: firebase-test
GitHub Actions ジョブ実行
上記yamlを github に push し、PullRequest を作成すると、ジョブが実行されます。
手動でデプロイする際は、ローカルに.env.localファイルがある状態で、npm run build
してから firebase deploy
しているので問題ないのですが、
.env.localファイルは github にはpushされないので、当然 GitHub Actions 上では反映されず、デプロイこそ成功しますが、デプロイされたアプリは API key error となります。
環境変数の値は、githubの該当プロジェクトの Settings → Secrets → Actions で別途登録することができます。
Secretsを環境変数として使用する場合、以下のように書いてみたものの、これではViteでのビルドには反映されませんでした。よく考えれば、ローカルでのビルド時でもシェル上で環境変数をexportしたところで反映されないのと同じです。
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@v2
- run: npm ci && npm run build
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_MEASUREMENT_ID: ${{ secrets.VITE_MEASUREMENT_ID }}
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: '${{ secrets.GITHUB_TOKEN }}'
firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_COMIC_HISTORY }}'
projectId: firebase-test
代わりに良い方法がないか探してみましたが見つかりませんでした。冒頭にも書いた通り、そもそも対応の方向性からしておかしいのかもしれません。
そこで、無理矢理な方法ですが、ビルド環境上で.envファイルを作成してしまうことにしてみました。
# 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@v2
- name: create .env file
run: |
echo "VITE_FIREBASE_API_KEY=${{ secrets.VITE_FIREBASE_API_KEY }}" >> .env
echo "VITE_FIREBASE_AUTH_DOMAIN=${{ secrets.VITE_FIREBASE_AUTH_DOMAIN }}" >> .env
echo "VITE_FIREBASE_PROJECT_ID=${{ secrets.VITE_FIREBASE_PROJECT_ID }}" >> .env
echo "VITE_FIREBASE_STORAGE_BUCKET=${{ secrets.VITE_FIREBASE_STORAGE_BUCKET }}" >> .env
echo "VITE_FIREBASE_MESSAGING_SENDER_ID=${{ secrets.VITE_FIREBASE_MESSAGING_SENDER_ID }}" >> .env
echo "VITE_FIREBASE_APP_ID=${{ secrets.VITE_FIREBASE_APP_ID }}" >> .env
echo "VITE_MEASUREMENT_ID=${{ secrets.VITE_MEASUREMENT_ID }}" >> .env
- run: npm ci && npm run build
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: '${{ secrets.GITHUB_TOKEN }}'
firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_COMIC_HISTORY }}'
projectId: firebase-test
とりあえずこれでビルド・デプロイが成功するようになりました。
ちなみに、yaml上での複数行コマンドについては、以下を参考にさせていただきました。
まとめ
GitHub Actions のビルドコマンド内で、Vite向けの.envファイルをSecretsを元に作成して使用できるようにしました。
git管理したくない値を取り込むための逃げ道としては許容できるかもしれませんが、Firebaseのconfig objectの値などは、そもそも.env.localで管理すべき情報なのかというところから見直す方がよさそうです。