GitHub CI/CD for multi-environment deployment on Firebase multiple sites
Tags: cicd, webdev, react, firebase
Published: 2022-11-10 21:03:39

> Hi, Here we'll cover how to automate your workflow on GitHub, deploy to multiple environments. This will assist in rapid iterations to your front-end app, without constantly pushing breaking changes to production. The goal is to have an environment for your users (production), an environment to approve changes prior to shipping (staging) and an environment that's actively being worked on (development).

By the end of this article, your app will automatically be deployed to a specific Firebase Project simply by pushing to GitHub. Although we go extremely in-depth in this article, the end result is rather simple. The [github repo can be seen here](https://github.com/thisisrid/firebase-cicd). 

Let have a look some definition first.
**Multi-Environment Deployment**: The standard practice for developing & testing changes in an isolated environment.
**CI/CD**: Continuous Integration is the practice of merging all outstanding changes in a code-base, as often as possible. Being sure to test at all points. Continuous deployment is the practice of automating deployments to your users. Getting them new updates regularly.
**Firebase**: A mobile and web application development platform, owned by Google, that provides a number of products for any real world app. In this article, we'll only be using "Firebase Hosting".
We are jumping into the process supposing you've already got your front-end app setup. We will use React app here.

## **Step 1: Initialize Firebase and Getting Firebase Token**


Before start we need firebase initialization, run

`firebase init`

This is needed in order for GitHub to authenticate to your  Firebase project.  Allowing you to deploy.

`firebase login:ci`

Caution: this token can be used to perform almost any task on any Firebase project you have access to. Save it. If, for any reason, your token becomes compromised, you can run the following command: firebase logout --token YOUR_TOKEN

Now, you'll need to add your Firebase token to your repo's secrets. Navigate to your GitHub repo, go to "Settings -> Secrets -> Add a New Secret".
Name: FIREBASE_TOKEN

Set the firebase token in your github repo

## **Step 2: Create "yml" file**

Now that we're all set up, let's create our initial workflow. Create a file at .github/workflows/firebase_web.yml, with the contents below. 

```

name: Firebase hosting

on:
  push:
    branches: [master, dev]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2

      - name: Install firebase tools
        run: |
          sudo npm install -g firebase-tools
          firebase use rid1-test --token ${{secrets.FIREBASE_TOKEN}}

      - name: Build website
        run: |
          yarn
          yarn build

      - name: Deploy to staging site
        if: github.ref == 'refs/heads/dev'
        run: firebase deploy --only hosting:dev --non-interactive --token ${{secrets.FIREBASE_TOKEN}} -m "RunID ${{ github.run_id }} Commit SHA ${{ github.sha }}"

      - name: Deploy to production site
        if: github.ref == 'refs/heads/master'
        run: firebase deploy --only hosting:prod --non-interactive --token ${{secrets.FIREBASE_TOKEN}} -m "RunID ${{ github.run_id }} Commit SHA ${{ github.sha }}"

      - name: Archive build Artifact
        uses: actions/upload-artifact@master
        with:
          path: build
```
**Workflow explained**
We're creating a workflow that's triggered whenever a push is made on master and dev brances. The workflow runs on Ubuntu. 
Then, we install Node, which is needed for Firebase. After that, we run yarn (npm can also be used just fine) to install dependencies. From there, we run the typical "build" command that React ships with. After the build is complete, we deploy using Firebase CLI. 
We splite the deployment in 2 way. "Deploy to staging site" workflow   will be triggered for dev branch another is for master.


## **Step 3: Firebase configuration**

Create "firebase.json" file in your root directory and add the following codes;

```
{
  "hosting": [
    {
      "target": "dev",
      "public": "dist",
      "ignore": ["firebase.json", "**/.*", "**/node_modules/**"]
    },
    {
      "target": "prod",
      "public": "dist",
      "ignore": ["firebase.json", "**/.*", "**/node_modules/**"]
    }
  ]
}
```
Create ".firebaserc" file in your root directory and add the following codes

```
{
  "projects": {
    "default": "rid1-test"
  },
  "targets": {
    "rid1-test": {
      "hosting": {
        "dev": [
          "rid1-test-development"
        ],
        "prod": [
          "rid1-test-production"
        ]
      }
    }
  }
}
```
**Explanation:**

Here rid1-test is my Firebase project, "rid1-test-development" and "rid1-test-production" denotes the firebase multiple site names, first one is for the development another is for production. If example-dev.web.app is your firebase site then example-dev will be your site name. 
Make sure you have created a firebase project and create similarly two sites from firebase console.
Create firebase project and multiple site.


## 4. **Final step: Check the action!**

Now  to push to GitHub and see a successful action now : )

```
git add .
git commit -m 'WOW CI&CD checking/Github Action'
git push
```
Additionally, any pushes you make both on master/dev should deploy to the correct Firebase project, based on the branch you're working on!!
All done!

Congratulations! You're now ready to maximize your workflow by utilizing automated deployments to multiple environments 🚀🤙🏻

Happy Hacking!
Interested in the final result? Take a look at these [GitHub REPO](https://github.com/thisisrid/firebase-cicd).