My boring Blog

Mauro Frigerio blog

Automatically update site created with Hugo

01-10-2021 3 min read article

CMS’s like WordPress or Joomla are convenient, but they need constant updates, as regularly there are quite urgent security updates. That’s also why a year ago I went back to a static site, to be precise using Hugo. So I worry about creating the content and when I load new pages I don’t have to think what’s on the server anymore.

The disadvantage of this system is the need to have a computer to generate the site again and then upload everything on the server. GIT and Github are fantastic because once correctly configured they simplify the management of new content for Hugo websites.

In Github you can create automations or Actions whenever a new version of code is uploaded. When I first started with Hugo I configured an automation that would update the site as soon as a new post is uploaded to a Github branch. The automation create a virtual machine and fully generates the new site inside it. Then all files are uploaded via SFTP to the website server. The total procedure takes a long time, the generation takes a few seconds, while the upload of all files (even the unchanged ones) takes almost 15 minutes. Definitely too long. The whole thing works and since the time at my disposal is not much I couldn’t look for an alternative solution. But it always bothered me a lot.

Finally I found a solution that works and is much faster. I’m sure there is a better solution out there, but I’m happy with the performance.

The core of the new solution is a copy on Github of the latest generated version of the site. Since I have a test one and the production one, I created two separate folders. Hugo only has to edit the modified files and all others are untouched. Then thanks to rsync only the respective updated files are loaded. After the upload the new version of the site is saved in the repository, ready for a new post. In the options of Hugo and rsync you shouldn’t forget the option to delete files you don’t need anymore (option --cleanDestinationDir for Hugo and --delete for rsync).

So I managed to go from 14-15 minutes to less than 2, much more acceptable for my patience.

This is the code of my Github Action for the test site, the secret fields are configured in the repository settings:


      - integration

    runs-on: ubuntu-latest

      - uses: actions/checkout@v2
          submodules: true  # Fetch Hugo themes
          fetch-depth: 0    # Fetch all history for .GitInfo and .Lastmod

      - name: Setup Hugo
        run: |
          sudo snap install hugo
          hugo --config config-integration.toml --minify --cleanDestinationDir --destination "public-integration/"          

      #- name: Setup tmate session
      #  uses: mxschmitt/action-tmate@v2
      - name: rsync deployments
        uses: burnett01/rsync-deployments@5.1
          switches: -avzr --delete
          path: public-integration/
          remote_path: integration-site/
          remote_host: ${{ secrets.SSH_SERVER }}
          remote_user: ${{ secrets.SSH_USER }}
          remote_key: ${{ secrets.SSH_PRIV_KEY }}

      - name: Archive production artifacts
        uses: actions/upload-artifact@v2
          name: dist-without-markdown
          path: |