Publish content to the repo’s static site. The site is built with Quartz v5, lives in garden/, and is generated from the repo’s own markdown and config files by garden/scripts/build-site-content.mjs, then deployed to GitHub Pages by .github/workflows/deploy.yml on every push to main.
⚠️ The site is PUBLIC
GitHub Pages is public even though this repo is private (project Pages without Enterprise can’t be restricted). Anything published is world-readable and Google-indexable. Before publishing new content, scan it for secrets (account IDs, emails, tokens, keys) and redact what must not leak — see the redaction step below. This is the cardinal rule: treat every addition as “about to be on the public internet.”
Mental model
repo source files build script (first-party) Quartz GitHub Pages
obsidian/ blueprints/ → garden/scripts/ → garden/ → public site
dotfiles/ vscode/ … build-site-content.mjs (build) (on git push)
writes garden/content/
Two things are separate:
- What appears on the site is decided by the build script’s mapping lists (
MAPPINGS,CODE_FILES,CODE_DIRS,DOWNLOADS). - Deployment is automatic — once pushed, every
git pushtomainre-runs the whole pipeline and redeploys. You never hand-build for production; you commit source files (and any script change).garden/content/andgarden/public/are generated and git-ignored — never commit them.
First decision: is it picked up automatically?
| What you’re adding | Automatic? | Action |
|---|---|---|
.md note, or image/PDF, inside obsidian/configs, obsidian/certifications, obsidian/studying, vscode/plugins/harp, .claude/skills, or anywhere under blueprints/ | ✅ Yes | Just add the file (recursive dir walk) |
.hcl under blueprints/01-terragrunt/ | ✅ Yes | Just add the file (walked by extension) |
A new dotfile (e.g. .zshrc) or any config you want shown as a code page | ⚙️ No | Add one line to CODE_FILES — see pipeline.md |
| A new top-level area (a source dir not already mapped) | ⚙️ No | Add one entry to MAPPINGS — see pipeline.md |
| A new binary to offer for download (e.g. a PDF book) | ⚙️ No | Add one entry to DOWNLOADS — see pipeline.md |
| A new file type that isn’t markdown / image / PDF / a known config | ⚙️ No | Extend the script — see pipeline.md |
Rule of thumb: anything inside an already-mapped directory is automatic. Only a new kind of content or a new top-level directory needs a one-line script edit.
Workflow A — automatic content (the common case)
For a new note/image/PDF in an already-mapped directory:
- Add the file to its source directory (e.g. write the note in
obsidian/configs/...). - Redact check (site is public) — scan the new file:
If a real secret must stay in the source, add agrep -nEi 'AKIA[0-9A-Z]{16}|-----BEGIN|[0-9]{12}|[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}|tskey-|ghp_|xox[baprs]-' <new-file>REDACTIONSentry (see pipeline.md). Account IDs123456789012/123456789012and the personal email are already redacted. - Preview locally (below) and confirm it renders.
- When ready, the source file is committed and pushed to
main(the user’s call — don’t auto-commit) → the Action rebuilds and redeploys.
Workflow B — needs a script edit
When the table above says ⚙️: open pipeline.md, edit the relevant list at the top of garden/scripts/build-site-content.mjs (one line, copy an existing entry), then run Workflow A from step 2. Remember to commit the changed script too.
Preview locally
The build script and Quartz are two steps — run the script first, then Quartz:
node garden/scripts/build-site-content.mjs # repo source → garden/content (with redactions)
npm --prefix garden run quartz -- build --serve # → http://localhost:8080
While the server runs it watches garden/content/ and hot-reloads. After editing a source file, just re-run node garden/scripts/build-site-content.mjs — Quartz picks up the regenerated content automatically. To stop the server: lsof -ti tcp:8080 | xargs -r kill.
Deploy
Deployment is the push itself — no manual build. Committing and pushing is the user’s decision; never auto-commit or auto-push. When the user pushes to main (or asks you to):
- First confirm the local preview looks right and the verify checklist passes.
- Stage the source files (and the script, if you edited it). Never commit
garden/contentorgarden/public. - The push to
maintriggers.github/workflows/deploy.yml, which regenerates content, builds, and publishes toconfigs.themaybe.ukin ~1–2 min. - (Optional) trigger a build without a content change from the repo’s Actions tab → “Deploy site to GitHub Pages” → Run workflow (
workflow_dispatch).
Example — add an AWS note, file to live URL
A new note in obsidian/configs/ is in a mapped directory, so it’s the fully-automatic path (no script edit):
# 1. Write the note (line-1 `tags:`, H2 sections — see the format-vault skill for house style)
# obsidian/configs/aws/cdn/CloudFront Signed URLs.md
# 2. Secret-scan it — the site is public
grep -nEi 'AKIA[0-9A-Z]{16}|-----BEGIN|[0-9]{12}|[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}|tskey-|ghp_' \
"obsidian/configs/aws/cdn/CloudFront Signed URLs.md"
# 3. Preview locally
node garden/scripts/build-site-content.mjs
npm --prefix garden run quartz -- build --serve
# → http://localhost:8080/configs/aws/cdn/cloudfront-signed-urls (slug is lower-kebab)
# 4. Publish — when ready, the SOURCE note is committed and pushed to main.
# Committing/pushing is the user's call (or done only when they ask) — never auto-run git.
# The push triggers the Action, which rebuilds and deploys; no manual build needed.Once it’s pushed, ~1–2 min later it’s live at
https://configs.themaybe.uk/configs/aws/cdn/cloudfront-signed-urls,
and any new tag auto-creates its /tags/<tag> page. Nothing else to register.
Verify before pushing
- New file renders in the local preview (Workflow A step 3).
- Secret scan clean, or the secret is covered by a
REDACTIONSentry — confirmgrep -r '<secret>' garden/publicreturns nothing. - Internal links/embeds resolve (Quartz marks unresolved wikilinks with class
broken—grep -rl 'internal broken' garden/publicshould be empty). - If you edited the script: it’s staged for commit alongside the source.
- Not committing generated dirs (
garden/content,garden/public).
Styling tweaks
Site-wide CSS overrides go in garden/quartz/styles/custom.scss (a committed file that survives CI). Do not edit anything under garden/.quartz/plugins/ — that directory is git-ignored and regenerated by quartz plugin install on every build, so edits there are lost. See pipeline.md for the build gotchas.
Reference
- pipeline.md — the build script’s config lists (with edit recipes), the transforms it applies, how redaction works, and the Quartz/build gotchas (gitignore + globby, the broken
install-pluginsnpm script, YAML config, custom.scss).