Update Documentation
How to publish documentation changes to https://docs.eblu.me.
Quick Release
After merging documentation changes to main:
- Go to Actions > Build BlumeOps > Run workflow
- Select version bump type (patch/minor/major) or enter a specific version
- The workflow builds, releases, and deploys automatically
Direct link: https://forge.ops.eblu.me/eblume/blumeops/actions?workflow=build-blumeops.yaml
What the Workflow Does
The build-blumeops workflow (.forgejo/workflows/build-blumeops.yaml):
- Resolves version — Uses input or auto-increments from latest release
- Builds changelog — Runs towncrier on the runner to update
CHANGELOG.md - Builds docs — Calls
dagger call build-docs(Quartz build in a container) - Creates release — Uploads
docs-<version>.tar.gzto Forgejo releases - Updates deployment — Edits
argocd/manifests/docs/deployment.yamlwith new URL - Commits changes — Pushes changelog and deployment updates to main
- Deploys — Syncs the
docsArgoCD app - Purges cache — Clears the nginx cache on the flyio-proxy so the new docs are served immediately
Changelog Fragments (Towncrier)
When making changes, add a changelog fragment to docs/changelog.d/:
# Format: <identifier>.<type>.md
# Types: feature, bugfix, infra, doc, ai, misc
# Using branch name (preferred)
echo "Add new feature X" > docs/changelog.d/my-feature.feature.md
# Orphan fragment (when no branch fits)
echo "Fix bug Y" > docs/changelog.d/+fix-bug.bugfix.mdFragments are automatically collected into CHANGELOG.md (at repo root) during release.
Fragment types:
| Type | Description |
|---|---|
feature | New features |
bugfix | Bug fixes |
infra | Infrastructure changes |
doc | Documentation updates |
ai | AI assistance changes |
misc | Other changes |
Runner Environment
The workflow runs on the k8s label, which uses the forgejo-runner in Kubernetes:
- Runner deployment:
argocd/manifests/forgejo-runner/ - Job image:
registry.ops.eblu.me/blumeops/runner-job-image(commit-SHA tagged) - Build engine: dagger CLI installed at runtime; Node.js and Python run inside Dagger containers
The job image is built from containers/forgejo-runner/Dockerfile.
Quartz Static Site Generator
Quartz builds the documentation into a static site with:
- Wiki-link support (
[[page]]syntax) - Backlinks panel showing what references each page
- Graph view of document connections
- Full-text search
Configuration files (in docs/):
quartz.config.ts- Site metadata, plugins, themequartz.layout.ts- Page layout components
Quartz is cloned fresh during each build (not vendored) to use the latest version.
Manual Build (Local)
To test docs locally without triggering a release:
# Build docs tarball (identical to CI)
dagger call build-docs --src=. --version=dev export --path=./docs-dev.tar.gz
# Inspect the output
tar tf docs-dev.tar.gz | head -20
# Debug a Quartz build failure interactively
dagger call --interactive build-docs --src=. --version=devTroubleshooting
Workflow fails on “Resolve version”:
- Check if the version already exists as a release
- Ensure version format is
vX.Y.Z
Docs not updating after deploy:
- Check ArgoCD sync status:
argocd app get docs - Verify the pod restarted:
kubectl --context=minikube-indri -n docs get pods - Check pod logs for download errors
Towncrier not finding fragments:
- Fragments must be in
docs/changelog.d/ - Must have
.mdextension - Must match pattern
<name>.<type>.md