Deploy Apps And Functions To Firebase From A Mono Repo With GitHub Actions

How to deploy applications and functions from a mono repo with GitHub Actions to Firebase Hosting and Functions

Image for post
Image for post
Photo by 张 嘴 on Unsplash

I share one trick a day until the end of the COVID-19 quarantine in Switzerland, April 19th 2020. Twenty-seven days left until hopefully better days.

I am a big fan of a blog post published by Julien Renaux a couple of months ago in which he displays how to deploy an application using GitHub Actions to Firebase Hosting.

The article is super comprehensive and I even already have published a following post about it once before 🤣. Nevertheless I think that this challenge is the perfect excuse to publish again another follow-up 😉.

Mono Repo

Our open source project DeckDeckGo contains many Progressive Web Apps and Cloud Functions, for which, obviously, I did set up GitHub actions as Julien displayed.

In this blog post I share the enhancement I had to implement in order to make the integration supports a mono repo.

To Firebase Hosting

Let’s say that one of your application is available in a sub-folder of our repo called docs . Basically, everything you have to do in addition to the original post is to prefix all steps of the Action with your sub-directory, respectively with docs .

Concretely, if for example we would like to trigger the action when a merge happens in the master branch, but, only if a modifications impacts our specific app, we specify a path to the Action on listener.

Listen to push to master for the all repo:

on:
push:
branches:
- master

Listen to push to master only if sub-folder is affected:

on:
push:
branches:
- master
paths:
- 'docs/**'

Because the Git checkout of our pipeline happens on the root level of our repo, when it goes to installing dependencies or running a build, we do have to observe our sub-folder too. For such purpose, GitHub Action provides a handy option working-directory for the npm steps.

Run npm in the root folder:

- name: Install Dependencies
run: npm ci

Run npm in a sub-directory:

- name: Install Dependencies
run: npm ci
working-directory: ./docs

Likewise, when it goes to artifacts, we also have to prefix the path to our bundle.

Archiving without sub-folder:

- name: Archive Artifact
uses: actions/upload-artifact@master
with:
name: www
path: www

Archiving with sub-folder:

- name: Archive Artifact
uses: actions/upload-artifact@master
with:
name: docs
path: docs/www

Finally, the Firebase Action does also provide an option to specify a project path.

Deploy to Firebase from root:

- name: Deploy to Firebase
uses: w9jds/firebase-action@master
with:
args: deploy --only hosting
env:
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}

Deploy to Firebase for a sub-directory:

- name: Deploy to Firebase
uses: w9jds/firebase-action@master
with:
args: deploy --only hosting
env:
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
PROJECT_ID: "default"
PROJECT_PATH: "./docs"

All in all, here’s the action to deploy our application for a sub-folder of our mono repo to Firebase Hosting:

name: CI - Docs

on:
push:
branches:
- master
paths:
- 'docs/**'

jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@master
- name: Install Dependencies
run: npm ci
working-directory: ./docs
- name: Build
run: npm run build
working-directory: ./docs
- name: Archive Artifact
uses: actions/upload-artifact@master
with:
name: docs
path: docs/www
deploy:
name: Deploy
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@master
- name: Download Artifact
uses: actions/download-artifact@master
with:
name: docs
path: docs/www
- name: Deploy to Firebase
uses: w9jds/firebase-action@master
with:
args: deploy --only hosting
env:
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
PROJECT_ID: "default"
PROJECT_PATH: "./docs"

To Firebase Cloud

In DeckDeckGo we are also taking advantages of the amazing Cloud Functions features of Firebase.

The process is basically the same as previously with that difference that you don’t have to build or even bundle anything because these steps are contained in the deployment process it self. Therefore checking out the repo, installing the dependencies and deploying is going to do the trick.

Note that again, as we have a mono repo, the following example happens in a sub-directory called cloud which contains the functions.

name: CI - Cloud

on:
push:
branches:
- master
paths:
- 'cloud/**'

jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@master
- name: Install Dependencies
run: npm ci
working-directory: ./cloud/functions
- name: Deploy to Firebase
uses: w9jds/firebase-action@master
with:
args: deploy --only functions
env:
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
PROJECT_ID: "default"
PROJECT_PATH: "./cloud"

Summary

GitHub actions are awesome! Seriously, few lines, few configuration, supports mono repo, really a perfect solution for a project like ours.

That being said, notably if you are and want to use them in your company, you might be interested by another blog post published by Julien which describes some possible risks linked to versioning and dependencies.

You are also most welcomed to have a look to our open source Actions in our repo or even better, if you notice anything which can be improved in DeckDeckGo, don’t hesitate to open an issue or even better, send us a Pull Request 😃.

Stay home, stay safe!

David

Written by

Freelancer by day | Creator of DeckDeckGo by night | Organizer of the Ionic and IndieHackers Zürich Meetup

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store