Here I describe how this site is managed and published.
The general idea is pretty straight forward. I use an Obsidian centric workflow for managing my notes on a day to day basis and I use Syncthing for keeping my vault up to date between devices.
On my server I have a script that checks any changes to the syncthing directory in to git every 5 minutes (via cron):
#!/bin/bash
cd /path/to/mynotes
# Check if there are any changes
if [ -n "$(git status --porcelain)" ]; then
# Changes are present; add, commit, and push
git add .
git commit -m "Automated content changes"
git push
else
echo "No changes detected"
fi
If changes are found, the subsequent push to git triggers a CI job which builds my website. I use a small python script called notesync to recursively check all my notes for a public: true
tag in the metadata and copy them to my quartz site.
The CI script is:
#!/bin/bash
/path/to/virtualenv/bin/python \
-m notesync \
-i /path/to/mynotes \
-o /home/to/myquartzsite/content\
--ignore "**/Work/**"\
--ignore "**/Journal/**"\
--ignore "**/Meetings/**"
# copy image assets that I've chosen to make public too
cp -r /path/to/mynotes/assets/public/* /home/to/myquartzsite/content
# move back to website dir
cd /home/to/myquartzsite
# run the quartz build
npx quartz build
Then I copy the output from this directory (which comes under a subdirectory called public
) to a folder that I serve up to the internet:
beta.jamesravey.me, notes.jamesravey.me {
root * /path/to/public
file_server
try_files {path} {path}.html {path}/ /404.html
handle_errors {
@404 {
expression {http.error.status_code} == 404
}
rewrite @404 /404.html
file_server
}
log {
output file /var/log/caddy/my-notes-site.log {
roll_size 2M
roll_keep 10
}
}
}
In theory you could do all of this from a single CI action like this:
name: Build and Deploy
on:
push:
branches:
- main # or your default branch
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout current project
uses: actions/checkout@v3
- name: Checkout notes project
uses: actions/checkout@v3
with:
repository: your-username/notes-repo # Replace with your notes repository
path: /projects/notes
- name: Set up Python 3.10
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install notesync
run: |
python -m venv /path/to/virtualenv
/path/to/virtualenv/bin/pip install git+https://git.jamesravey.me/ravenscroftj/notesync.git
- name: Run notesync and copy assets
run: |
/path/to/virtualenv/bin/python \
-m notesync \
-i /projects/notes \
-o /home/to/myquartzsite/content \
--ignore "**/Work/**" \
--ignore "**/Journal/**" \
--ignore "**/Meetings/**"
cp -r /projects/notes/assets/public/* /home/to/myquartzsite/content
- name: Set up Node.js 20
uses: actions/setup-node@v3
with:
node-version: '20'
- name: Build Quartz site
run: |
cd /home/to/myquartzsite
npm install
npx quartz build
- name: Deploy to web host via SFTP
env:
HOST: ${{ secrets.SFTP_HOST }}
USER: ${{ secrets.SFTP_USERNAME }}
PASS: ${{ secrets.SFTP_PASSWORD }}
REMOTE_DIR: ${{ secrets.SFTP_REMOTE_DIR }}
run: |
lftp -c "set sftp:auto-confirm yes; \
open -u $USER,$PASS sftp://$HOST; \
mirror -Rev /home/to/myquartzsite/public $REMOTE_DIR \
--ignore-time \
--parallel=10 \
--exclude-glob .git* \
--exclude-glob .env \
--exclude .DS_Store \
--transfer-all"
The quartz documentation also provides a lot of great hints and tips for how to publish using the framework.