Github to Firebase, Made Easier

Way back in 2019 I wrote about how I moved from Wordpress to Hugo.

Publishing a new blog post involved two Git repositories,, and lots of headaches (submodules, private and public repositories, etc). I always found dealing with the submodules a hassle. I never seemed to figure out a reproducible workflow of update repo, commit and push to Github, and finally updating Firebase. For all the playing around with submodules I’ve done, mastering them still escapes me.

Along came Github Actions. Actions are automatable steps you can perform in response to actions on your Github repo (push), as well as on their own via crontab, among other things. This sounded perfect. Could I get rid of the Travis integration? Could I only deal with one repository?

Answers to the above questions: yes. I admit, I have barely scratched the surface of what the actions can do. My goal was to replace my complicated workflow with something simpler.

So what is involved in wiring up Github actions to push to Firebase?

First .github/workflows/main.yml:

name: Hugo
on: [push]

    name: Build
    runs-on: ubuntu-18.04
      - name: Check out code into the Go module directory
        uses: actions/checkout@v2
          submodules: true  # Fetch Hugo themes (true OR recursive)
          fetch-depth: 0    # Fetch all history for .GitInfo and .Lastmod
      - name: Set up Hugo
        uses: peaceiris/actions-hugo@v2
          hugo-version: 'latest'
          extended: true
      - name: Build
        run: hugo --minify
      - name: Deploy to Firebase
        uses: w9jds/firebase-action@master
          args: deploy --only hosting:HOSTING_SITE_TARGET_POINTER
          FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}

From a high level: On a push to the repository, the code is checked out, including submodules, Hugo (the extended version) is run on the checked-out repository, with the firebase action deploying the ‘prod-site’ target. The FIREBASE_TOKEN is a Github secret which is a deploy key for my Firebase project.


  "projects": {
    "default": "$FIREBASE-PROJECT"
  "targets": {
      "hosting": {


  "hosting": {
    "public": "public",
    "ignore": [

I admit to not knowing all the firebaserc and firebase.json options, but my understanding in the context of getting this working is: The flag to the deploy call above mentions hosting (As the Firebase service), as well as a hosting site targt. This target corresponds to an actual Firebase site within your Firebase project. This hosting site is the target of the Hugo generated content inside the public directory.