Architecture
Personal blog built with Quarto, deployed to GitHub Pages via CI.
Structure
_quarto.yml — site config (theme, fonts, grid, output-dir)
custom.scss — all custom CSS overrides (Bootstrap/Quarto)
styles.css — minimal extra styles
posts/ — blog posts (*.qmd)
projects/ — project write-ups (*.qmd)
_freeze/ — pre-computed notebook outputs (committed)
.github/workflows/ — CI publish workflow
Publish Architecture
Source branch: main (.qmd source files, custom.scss, config) Published branch: gh-pages (rendered HTML, managed entirely by CI) GitHub Pages setting: gh-pages branch, root /
CI Workflow (.github/workflows/publish.yml)
On every push to main: 1. quarto render — renders all .qmd files to docs/ (output-dir) 2. peaceiris/actions-gh-pages@v4 — pushes docs/ contents to root of gh-pages branch
docs/ is gitignored on main. Never commit it.
Gotchas
quarto publish is incompatible with output-dir: docs
Do not use quarto publish gh-pages in CI. Quarto’s publish render step expects intermediate HTML to land at the source file’s directory (e.g. posts/foo/index.html), then moves it to output-dir. With output-dir: docs, rendered HTML goes directly to docs/ — the intermediate path never exists, causing a fatal rename error.
The correct approach for this repo is always: quarto render → deploy docs/ separately.
Bootstrap hash accumulation (historical)
Before the CI migration, docs/ was committed to main. Every custom.scss change regenerated a new hash-named bootstrap CSS file (bootstrap-<hash>.min.css). Old files accumulated as untracked git artifacts because Quarto doesn’t clean orphaned assets. This is fully resolved — docs/ is no longer tracked.
Quarto version
Pinned to 1.6.40 in CI (.github/workflows/publish.yml) to match local. Upgrade both together.