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_repoWaiting 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.yml1 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
- Deploy to live & preview channels via GitHub pull requests
- Firebase Hosting GitHub Action
- Publish — the static site generator enales you to build your entire website using Swift