How to Deploy Hugo Static Website with Github Actions
Tags: hugo, githubactions, cicd
Published: 2023-07-06 15:19:41

As you know [Hugo](https://gohugo.io/) 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zvvkpnvn00027yzporrm.png)


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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ibprm5hlphj2hq40vcev.png)

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](https://veerendra2.github.io/ci-cd-github-pages-with-github-actions/)

Like I said before, currently, I’m using 2 repos approach to keep my draft post private [#12](https://github.com/veerendra2/veerendra2.github.io/issues/12)

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


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hko3e47e44mfpp9v0wlr.png)



And then I do

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/71a5pbj39qp34tulng21.png)

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”).
```yaml
...  
pull_request:
    types:
      - closed
...
```

* Checkout both source and destination repos with “path” argument as you can see below.
```yaml
...
    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 }}
...
```

* Setup and build the Hugo website using options “-d” destination directory and “-s” source directory.
```yaml
...
      - 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 }}
...
```
* Finally, commit your changes and push them to the destination repo.
```yaml
...
      - 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
...
```
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…
```yaml
...
  workflow_dispatch:
    inputs:
      blog:
        description: "Publish Blog"
        required: true
        default: "yes"
...
```

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5njrv3u7ttvqsv4tyxdc.png)



Let me know how you guys deploy your static website.