Github Actions: Deploying Ionic Angular App to Firebase Hosting
Github Actions is Github’s way of CI/CD
GitHub Actions now supports CI/CD, free for public repositories.
CI or Continuous Integration is a mechanism to automate the process of merging new code into an existing code base, — and to test things before doing this merge. This means as a developer you don’t have to worry about — are things still working? Use Continuous Integration to automatically build and test your code as you push it to GitHub, preventing bugs from being deployed to production. That's all about continuous integration here.
What is Continuous Deployment?
CD or Continous Deployment is the process of deploying automatically this code after CI is over — e.g. deploying a website on the server automatically after the relevant code changes are done. Explaining CI/CD or discussing Continuous integration vs. continuous delivery vs. continuous deployment is not the point of this article — so we will move forward with these basic sets of simple definitions. After discussing Github Actions, let us see How to deploy Angular App to Firebase Hosting?
Building with GitHub Actions — Automate software workflows
In this article, we will see — How to use Github Actions for automatically deploying your Angular Web app (Ionic in this case) to Firebase Hosting.
After Github Actions, let us now move on to how to deploy Angular App to Firebase Hosting.
We also assume that you are testing your application via the automated unit tests — So we have added some part related to setting up those tests in the Github environment. However you are free to skip that step — it not at all required.
Preparation 🧑🍳
So let’s start with first knowing the application which we are going to deploy. I have a simple Grocery Dashboard made in the Ionic 5 framework. This app is available on Enappd.com
Note: We have already set up a firebase hosting environment. To get this setup done you can learn more about How to set up firebase hosting and environment to deploy
Setup Github Actions — Configuring a workflow :
The following are the steps to add a workflow file.
Step 1: Create Directory Structure
Create a directory .github
in your root folder and put another directory workflows
inside this. In workflows
directory, we will make some YAML files. the extension to make a YAML file is .yml
Step 2: Write the Basic Config in Workflow file
Create a YAML file of any name — main.yml
(In our case “main.yml” here). This YAML file will often be called the workflow file. As one file contains one workflow. You can create more files in this directory for more workflows.
Let’s understand each part one by one.
There are two main sections of a workflow file ( main.yml )
- Trigger: Trigger tells about the action (git related actions — push, merge, etc.) on which GitHub automated workflow will start. For example, it is
push
in the above example but it can be any other git related action likemerge.
Also, we have mentioned that this workflow will only be triggered with a push on the branchrefactor
. This way you can restrict the workflows to only certain branches that are related to deployment branches and not on every push done during the development phase. - Jobs: This part contains a list of jobs that will be triggered. In our case, we have given it a name
Build and Deploy
.name
as you can notice appears everywhere in the workflow file— they will be shown while your CI system will run. Every job has somesteps
— which are like commands to be executed sequentially. Here in the above file, we have many steps and each step is marked with somename
and some command inrun
. As jobs will need a working environment (Operating System) we have put aruns-on
part in at the start of the job with a value for the Ubuntu environment — you can change the environment according to your requirements. For most generic requirements Ubuntu seems to be an easy pick.
Step 3: Configuring the steps
- Checkout Repo — this is a step to checkout (git checkout) your latest code from the branch you mentioned in the above settings. You can see that there is a
uses
key which essentially means we are using pre-built GitHub Actions (Scripts). These workflow actions are written by the community and are very helpful to do complex actions. If you don’t know much about shell scripts and automation scripts — these are life saviors for you. You can check the whole list of such actions - Install Dependencies — This step is quite simple — Doing an
npm install,
as we are using an npm based project. - Build — In this step we are running
npm run build
which is used to create a build for our web applications. - Run Tests — In this step, we are using the command to test our code. Interesting to note, it will not run tests properly as well as on our local desktop. As in this CI environment, we don’t have the Chrome browser UI to be launched — however, we will make some adjustments to run the code. We will see that part later.
- Deploy to Firebase — Again we use an external Github Action here named
firebase actions
. This action will do a lot of complex stuff to make the Firebase CLI available in our CI environment — and we don’t have to install the firebase environment manually on the CI system. If you are confused about what is@
doing after these actions — it is just the version or branch of that action. In theargs
we will pass the command we use for hosting i.e.firebase deploy --only hosting
In this casefirebase
is not required to be put in this action and you can use the remaining part of the commanddeploy --only hosting
. Finally, to connect your firebase with your account you will need to login to firebase — but you can’t log in simply as this is an automated environment. So how to authenticate?
Step 4: Get Token from Firebase 🔥
You can go to your system and type the command.
firebase login:ci
Then you can choose the google account from which you are using the firebase account to deploy. In the end, you will be presented with a long token string that you can use for the value of FIREBASE_TOKEN
key in the last step. BEWARE: it is not a good practice to put a token available directly and can be a security concern. However, we will use this token right now to test. Later we can use Github Secret Store to hide this secret token from code view.
Let’s Go Live now 🤞
Now we are ready with all the script work. We can push the latest changes on the Github and it should work — at least we hope so
uh oh! 😞
Let us see what might have happened if you see ❌ Build .
We have not tested our code on the localhost — so we are facing some issues here. You should run all these steps beforehand on the local system. Because there is no way CI will magically deploy the code — unless everything is working fine.
After some fixes in our code, we are ready to go again.
This time build works but our tests ( Run Tests ) are stuck for a long time.🐌 🐌
REASON: We are not having Chrome on this CI Server and we can’t run a UI based browser here, so we need to make a small adjustment to our code
"scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "test": "ng test --watch false --browsers ChromeHeadless", "lint": "ng lint", "e2e": "ng e2e" }
We have changed test
script to work with ChromeHeadless which is already installed with karma launcher. Also, we made watch false
— so that test end after a single run. Otherwise, your tests will be running forever — Caution: Beware of such a mistake on CI as you may lose some free hours of Github Actions.
Now finally let’s run it again by pushing these changes.
YES !! My code works now. 🕺 💃.
Finally, you can refresh your firebase web app and you will find the new changes.
Github Secret Store 🤫
If you have come this far you can now move your secrets to Github Secret Store, which is under the SETTINGS tab.
Now you can update your YML file and put Token as
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
And everything runs fine !! 🏃♀️
Here is the final workflow file.