Search Lessons, Code Snippets, and Videos
search by algolia
X
#native_cta# #native_desc# Sponsored by #native_company#

Continuous Integration and Delivery for Angular Firebase Apps

Episode 115 written by Jeff Delaney
full courses and content on fireship.io

Source code available to pro members. Learn more

Have you ever spent weeks working on a new feature, only to find that everything breaks when it comes time to merge it with the master branch? Continuous Integration and Delivery are processes that automate code testing and deployment to avoid Integration Hell. Many companies now employ dedicated individuals and teams to orchestrate these tasks, which fall under the umbrella of DevOps. My goal with this lesson is to break down the most important DevOps responsibilities so you can test, maintain, and deploy a reliable Angular/Firebase project. These techniques can lead to large productivity gains for individual developers, large teams, and open source projects alike.

CircleCI passing build

Project Overview

In order to produce a fullstack DevOps example, we will build an Angular v6 app, along with a Cloud Functions backend. We have covered Angular Component Testing and Cloud Functions Testing with Jest in past episodes, so this article assumes you have some existing specs created in your project.

Whenever new code is committed to the Github repo with git push some-branch, the following events will happen:

  1. CircleCI listens to Github commits, then builds a Docker container to test the app.
  2. Runs all Angular specs
  3. Runs all Cloud Functions specs
  4. If all specs pass and we’re on the master branch, deploy to Cloud Functions and Firebase Hosting

Get started by signing up for a free CircleCI account, then link an existing Github project to it.

Continuous Integration for Angular 6 Frontend

CircleCI is popular right now, but shop around for other CI/CD alternatives like Travis, Jenkins, Gitlab, and Bitbucket. Create a config folder and file in the root of your project called .circleci/config.yml

Circle CI config in angular project

CircleCI Config

Our first job will run our Angular tests on every commit to Github. (1) First, we specify the node8-browsers Docker container runtime, then (2) provide steps to build and test the app. These should match the NPM scripts you have in your package.json.

version: 2
jobs:
test-job:
docker:
- image: circleci/node:8-browsers
steps:
- checkout

# Cache to enable faster future jobs
- run: npm install

# Run tests
- run: npm run test

Now change something in your codebase and commit it to github. You should see something like this on the dashbord - in my case we have a failing test:

Failing spec on CircleCI Angular app

CircleCI Pro Tip - Watch the favicons on your browser tabs when running tests. They will cycle between blue, red, and green based on the state of your CI server.

Full Stack Continuous Delivery

The last example was very simple, but most CI tasks need to be orchestrated in complex ways. When deploying code, for example, we only want the job to run on the master branch IF the test suite is passing. Let’s see how we might combine multiple jobs into a workflow that can deploy both Angular and Firebase Cloud Functions.

Environment Variables for Firebase Cloud Functions

Before we can deploy code to Firebase, we need to authenticate our CircleCI container. We can do this by generating a token by logging into our Firebase project locally, then setting it as an environment variable. First, run the following commands:

npm i -D firebase-tools

firebase login:ci

Then grab the token string it returns, and save it as FIREBASE_DEPLOY_TOKEN by going to your-project >> settings >> environment variables on the CircleCI dashboard.

Defining a CircleCI Workflow

We want ours tests to run on every commit, but only deploy on passing commits to the master git branch. Our config will now add an additional job for deployment and run it only if specific conditions are met. Also, notice how we need to pass the --token flag to Firebase tools to authenticate the CI server.


deploy-job:
docker:
- image: circleci/node:8-browsers

pro-only: true



version: 2
jobs:
test-job:
docker:
- image: circleci/node:8-browsers
steps:
- checkout

# Cache to enable faster future jobs
- run: npm install
- save_cache:
paths:
- node_modules
key: v1-dependencies-{{ checksum "package.json" }}

# Run tests
- run: npm run test
deploy-job:
docker:
- image: circleci/node:8-browsers
steps:
- checkout
- run: npm install
- run: npm run build
- run: cd functions && npm install && npm run build
- run: ./node_modules/.bin/firebase deploy --token=$FIREBASE_DEPLOY_TOKEN

workflows:
version: 2

-test_and_deploy:
jobs:
- test-job
- deploy-job:
requires:
- test-job
filters:
branches:
only: master


Congrats! You now have fullstack continuous integration for your Angular Firebase project. Every new commit fill follow a consistent workflow that can increase reliability and developer productivity.

CircleCI angular firebase workflow cloud functions