Quartz 4 fork- en deploy-gotchas

Definitie

Wie Quartz 4 als basis voor een eigen wiki gebruikt erft een aantal configuratie-keuzes van upstream die pas zichtbaar worden als je gaat builden, forken of deployen. Dit artikel verzamelt de niet-triviale valkuilen die bij het opzetten van kennisbank-web naar voren kwamen: ignorePatterns die niet doet wat je denkt, upstream CI die stil blijft in elke fork, en het content/git-contract dat nodig is voor Cloudflare Pages zonder DB-toegang.

Context

Tijdens een volledige code-QA op kennisbank-web (Quartz 4 fork met eigen theme, components en een sync-vault.ts script dat de Vault MCP database uitleest) bleken drie gotchas die upstream niet expliciet documenteert en die elk hun eigen klasse van bugs veroorzaken: een privacy-leak door verkeerd gelezen globs, vier CI-workflows die op elke fork passief blijven, en een deploy-workflow die alleen werkt als je begrijpt wat er wel en niet in CI beschikbaar is.

Kernpunten

ignorePatterns is een globby ignore, geen bare directory-lijst

In quartz.config.ts accepteert configuration.ignorePatterns een array strings die onder de motorkap aan globby wordt doorgegeven als ignore. Dat betekent: het zijn glob-patterns, geen directory-namen. Een bare string "_vault-cache" matcht alleen een bestand met exact die naam op de root van content/, niet de hele directory. Zet je er een hele map metadata in, dan wordt die bij elke build klakkeloos door de Assets-emitter naar public/ gekopieerd.

De robuuste fix is "**/_vault-cache/**". Hetzelfde geldt voor andere directories die eigenlijk nooit publiek mogen zijn:

ignorePatterns: ["private", "templates", ".obsidian", ".git", "**/_vault-cache/**"],

De eerste vier werken in de praktijk toevallig alleen omdat Quartz upstream ze ook via .gitignore-style logica behandelt en omdat ze bovenaan content/ staan. Voor veiligheid: gebruik altijd de glob-vorm. Je ziet het verschil pas als er daadwerkelijk files in public/ belanden die er niet horen, en dan is de data-exposure al een feit.

Upstream CI-workflows draaien nooit in jouw fork

De vier standaard workflows in een verse Quartz-clone (ci.yaml, build-preview.yaml, deploy-preview.yaml, docker-build-push.yaml) hebben allemaal deze guard:

jobs:
  build:
    if: github.repository == 'jackyzha0/quartz'

In elke fork is github.repository iets anders, dus de job wordt geskipt. Het gevolg is subtiel: de workflows lijken actief want ze staan in .github/workflows/, maar ze runnen nooit iets. Je krijgt geen CI-feedback op PRs, geen preview-builds, geen Docker-image. Tegelijk staan er wel secrets.CLOUDFLARE_* en secrets.DOCKER_* references in die werk lijken te vereisen.

Welke workflows dit raakt (stand upstream april 2026): build-preview.yaml, ci.yaml, deploy-preview.yaml, docker-build-push.yaml, release.yaml. Allen hebben dezelfde guard of een variant erop.

Snelle check direct na fork:

grep -r "github.repository ==" .github/workflows/

Daarna kiezen:

  • Weggooien als je hem niet gebruikt. Minder ruis in de repo, minder misleiding over wat er draait.
  • Guard weghalen en secrets toevoegen als je hem wel wil gebruiken.

Voor een private wiki-fork: vrijwel alles weggooien en zelf 1 deploy.yml schrijven. Bijkomende hygiene: package.json naam hernoemen van @jackyzha0/quartz naar eigen naam, en Dockerfile-oorsprong controleren (upstream is root-based).

Niet tussenin laten hangen.

Deploy-contract voor Cloudflare Pages zonder DB in CI

Een minimale Cloudflare Pages deploy-workflow voor een Quartz-fork ziet er zo uit:

name: Deploy to Cloudflare Pages
on:
  push:
    branches: [main]
  workflow_dispatch:
 
jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      deployments: write
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "22"
          cache: "npm"
      - run: npm ci
      - run: npx quartz build
      - uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          command: pages deploy public --project-name=kennisbank

Let op het contract dat hieronder hangt:

  • sync-vault.ts draait niet in CI. De Vault MCP SQLite database staat alleen lokaal op Jims Mac, niet in de GitHub Action runner. De workflow doet alleen npx quartz build, geen sync-vault. Dus moet je lokaal npx tsx scripts/sync-vault.ts draaien voor elke push, en gegenereerde output meecommitten: content/vault/thumbnails/, content/media/ en content/_vault-cache/. Dit gaat tegen de gebruikelijke “gegenereerde bestanden niet in git” wijsheid in, maar is een bewuste keuze voor een build-pipeline zonder runtime DB-toegang.
  • Branch conventie. De workflow triggert op push: branches: [main]. Upstream Quartz draait op branch v4. Als je een Quartz-fork in gebruik neemt, hernoem v4 naar main (of pas de trigger aan) voordat je de eerste push doet, anders gebeurt er niks. git branch -m v4 main en git push -u jim main:main.
  • Cloudflare secrets CLOUDFLARE_API_TOKEN en CLOUDFLARE_ACCOUNT_ID moeten in de fork staan, niet in upstream. gh secret set -R Jvdbreemen/kennisbank-web.
  • Pages project moet van tevoren bestaan (naam matcht --project-name). Eenmalig via dashboard of wrangler pages project create.

kennisbank-web gebruikt een content/ symlink naar ~/KennisBank/02-wiki. Dat is handig voor content, maar het betekent ook dat een script dat naar content/_vault-cache/ schrijft in werkelijkheid in de vault zelf schrijft. Obsidian toont die bestanden, een vault-commit pakt ze mee, en als de vault-repo ooit publiek wordt is de lek compleet.

Minimale bescherming is toevoegen aan de vault .gitignore:

_vault-cache/
02-wiki/_vault-cache/

De permanente oplossing is een cache-dir buiten de symlink (bijvoorbeeld .vault-cache/ in de kennisbank-web root). Dat raakt alle code die naar die dir leest of schrijft: sync-vault.ts, de VaultEmbed transformer en de VaultProjectMedia component. Zie wiki-quartz-4-custom-extensies voor hoe die componenten en transformers aan elkaar hangen.

Verbanden

Bronnen

Sessie-herkomst