Overview
I was inspired to create this blog after watching a NetworkChuck video from about 5 months ago. He talked about building out a pipeline to automatically format notes from Obsidian using Hugo, push the results to a GitHub repository, and then have GitHub send a webhook to Hostinger which would trigger Hostinger to clone his repository and update his website. I think that the pipeline he created is really cool and he has a detailed post about it on his blog so I decided to try it out for myself. I figured that if I was going down this rabbit hole anyway, I figured I might as well try to make some improvements to his pipeline and get hands-on with GitHub Actions along the way!
Improvements
After watching Chuck’s video, the biggest opportunities for improvement in my opinion were to offload as much of the processing/work from the endpoint as possible, and to make the deployment of new posts more integrated with Obsidian (instead of maintaining a separate script).
1. Offload Processing and Configuration with GitHub Actions
Chuck put together a Python script that copies blog posts and images from his Obsidian vault, reformats image references so that Hugo will understand them, runs Hugo, and then pushes the results to his GitHub repository. I decided that instead of running Python locally, this would be a perfect opportunity to get hands-on with GitHub actions!
I created a GitHub action workflow that installs Hugo, builds the site based on the data in my GitHub repository, and then posts it to GitHub Pages:
name: hugo-build-deploy
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the "main" branch
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
build:
runs-on: ubuntu-latest
env:
HUGO_VERSION: 0.147.0
steps:
- name: Install hugo
run: |
wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
&& sudo dpkg -i ${{ runner.temp }}/hugo.deb
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup Pages
id: pages
uses: actions/configure-pages@v5
- name: Install Node.js dependencies
run: "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true"
- name: Build with hugo
env:
HUGO_CACHEDIR: ${{ runner.temp }}/hugo_cache
HUGO_ENVIRONMENT: production
run: |
hugo \
--minify \
--baseURL "${{ steps.pages.outputs.base_url }}/"
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./public
deploy:
runs-on: ubuntu-latest
needs: build
permissions:
contents: write
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub pages
id: deployment
uses: actions/deploy-pages@v4
You’ll also notice that I’m deploying to GitHub pages rather than Hostinger. GitHub pages is free (even with custom domains) and integrates tightly with GitHub actions and the broader GitHub ecosystem.
Now whenever I push updated content to my GitHub repo, the workflow I created automatically runs and deploys the latest content to pages:
2. Tighter Integration with Obsidian
The other missing piece for me was the ability to publish directly from within Obsidian and to solve that I found the Hugo Publish plug-in for Obsidian. You can install this plug-in from Obsidian’s Community Plug-Ins section in the settings.
Once the plug-in is installed, there are a few settings you need to configure including the local folder to publish to as well as the content/posts folder that you want to use within the folder structure. You can also configure the plug-in to only post notes with a certain tag so that your private notes don’t get published to your blog.
This plugin also handles all of the image copying and image reference conversions to get images working in your blog posts just like they do in Obsidian.
Future Improvements
The one obvious weak point that still exists in my pipeline is pushing changes to my GitHub repository. The Obsidian plug-in I found posts changes to a local folder, but it doesn’t automatically push them up to GitHub and my workflows only trigger when a new push occurs. In the future, I’d like to set up a button, keyboard shortcut, or cron job to automatically commit and push changes, removing the need to do this manually.
Conclusion
I’m really glad that NetworkChuck started a blog and inspired me to create one as well. The pipeline he set up was a great idea and I hope that the minor improvements I’ve made here will be helpful (or at least interesting) to others!
Resources
- NetworkChuck’s Video: My Insane Blog Pipeline (YouTube)
- NetworkChuck’s Blog Post: My Insane Blog Pipeline (Blog)
Tools & Platforms
- Obsidian (note-taking app): https://obsidian.md/
- Hugo (static site generator): https://gohugo.io/
- GitHub Actions (CI/CD platform): https://docs.github.com/en/actions
- GitHub Pages (static site hosting): https://pages.github.com/
- Hostinger (web hosting): https://www.hostinger.com/
Obsidian Plugins
- Hugo Publish Plug-in: https://github.com/kirito41dd/obsidian-hugo-publish
(Can be installed from the Community Plug-ins section in Obsidian settings)