circleciでgithubのブランチ毎にfirebaseへのデプロイ先を切り替える方法
Firebaseに複数の環境(本番環境と開発環境など)とGitHubのブランチと関連付け、circleciを利用してビルド・テスト・デプロイを自動化する方法をまとめました。
環境(Firebase/circleci/GitHub)
Firebase | prod | 本番環境 |
dev | 開発環境 | |
circleci | config.yml | master/developブランチが更新されたタイミングでデプロイ実行 |
GitHub | masterブランチ | 本番環境にデプロイするブランチ |
developブランチ | 開発環境にデプロイするブランチ |
環境別の.envファイルを作成する
Firebaseの設定ファイルを環境別に2つ準備する
Firebaseの設定は、以下の手順で取得できます
- Firebaseにログイン
- 対象のプロジェクト選択
- 歯車アイコンから「プロジェクトを設定」を選択
- 「全般」タグの「マイアプリ」の「Firebase SDK snippet」で「構成」を選択
以下のような形式で表示されています。
const firebaseConfig = {
apiKey: "xxxxxxxxxxxxxxxx",
authDomain: "プロジェクトID.firebaseapp.com",
databaseURL: "https://プロジェクトID.firebaseio.com",
projectId: "プロジェクトID",
storageBucket: "プロジェクトID.appspot.com",
messagingSenderId: "9999999999",
appId: "9:999999999999:xxx:999999999999999999",
measurementId: "X-XXXXXXXXXXXX"
};
この情報を.envのファイル形式で環境別に作成します。
.env.dev
ファイル名は環境を区別するために「.env.dev」とします。
REACT_APP_API_KEY="xxxxxxxxxxxxxxxx"
REACT_APP_AUTH_DOMAIN="開発環境のプロジェクトID.firebaseapp.com"
REACT_APP_DATABASE_URL="https://開発環境のプロジェクトID.firebaseio.com"
REACT_APP_PROJECT_ID="開発環境のプロジェクトID"
REACT_APP_STORAGE_BUCKET="開発環境のプロジェクトID.appspot.com"
REACT_APP_MESSAGING_SENDER_ID="9999999999"
REACT_APP_APP_ID="9:999999999999:xxx:999999999999999999"
REACT_APP_MEASUREMENT_ID="X-XXXXXXXXXXXX"
.env.prod
ファイル名は環境を区別するために「.env.prod」とします。
REACT_APP_API_KEY="xxxxxxxxxxxxxxxx"
REACT_APP_AUTH_DOMAIN="本番環境のプロジェクトID.firebaseapp.com"
REACT_APP_DATABASE_URL="https://本番環境のプロジェクトID.firebaseio.com"
REACT_APP_PROJECT_ID="本番環境のプロジェクトID"
REACT_APP_STORAGE_BUCKET="本番環境のプロジェクトID.appspot.com"
REACT_APP_MESSAGING_SENDER_ID="9999999999"
REACT_APP_APP_ID="9:999999999999:xxx:999999999999999999"
REACT_APP_MEASUREMENT_ID="X-XXXXXXXXXXXX"
env-cmdのインストール
envファイルを切り替える方法として「env-cmd」を利用します。
他にも環境設定を切り替える方法として「cross-env」というものもありますが、Firebaseの場合は切り替えたい環境変数の数が多いため、「env-cmd」の方が便利です。
インストール方法(npm)
npm install env-cmd
インストール方法(yarn)
yarn add env-cmd
.firebaserc
.firebasercを編集しFirebaesの各プロジェクトIDに対して環境名を設定します。
そうすることで、firebaseコマンドを実行する際に環境名を指定することでプロジェクトIDを切り替えられるようになります。
{
"projects": {
"dev": "開発環境のプロジェクトID",
"prod": "本番環境のプロジェクトID"
}
}
ここでは、開発環境をdevとし本番環境をprodとして設定しています。
package.json
packeage.jsonのscriptsで、buildやdeployを環境別に準備しましょう。
以下の例はbuildとdeploy用のコマンドを環境別に設定した場合です。
"scripts": {
"build:dev": "env-cmd -f .env.dev react-scripts build",
"build:prod": "env-cmd -f .env.prod react-scripts build",
"test": "react-scripts test",
"deploy:dev": "firebase deploy --only hosting --project=dev",
"deploy:prod": "firebase deploy --only hosting --project=prod",
},
コマンド | 内容 | やっていること |
---|---|---|
build:dev | 開発環境用のビルドコマンド | env-cmdで.env.devのファイルを指定しbuildコマンドを実行 |
build:prod | 本番環境用のビルドコマンド | env-cmdで.env.prodのファイルを指定しbuildコマンドを実行 |
test | テストコマンド | react-scriptsのテストコマンド実行(※環境の区別なし) |
deploy:dev | 開発環境用のデプロイコマンド | firebaseコマンドのprojectオプションでdevを指定しデプロイを実行 |
deploy:prod | 本番環境用のデプロイコマンド | firebaseコマンドのprojectオプションでprodを指定しデプロイを実行 |
このように設定することで、コンソールから各環境へのコマンドの実行が簡単になります。
例えば、開発環境にデプロイする場合は
npm run deploy:dev
と実行します。
GitHubのアカウント取得とリポジトリの作成
今回の構成はGitHubの特定のブランチに変更があった場合にcircleciで自動ビルド・テスト・デプロイを行うことを前提としていますので、GitHubのアカウントがない場合は以下の記事を参考に取得してみてください。
circleciの設定
firebase-toolsのコマンドで各環境別にビルドやデプロイができる状態になれば、circleciの設定を行いましょう。
circleciのアカウント作成
circleciのアカウントは、以下のURLからGitHubのアカウントで取得できます。
GitHubのリポジトリと関連付ける
以下の手順でGitHubのリポジトリと紐付けましょう。
- circleciにログイン
- 「Go to App」をクリック
- GitHubのアカウントを選択する画面が表示されるので選択し次に進める
- 「Add Projects」のアイコンをクリック
- 関連付けするリポジトリの「Set Up Project」をクリック
- 「Start Building」をクリック(※設定ファイルは後で書き換えるのでそのままクリックでいよい)
環境変数(Environment Variables)の設定
FirebaseのトークンIDがデプロイ時に必要になりますのでcircleciの環境変数に登録します。
ここでは環境別にそれぞれ以下の環境変数名で登録します。
環境変数名 | 設定値 |
---|---|
FIREBASE_TOKEN_PROD | 本番環境のFirebaseトークンID |
FIREBASE_TOKEN_DEV | 開発環境のFirebaesトークンID |
環境変数の設定方法
circleciのプロジェクトの設定画面から「Environment Variables」で環境変数を登録できます。
FirebaseトークンIDの確認方法
コンソールで以下のコマンドを実行すると、ブラウザで認証画面が表示されます。
認証完了後にコンソールにトークンIDが表じれます。
firebase login:ci
.circleci/config.yml
crcleciの設定ファイルは配置するフォルダとファイル名が決まっていますので、間違えずに作成しましょう。
GitHubのプロジェクトフォルダ
└─ .circleci
└─ config.yml
developブランチを開発環境へデプロイし、masterブランチを本番環境へデプロイするサンプルです。
version: 2.1
#----------------------------------------------
# Deploy React App to Firebase Hosting
#----------------------------------------------
executors:
executor:
docker:
- image: circleci/node:12.16.1
commands:
npm_install:
steps:
- restore_cache:
name: Restore Dependencies
keys:
- v1-dependencies-{{ checksum "yarn.lock" }}
- run:
name: Install Dependencies
command: yarn install
- save_cache:
name: Save Dependencies
key: v1-dependencies-{{ checksum "yarn.lock" }}
paths:
- node_modules
firebase_install:
steps:
- run:
name: Install Firebase CLI
command: yarn add -D firebase-tools
build:
parameters:
env_name:
type: string
default: "dev"
steps:
- run:
name: Build Project
command: yarn build:<< parameters.env_name >>
deploy:
parameters:
env_name:
type: string
default: "dev"
token:
type: string
default: $FIREBASE_TOKEN_DEV
steps:
- run:
name: Deploy to Firebase Hosting
command: node_modules/.bin/firebase deploy --only hosting --project=<< parameters.env_name >> --token << parameters.token >>
jobs:
#-----------------------
# jobs:dev
#-----------------------
build_dev:
executor:
name: executor
working_directory: ~/tmp/dev
steps:
- checkout
- npm_install
- build:
env_name: "dev"
- persist_to_workspace:
root: ~/tmp/dev
paths:
- .
test_dev:
executor:
name: executor
working_directory: ~/tmp/dev
steps:
- attach_workspace:
at: ~/tmp/dev
- run:
name: Test Project
command: yarn test
deploy_dev:
executor:
name: executor
working_directory: ~/tmp/dev
steps:
- attach_workspace:
at: ~/tmp/dev
- firebase_install
- deploy:
env_name: "dev"
token: "$FIREBASE_TOKEN_DEV"
#-----------------------
# jobs:prod
#-----------------------
build_prod:
executor:
name: executor
working_directory: ~/tmp/prod
steps:
- checkout
- npm_install
- build:
env_name: "prod"
- persist_to_workspace:
root: ~/tmp/prod
paths:
- .
test_prod:
executor:
name: executor
working_directory: ~/tmp/prod
steps:
- attach_workspace:
at: ~/tmp/prod
- run:
name: Test Project
command: yarn test
deploy_prod:
executor:
name: executor
working_directory: ~/tmp/prod
steps:
- attach_workspace:
at: ~/tmp/prod
- firebase_install
- deploy:
env_name: "prod"
token: "$FIREBASE_TOKEN_PROD"
workflows:
version: 2
build_and_deploy:
jobs:
#------------------------
# develop branch to dev
#------------------------
- build_dev:
filters:
branches:
only: develop
- test_dev:
requires:
- build_dev
filters:
branches:
only: develop
- deploy_dev:
requires:
- test_dev
filters:
branches:
only: develop
#------------------------
# master branch to prod
#------------------------
- build_prod:
filters:
branches:
only: master
- test_prod:
requires:
- build_prod
filters:
branches:
only: master
- deploy_prod:
requires:
- test_prod
filters:
branches:
only: master
コマンドの共通化などを行っているため、長くなっていますがポイントは以下の2つです。
- branches:onlyでブランチ名を指定してビルド・テスト・デプロイの各コマンドを実行
- package.jsonに設定したコマンドを環境に合わせて実行
GitHubにPushして自動デプロイ
実際にcircleciに設定した内容が動作するか、GitHubの各ブランチにPushして確認してみましょう。