Files
paperspec/deploy
alexmandClaude 76d76353d9 feat: rename to paperspec and add the website
- Rename manuspec to paperspec everywhere outside pixi.toml: prose, the
  tools, provenance tool names and the fixture key derivations, so every
  fixture and vector is rebuilt.
- Move the namespace addresses under the site, mirroring the repository:
  schema $id https://paperspec.scient.ing/schemas/<file>, the JSON-LD
  context https://paperspec.scient.ing/context/scienting-1.jsonld, and
  term IRIs https://paperspec.scient.ing/vocab#<term>. Format
  identifiers (scienting-*) and URNs (urn:scienting:) are unchanged.
- tools/site.py (standard library only) builds _site/: every file of the
  repository at its own path, each Markdown file rendered as a page with
  sidebar navigation, heading anchors matching the forge's, folder
  listings, a vocabulary page for the context's IRIs, a heading search
  and a 404 page; light and dark themes.
- check.py builds the site and checks that every Markdown file has a
  page, every internal link and fragment resolves, no Markdown is left
  unrendered, and every $id, the context address and the vocabulary IRIs
  are files of the site.
- deploy/: a Caddyfile with the media types and CORS the data needs, and
  a guide; .gitea/workflows/site.yml builds on main and publishes with
  rsync when the SITE_* secrets are set.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 21:27:21 -04:00
..

Deploying the website

This folder holds what it takes to serve the paperspec website at https://paperspec.scient.ing. The site is static: tools/site.py builds it into _site/, and any web server can serve that folder.

What the site serves

The site mirrors the repository, so a file at schemas/anchor.schema.json in the repository is served at https://paperspec.scient.ing/schemas/anchor.schema.json. Three addresses that the formats themselves name depend on that:

Address What is there
https://paperspec.scient.ing/schemas/<file> Each JSON Schema, at the address in its $id.
https://paperspec.scient.ing/context/scienting-1.jsonld The JSON-LD context every layer and annotation lists.
https://paperspec.scient.ing/vocab The vocabulary page, whose fragments are the IRIs of the context's terms.

Beside every Markdown file the builder writes a rendered page: README.md becomes its folder's index.html, and X.md becomes X.html. A folder without a README gets a listing page, so every fixture and vector can be browsed. The pages need no server-side code; search runs in the browser over a small index of headings, search.json.

Build it

pixi run python tools/site.py           # writes _site/
pixi run python tools/site.py --out /tmp/paperspec-site

pixi run check builds the site into a temporary folder and checks that every Markdown file has a page, that every internal link and fragment resolves, that no Markdown is left unrendered, and that each schema's $id, the context's address and the vocabulary's IRIs are files of the site.

To look at it locally, serve the folder with any static server, for example:

pixi run python -m http.server --directory _site 8000

Serve it with Caddy

Caddyfile serves /srv/paperspec at paperspec.scient.ing. It sets the media types the data needs (application/ld+json for the context, application/schema+json for schemas, application/jsonl for vectors and package files), allows every file to be fetched from any origin, and serves 404.html for missing paths. Add it to the server's Caddy configuration, for example with an import line, and reload Caddy.

Publish from CI

The workflow .gitea/workflows/site.yml builds the site on every push to main, and publishes it with rsync over SSH when four repository secrets are set:

Secret Holds
SITE_HOST The server's host name.
SITE_USER The account that owns the site folder.
SITE_PATH The folder Caddy serves, such as /srv/paperspec.
SITE_SSH_KEY A private SSH key whose public half is in that account's authorized_keys, and that can do nothing else.

Without SITE_HOST the workflow still builds and checks the site, and says that it did not publish.