Deploy your Angular App to Firebase using BitBucket Pipelines

BitBucket Pipelines — Building, Deploying to Firebase Hosting (pt 1 — Static HTML)

The thing with side hustles is that you want to automate as much as possible. You write some code, fix a bug, run through some testing, then push to your automated testing pipeline, and if passes that, then deploy. However, this is often done either in the wee hours of the night or first thing in the morning. And this my friends is where automation is epic.

For source control, we chose BitBucket by Atlassian. There are many reasons for this, we were using it at our paying day jobs, the price was right (free for small teams), Trello integration, and it had pipelines. This is not an article on which provider is better but needless to say at this point in time, we are happy with BitBucket.

Process

So really what we needed was the following:

  1. Deploy our website to Firebase hosting
  2. Deploy our Angular Master branch to Firebase hosting (different URL)
  3. Deploy our Angular Develop branch to our testing site (again different URL)
  4. Ability to roll back if required
  5. Run automated test script and abort if failed

What would be awesome if this could “just work”, and with BitBucket Pipelines we were able to accomplish this task fairly easily. A couple of hours on the console, searching Google and reading the documentation and we were set.

First the Website

We set this up for the website first as it was felt this would be easiest. The next article will go into deploying the Angular side of things to the test and production environments.

Firebase Project Setup

If you already have a firebase project and can access the firebase console, you can skip this step.

You need to set up your Firebase account for hosting and add your own URL. There are plenty of tutorials online on how to do this, so we won’t get into that here. (See here, here, or here )

Firebase hosting project

Now that Firebase is expecting to host your site, you need to use the Firebase CLI to initialize the project. This is easy and will create .firebaserc and a firebase.json file.

Those files are used by Firebase to know how to handle and deploy your project. Once created, they likely will not need to be modified.

Again there are lots of tutorials on how to do this already — and since this is about how to use Pipelines we are assuming you have already done so. If not, a great tutorial on this can be found here specifically Step 6 for this part.

Now that you have your project all set up and ready to go. Hopefully, you have tried to push a version to your Firebase project and of course, committed the new files created to your BitBucket repo (they are used by Pipelines later).

Get your token

Since you do not want to store your credentials (you can — but should you? — no you shouldn’t) you will need to generate a token that will be used with for this project. To get a token, run the following command:

$ firebase login:ci

You will be required to authenticate to the Firebase console via web browser popup. Once you have authenticated, you will see a line that says:

 Success! Use this token to login on a CI server:

Your token is immediately after that line. Copy and save that token — you will need it later.

That is all you need to do on the project side, now into BitBucket.

Pipelines overview

When you setup pipelines, a file will be added to your source control named bitbucket-pipelines.yml. This file contains your pipeline script. Please note that when you first enable, the file is created in your master branch. This file is subject to how you use GIT. It is possible depending on your branching that you — and where you want pipelines to run, that you may have issues when you merge branches. For example, if you have a version in develop, and then merge back into master that you could overwrite or add calls. There are ways around this which we will get into that when we get into the Angular site vs the static HTML site. Our static HTML site will be pulled strictly from our master branch, so this risk is limited in this scenario.

Schedules

You can set up schedules to run your pipelines. This is handy if you want to have to deploy weekly, monthly, or at a set time every day, however, given your limited number of commits, we will want to push out every commit to our branch.

Docker

Pipelines use a Docker instance to run the pipeline. As we go through the setup, there are many options here depending on how you want to use it.

Enable Pipelines in your Project

The first thing you need to do is enable Pipelines in your project. Even free projects have 50 minutes a month — so you definitely can set this up. The minutes renew on the first of every month. At this time you can get an additional 1000 minutes of pipelines time for $10.

This is done under the Project Settings menu item, scrolling to the Pipeline Settings section, and selecting the Settings link.

Repository Variables

Now we get to use that token you created above. Go to the Repository Variables link in your project and in the Name box enter: FIREBASE_TOKEN and in the Value box paste in your token. We will refer to this in your script file.

bitbucket-piplines.yml

This is our master branch file:

image: node:8.12.0
pipelines:
branches:
master:
- step:
deployment: production
caches:
- node
script:
- npm install -g firebase-tools
- firebase deploy --token=$FIREBASE_TOKEN --project your-firebase-projectname --non-interactive

Let's break this down line by line.

image: node:8.12.0

We are using the node:8.12.0 docker image. This works with the firebase-tools npm package we install later in the package and has node already installed on it.

branches:
master:

We use the branches line since we only want this to run on the master branch.

- step:
deployment: production

After the branches have been defined, you need to have a -step:. This is the code block that is your instructions on what to do.

By using deployment:production we are telling the deployment tool that we are going to deploy to production. This is important as we can have different deployment scripts for testing and production. When we go into our app deployment, you will see where we use this depending on the branch.

caches:
- node

Since you pay for minutes when using pipelines you want to be as efficient as possible. This means that if you are downloading a lot of packages as part of your deployment, you could be wasting time repeatedly downloading the same thing. This is where the caches: line comes in, you are telling BitBucket that you want to have a local cache of the download so that you only need to download the npm packages on the first pipeline run, or when there are updates only. Full documentation can be found here.

script:

Now that we have defined the setup for the pipeline to run, we get to tell it what do to. That is what follows thescript: block. These are the line by line commands run.

- npm install -g firebase-tools

Straightforward npm install command. We need to install the firebase-tools to use for deployment. If you caches are set up properly, this will only check to ensure the latest version is installed. I have not been able to get this to work without the -g flag — if you know of a way, please leave a comment below.

- firebase deploy --token=$FIREBASE_TOKEN --project your-firebase-projectname --non-interactive

This line is the actual deployment line and tells the firebase CLI to deploy to your instance. Since you already have the CLI installed on your dev machine (that is how you got the token) — you can test this command out before you run through the pipelines. That will ensure that your project is configured properly ahead of time. Ensure you have the --non-interactive flag set otherwise it the CLI will be expecting a user interaction.

Ready to deploy!

Once this is saved to your master branch, every time there is a commit to your master branch, then this will run. To confirm, make a small change (i.e. add an HTML comment) to your website somewhere and then commit. The pipeline process will run, and your site will be automatically deployed to Firebase hosting.

What if it fails?

No worries, you get an email stating as such. If your site is borked because of the failure you can go into your Firebase console and roll back to the previous version of the website. This is done by going to the hosting section of your firebase console, go to the Release History section and selecting Roll Back to the version you want to roll back to (hint: click on the three dots) and Firebase will rollback immediately.

But wait there is more…

In the next article, we will get into deploying are an Angular app, with a separate set of commands depending on which branch it is committed to. Click here to continue enhancing your pipelines.