So in the short guide, I'm going to show you how I deploy an angular site to Google's firebase hosting using Gitlabs CI/CD Pipelines to do all the build and deploy for me.
I'm also going to be doing a staging / production builds, this way I can see things in staging and test/play and when i'm happy, push my changes to the repo's main/master
branch and Gitlab will deploy it all to production.
Ok, so first thing, we need the Firebase CLI installed, using the following command in your terminal:
npm install -g firebase-tools
Once that is all done, head over to the Firebase Console and create 2 new projects:
For this demo, I created 2
fir-hosting-demo-staging
and
fir-hosting-demo-prod
You need to have 2 seperate projects if you want to deploy to staging and then production, if you don't, just create the one project.
Once they're created, head back over to your Angular application, we've got a bit of preparation to do.
Navigate to your angular application using a terminal and run the following command:
firebase init
Highlight the hosting
option and then the Use an existing project
option.
Select your Staging project from the list that you get by using the arrow keys.
You'll then be asked the question
What do you want to use as your public directory?
This is the path that is set in the angular.json
for outputPath
, it's the path that everything goes to when you run ng build
.
For me, it is dist/firebase-hosting-demo
as that is the name of my Angular application. So set it to that.
You'll then be asked about redirects and as its an angular application, you'll want to select yes
to redirect everything to index.html
.
Once you have ran this command, open up the newly created file called .firebaserc
and it should look something like this:
{
"projects": {
"default": "fir-hosting-demo-staging"
}
}
I like to rename my project alias, so go ahead and change default
to staging
{
"projects": {
"staging": "fir-hosting-demo-staging"
}
}
We're now going to add our production hosting, run the following command in the terminal.
firebase use --add
You'll then be given a list of your current firebase projects, select the production one you created.
You then have to give it an alias, I like to call mine production
.
If you head over to the .firebaserc
file, it should now look like this:
{
"projects": {
"staging": "fir-hosting-demo-staging",
"production": "fir-hosting-demo-prod"
}
}
You can now in the terminal of that project, just run
firebase use staging
and it will switch to use the staging project, same for firebase use production
.
Now, if everything has been setup right, you can go ahead and do a test build/deploy.
In your terminal, make sure you're using staging
by running
firebase use staging
Build your Angular application using the command
ng build
Once that has built, you should have a dist
folder with your application inside, for me it's dist/firebase-hosting-demo
.
Go ahead and run the command firebase deploy --only hosting
and watch as Firebase will now take all the built files from the output folder and upload them to firebase staging branch.
Once that has completed, the firebase cli will return a Hosting URL where you can see you staging application.
You can do the same for the production branch buy running the command to switch to production firebase use production
and then the same firebase deploy --only hosting
and the same files will be pushed to the production project in firebase.
This is good for testing, but it will become a bit tedious to remember which branch you're on, which project you're using and remembering that you need to build/push your code.
This is where we're going to leverage Gitlab and let it do all of the work for you.
Other CI/CD tools can do the same, I just mainly use Gitlab.
So now this is all setup, let's move onto the next step!
Gitlab
If you have your code all stored in Gitlab, the way I like to work is have 3 branches, master
, staging
, and develop
.
Both master
and staging
are protected branches and cannot be pushed to locally, only via a merge request using Gitlab.
So, for me, I'm going to switch to the develop
branch of my code.
git checkout -b develop
We're going to need a CI Token, this is a firebase token that Gitlab can use to act on our behalf. To get one of these, in your terminal, run the command
firebase login:ci
A popup will appear in your browser to login and ask for permissions, once you have done that, back in your terminal, you'll be given a CI Token that looks a bit like this.
1//03s000000000000000000000F-L9I00000000000000W-_000000Tg
I have purposely changed mine for this demo, yours won't have lots of zeros inside it.
Head over to gitlab as we now need to store this token in the project.
In your repo in gitlab, click the Settings > CI/CD and expand the section for Variables.
Click the Add Variable
button and a window like this will appear.
Call the variable FIREBASE_TOKEN
, and paste in the value you got from the ci:login
before. I don't have the variable protected or masked, I have found that sometimes Gitlab has issues when I check these options.
Save the variable and we're done with this part of the setup.
Back into our code, create a new file at the ROOT
level of your project called .gitlab-ci.yml
. This is a file that gives Gitlab the instructions needed to build your project.
Paste in the following into that file:
stages:
- build
- deploy
image: node:12.13.0-alpine
cache:
paths:
- node_modules/
build-staging:
stage: build
rules:
- if: $CI_COMMIT_BRANCH == "staging"
script:
# Install dependencies
- npm install
# Build App
- npm run build
artifacts:
paths:
# Build folder
- dist/firebase-hosting-demo
expire_in: 1 hour
deploy-staging:
stage: deploy
script:
- npm install -g firebase-tools
- firebase use --token $FIREBASE_TOKEN staging
- firebase deploy --only hosting -m "Pipeline $CI_PIPELINE_ID, build $CI_BUILD_ID" --non-interactive --token $FIREBASE_TOKEN
rules:
- if: $CI_COMMIT_BRANCH == "staging"
build-production:
stage: build
rules:
- if: $CI_COMMIT_BRANCH == "master"
script:
# Install dependencies
- npm install
# Build App
- npm run build
artifacts:
paths:
# Build folder
- dist/firebase-hosting-demo
expire_in: 1 hour
deploy-production:
stage: deploy
script:
- npm install -g firebase-tools
- firebase use --token $FIREBASE_TOKEN production
- firebase deploy --only hosting -m "Pipeline $CI_PIPELINE_ID, build $CI_BUILD_ID" --non-interactive --token $FIREBASE_TOKEN
rules:
- if: $CI_COMMIT_BRANCH == "master"
I'm not going to go over in depth what this file does, but essentially, it will build and deploy your Angular application for you, but use different Firebase projects depending on what Git branch you use.
So the idea is, make some code changes on your develop
branch. Once you're happy, commit and push your code to the remote develop branch.
Do a merge request when you're ready from develop
to staging
and watch as Gitlab will start a pipeline to build your Angular app and deploy it to Firebase.
When you're happy to go live, do another merge request from staging
to master
in Gitlab and it will build again and deploy to production.
The first time this runs it might take some time, this is because in my gitlab-ci.yml
file, I have specified to cache the node_modules
, but once this has done, pipelines that run after this should be faster!
Hope you enjoyed my guide, and any questions, don't hesitate to contact me!.
Top comments (3)
node:12.13.0-alpine
not working anymore, upgrade tonode:16.19-alpine3.16
to work.Also,
--token
is not working anymore, the pipeline must use the newGOOGLE_APPLICATION_CREDENTIALS
instead.Do you know how to use a google service account?
Thank you