Deploy Hugo site to Workers Sites using GitHub Actions
Tags: hugo, tutorial, cloudflare, actions
Published: 2021-02-15 02:07:42

**In this post we look at how to deploy Hugo sites to Cloudflare Workers Sites using GitHub Actions.**

Cloudflare [Workers Sites](https://developers.cloudflare.com/workers/platform/sites) is Cloudflare's service for hosting static websites directly on Cloudflare's edge nodes. [Hugo](https://gohugo.io) is a program for generating static web pages easily and quickly.  

If your static website is already in a repository on GitHub, using GitHub Actions is the best way to automate building your website, uploading to Workers Sites and so on, saving you a lot of manual work.

This post already assumes that your Hugo site is on GitHub and also that an associated Workers Site [has already been set up](https://developers.cloudflare.com/workers/platform/sites/start-from-existing). 

## Table of Contents
1. [Introduction to GitHub Actions](#introduction-to-github-actions)
2. [Install Hugo and build site](#install-hugo-and-build-site)
3. [Publish to Cloudflare Workers Sites](#publish-to-cloudflare-workers-sites)
4. [Full example](#full-example)
5. [Conclusion](#conclusion)

<a id="introduction-to-github-actions"></a>

## Introduction to GitHub Actions
**GitHub Actions** is a service from GitHub that automates regular tasks (e.g. building the software, publishing, testing, etc) into once-defined workflows, and then automates them, for example, when a release is created, when pushed to the main branch, when an issue is created, and so on.  

The workflows are stored in the `.github/workflows` folder and are written as `.yml` files.

For example, a simple workflow might look like this:

```yaml
name: Workflow Example

on:
  push:
    branches: [ $default-branch ]
  pull_request:
    branches: [ $default-branch ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - run: echo Hello World!
```

This workflow simply checks out the latest version of the repository from the default branch and then prints `Hello World!` to the console. The workflow runs on the latest Ubuntu version, `ubuntu-latest`.  

All commands to be executed are specified under `steps`. Actions created by other users can be specified with `uses`.

<a id="install-hugo-and-build-site"></a>

## Install Hugo and build site
To install Hugo and build the page, we use an action developed by another user, [`peaceiris/actions-hugo`](https://github.com/marketplace/actions/hugo-setup). We configure this action to always install the latest and extended version of Hugo.

So now our steps section of the workflow configuration looks like this:

```yaml
steps:
- uses: actions/checkout@v2
- name: Setup Hugo
  uses: peaceiris/actions-hugo@v2
  with:
    hugo-version: 'latest'
    extended: true
- name: Build site
  run: hugo --minify
```

The first step checks out the latest version of the repository, the second step installs Hugo, and the third step builds a minified version of the site.

<a id="publish-to-cloudflare-workers-sites"></a>

## Publish to Cloudflare Workers Sites
As previously stated, this post assumes that a Cloudflare Workers Site has already been initialized [as described here](https://developers.cloudflare.com/workers/platform/sites/start-from-existing).

To upload the built site to Cloudflare Workers Sites, we use the [cloudflare/wrangler-action](https://github.com/marketplace/actions/deploy-to-cloudflare-workers-with-wrangler) officially provided by Cloudflare.  

So now we add this step to the `steps` section of our workflow as well:

```yaml
steps:
- uses: actions/checkout@v2
- name: Setup Hugo
  uses: peaceiris/actions-hugo@v2
  with:
    hugo-version: 'latest'
    extended: true
- name: Build site
  run: hugo --minify
- name: Publish to Workers Sites
  uses: cloudflare/wrangler-action@1.3.0
  with:
    apiToken: ${{ secrets.CF_API_TOKEN }}
```

In the new step, there is now also a reference to a secret called `CF_API_TOKEN`. We need to set this to a Cloudflare API token with some Workers permissions in our repository settings.

This API key can be created in the Cloudflare settings under My Profile > API Tokens.

The new API token must be assigned the following permissions:

- All accounts: Workers KV Storage:Edit, Workers Scripts:Edit, Account Settings:Read.
- All zones (or only the "zone" through which the website will later be accessible): Workers Routes:Edit
- All users: User Details:Read

This key can now be stored in the repository settings in the section Secrets under the name `CF_API_TOKEN`.

<a id="full-example"></a>

## Full example
```yaml
name: Build & Publish

on:
  push:
    branches: [ $default-branch ]
  pull_request:
    branches: [ $default-branch ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Setup Hugo
      uses: peaceiris/actions-hugo@v2
      with:
        hugo-version: 'latest'
        extended: true
    - name: Build site
      run: hugo --minify
    - name: Publish to Workers Sites
      uses: cloudflare/wrangler-action@1.3.0
      with:
        apiToken: ${{ secrets.CF_API_TOKEN }}
```

**_Done!_** Now every time someone pushes to the main branch, the website is built using hugo and published to Cloudflare Workers Sites.

<a id="conclusion"></a>

## Conclusion
Hugo is one of the easiest and fastest tools to build static websites. Cloudflare Workers Sites is a relative newcomer to the static hosting market, but with Cloudflare's long established and fast network, your website is close to your users and speed is guaranteed.

Using GitHub Actions, the manual building and publishing process can then also be automated, reducing manual effort to a minimum.