Automatically deploy your website to Firebase Hosting with GitHub Actions

Heng Wang
8 min readJan 10, 2021

--

Github Actions + Firebase Hosting + Publish = 🚀🚀🚀

For the past few years, I have been using Hugo as a static site generator to build my personal website and hosting the site on Firebase Hosting. Until recently, I’ve encountered Publish, yet another static site generator, BUT it lets you build your entire website using Swift! How cool is that!

For this particular tutorial, we will learn:

  • create a brand new website using Publish
  • integrate the firebase hosting GitHub Actions
  • preview your website on Firebase Hosting preview channels via GitHub pull requests
  • auto deploy your website when pull request merged

Prerequisites

Before we jump in, let’s first make sure we’ve prepared all the tools or setups we need.

  • Publish

Make sure you have publish command available in your local terminal. Luckily, Publish provides an incredibly easy way to install the tool — via Homebrew. Refer to the Installation section on Publish github repo.

❯ brew install publish
  • Firebase project

Have a Firebase project created for your new website. If not, go to the Firebase console page to create one. If you already have projects created and wish to use the existing one, that’s totally fine. You have the option to choose which project to host your website later.

  • Firebase CLI

Make sure the firebase command line tool is installed. If you have Nodejs installed, you can use npm to install it. For more information, you can refer to the Firebase CLI reference.

❯ npm install -g firebase-tools

Step 1 — Create a new Publish project

First I have already created a new repository on my GitHub demo-publish-firebase and cloned locally. To create a new Publish project, cd to the local repo folder and run the following command:

❯ publish new
✅ Generated website project for ‘DemoPublishFirebase’
Run ‘open Package.swift’ to open it and start building
❯ la
total 16
drwxr-xr-x 12 hengwang staff 384B 8 Jan 17:00 .git
-rw-r — r — 1 hengwang staff 56B 8 Jan 17:03 .gitignore
drwxr-xr-x 4 hengwang staff 128B 8 Jan 17:03 Content
-rw-r — r — 1 hengwang staff 506B 8 Jan 17:03 Package.swift
drwxr-xr-x 2 hengwang staff 64B 8 Jan 17:03 Resources
drwxr-xr-x 3 hengwang staff 96B 8 Jan 17:03 Sources

After the project successfully created, run the command publish run, and you will be able to see your website at localhost:8080.

So far so good.

Step 2 — Integrate GitHub Actions to deploy to Firebase Hosting

In your terminal, login to Firebase with command firebase login, follow steps in the prompt window to authenticate your account.

Once logged in, check the projects on your Firebase account using command firebase project:list. Make sure the one you wish to use for the website exists.

Next will be the most important command throughout this tutorial.

❯ firebase init hosting

The command will prompt many questions and eventually take care of setting up the GitHub Actions automatically. There are few things we need to pay attention to.

For Project Setup, choose Use an existing project and select the proper Firebase project from the list.

=== Project Setup
First, let’s associate this project directory with a Firebase project.
You can create multiple project aliases by running firebase use — add,
but for now we’ll just set up a default project.
? Please select an option: Use an existing project
? Select a default Firebase project for this directory: fir-publish-firebase (demo-publish-firebase)
i Using project fir-publish-firebase (demo-publish-firebase)

Next is the Hosting Setup.

=== Hosting SetupYour public directory is the folder (relative to your project directory) that
will contain Hosting assets to be uploaded with firebase deploy. If you
have a build process for your assets, use your build’s output directory.
? What do you want to use as your public directory? Output
? Configure as a single-page app (rewrite all urls to /index.html)? Yes
? Set up automatic builds and deploys with GitHub? Yes
? File Output/index.html already exists. Overwrite? No
i Skipping write of Output/index.html

The default public directory will point to the public folder. This folder usually is generated by the static site generator which basially contains all the resources needed to render your website. The Publish package will build and generate the website under Output folder. So here you need to manually change to Output as the public directory.

Next make sure you enable Set up automatic builds and deploys with GitHub?. Finally, the prompt will ask you if you want to overwrite the Output/index.html, set to No since we want to preserve the page generated by Publish instead of Firebase.

After this step, the CLI will prompt you to authenticate your GitHub account and choose the repo for deployment.

