How to Deploy Hugo Static Website with Github Actions

veerendra2

Veerendra K

Posted on July 6, 2023

How to Deploy Hugo Static Website with Github Actions

As you know Hugo is a lightning-fast static website generator perfect for building modern websites. It has been almost 2 years since I’m using Hugo for my GitHub Pages blog https://veerendra2.github.io/. I’m comfortable using Hugo after I moved from Jekyll; https://veerendra2.github.io/moving-to-hugo/

In this write-up, I will show you how I‘m using Github Actions to build and deploy static websites on GitHub Pages.

👉 Here is my GitHub Actions workflow https://gist.github.com/veerendra2/28d35b44c8340d5a801e5606edb32f45

Background

I have 2 GitHub repositories, one is the source and the other is the destination.

Image description

The source repo contains markdown files where I write my blog content in these files and the destination contains a static HTML website which is served by GitHub Pages.

You can also use single repo with 2 branches to keep markdown files and a static HTML website. In fact, my previous setup was like this.

Image description

Basically, you keep all your source markdown files in a feature branch(In my case, it is “source”) and by using GitHub Actions, move the static HTML website to the “master” branch. You can take reference to this approach in my previous write-up

Like I said before, currently, I’m using 2 repos approach to keep my draft post private #12

Workflow

Usually, when I get new idea, I will create a GitHub issue for reference like below

Image description

And then I do

Image description

In the end, GitHub Actions trigger and publish my new blog post on https://veerendra2.github.io/

Github Action Workflow

👉 https://gist.github.com/veerendra2/28d35b44c8340d5a801e5606edb32f45

The workflow is straightforward and improved recently. The workflow triggers when the PR closed(Or you can also when the feature branch is merged to “main”).

...  
pull_request:
    types:
      - closed
...
Enter fullscreen mode Exit fullscreen mode
  • Checkout both source and destination repos with “path” argument as you can see below.
...
    steps:
      - name: Checkout ${{ github.repository_owner }}/${{ env.SRC_REPO }}
        uses: actions/checkout@v3
        with:
          path: ${{ env.SRC_REPO }}

      - name: Checkout ${{ github.repository_owner }}/${{ env.DEST_REPO }}
        uses: actions/checkout@v3
        with:
          fetch-depth: 0
          repository: ${{ github.repository_owner }}/${{ env.DEST_REPO }}
          path: ${{ env.DEST_REPO }}
          token: ${{ secrets.TOKEN_TO_PUSH_REPO }}
...
Enter fullscreen mode Exit fullscreen mode
  • Setup and build the Hugo website using options “-d” destination directory and “-s” source directory.
...
      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v2
        with:
          hugo-version: "0.110.0"
          extended: true

      - name: Build Hugo site
        run: |
          hugo --minify \
              -s ${{ github.workspace }}/${{ env.SRC_REPO }} \
              -d ${{ github.workspace }}/${{ env.DEST_REPO }}
...
Enter fullscreen mode Exit fullscreen mode
  • Finally, commit your changes and push them to the destination repo.
...
      - name: Commit ${{ github.repository_owner }}/${{ env.DEST_REPO }}
        run: |
          cd ${{ github.workspace }}/${{ env.DEST_REPO }}
          git config --global --add safe.directory ${{ github.workspace }}
          git config --local user.email "actions@github.com"
          git config --local user.name "GitHub actions"
          git add -A
          git commit -m "New changes" -a

      - name: Push changes
        uses: ad-m/github-push-action@master
        with:
          github_token: ${{ secrets.TOKEN_TO_PUSH_REPO }}
          directory: ${{ github.workspace }}/${{ env.DEST_REPO }}
          repository: ${{ github.repository_owner }}/${{ env.DEST_REPO }}
          force: true
...
Enter fullscreen mode Exit fullscreen mode

That’s it, this simple workflow build and publishes my blog posts.

But wait, there is one more trigger I placed as you might have noticed…

...
  workflow_dispatch:
    inputs:
      blog:
        description: "Publish Blog"
        required: true
        default: "yes"
...
Enter fullscreen mode Exit fullscreen mode

This is because, sometimes I make changes/fixes on the “main” branch itself, for this, it won’t trigger the pipeline to publish my changes/fixes. That’s why I have added a manually trigger like below.

Image description

Let me know how you guys deploy your static website.

💖 💪 🙅 🚩
veerendra2
Veerendra K

Posted on July 6, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related