i Authorizing with GitHub to upload your service account to a GitHub repository’s secrets store.Visit this URL on this device to log in:
https://github.com/login/oauth/authorize?client_id=<client_id>&state=<state_id>&redirect_uri=http%3A%2F%2Flocalhost%3A9005&scope=read%3Auser%20repo%20public_repo
Waiting for authentication…

This step will basically create a service account in your GitHub repo with Firebase Hosting admin permissions and upload service account JSON to GitHub as the repository secrets FIREBASE_SERVICE_ACCOUNT_FIR_PUBLISH_FIREBASE.

Next we need to set up and create the workflow.

? Set up the workflow to run a build script before every deploy? (y/N) y
? What script should be run before every deploy? npm ci && npm run build
✔ Created workflow file /Users/hengwang/Developer/demo-publish-firebase/.github/workflows/firebase-hosting-pull-request.yml
? Set up automatic deployment to your site’s live channel when a PR is merged? Yes
? What is the name of the GitHub branch associated with your site’s live channel? main

We will leave the script npm ci && npm run build as default for now and will update it later. In the meantime, for the GitHub branch associated with your site’s live channel, you can put main if your GitHub repo was newly created or created recently(Otherwise, it might be set to master as the default branch for older repos).

At last, if you see the following messages, congratulations! You’ve completed the most critical part of this tutorial.

i Writing configuration info to firebase.json…
i Writing project information to .firebaserc…
✔ Firebase initialization complete!

For the full command logs, please see below.

At this point, you should expect to have two `.yml` files created for the GitHub Actions workflows under your project folder.

❯ tree -a -L 3 .github
.github
└── workflows
├── firebase-hosting-merge.yml
└── firebase-hosting-pull-request.yml
1 directory, 2 files

Step 3 — Create a pull request to preview your website

We have completed all the code and configurations in order to launch our website. Let’s create a pull request in GitHub to test it out.

Create a new branch feat/setup_workflow, commit all the local changes in your project, and push to GitHub. Full commands are showing below.

❯ git checkout -b feat/setup_workflow
❯ git add .
❯ git commit -m “setup workflow”
❯ git push — set-upstream origin feat/setup_workflow

Once the branch is pushed to GitHub, you will see the option to create a pull request. Click to create the pull request.

Wait for GitHub Actions to complete the workflow. Unfortunately, our first attempt failed due to a build command npm ci && npm run build.

Recall one of the question during the firebase host setup prompts.

? What script should be run before every deploy? npm ci && npm run build

We leave it as the default one. This is set in the GitHub Actions config files in our project. Since we will build and generate our website using Publish locally, then push the full site to the repo, we don’t need GitHub Actions to do extra build step for us. Open the github config files under .github/workflows/firebase-hosting-*.yml. Comment out the command - run: npm ci && npm run build in both files.

- uses: actions/checkout@v2
# — run: npm ci && npm run build

Commit and push the changes to the remote branch. Go to Actions tab of your repo, wait for the workflow to complete.

You will see the latest workflow has completed with the green check mark! Go back to your pull request page, you will see github-actions bot has added a comment with the preview URL of your website!

Click the link and it will open your new website in the browser. Awesome!

Step 4 — Merge pull request to trigger production deployment

We are just one-click away to bring the website alive in production! Feel free to make any changes of the website and push to the pull request. Click Merge pull request button to merge your pull request to the main branch. Note this will trigger another workflow in GitHub Actions. Go to the Actions tab and monitor the build progress.

Once the build progress completed, navigate to the Hosting page of your Firebase project and you will find a new release of your project deployed by GitHub Actions. Additionally, Firebase Hosting provides you two default domains to access your website. If you want to use your own domain, Firebase Hosting also provides the way by simply click the Add custom domain button.

Click either of the domains to access your website in production. Congratulations, you have setup a fully functional CI/CD pipeline through GitHub Actions so that you can focus on your content delivery! 😄

Conclusion

From this tutorial, we started from zero by creating a brand new personal website project using the static site generator Publish, which lets you build your entire website using Swift thanks to John Sundell. Then we integrated GitHub Actions to the project for auto deploying your website to Firebase Hosting. We’ve also exercised creating a pull request to preview the changes of your website before publishing them in public.

You can check the demo repo for this tutorial here. In the meantime, you can also visit my personal website which uses the same techniques mentioned in this tutorial at https://wangheng.ca.

Happy coding!

References

--

--

Responses (2)