Files
paperspec/deploy
alexmandClaude 607062056f feat!: pin Python 3.14 and Unicode 16.0, and make the tools commands
Python and Unicode
- requires-python is >=3.14,<3.15: 3.14 is the only Python with the
  Unicode 16.0 data the specification pins (3.13 has 15.1, 3.15 has 17.0).
- `import paperspec` raises ImportError unless unicodedata reports
  paperspec.UNICODE_VERSION (16.0.0), so a source checkout or an install
  that bypasses requires-python cannot compute values on other data.

Commands
- tools/{check,build,validate,load,stress,site}.py move with history to
  src/paperspec/cli/ and install as paperspec-check, -build, -validate,
  -load, -stress and -site; each also runs as `python -m paperspec.cli.X`.
- paperspec.cli.require() exits with "install paperspec[tools]" when
  cryptography or jsonschema is missing; paperspec.cli.checkout() finds
  the repository the check, build, stress and site commands work on (the
  editable install's own checkout, else the one around the current
  folder) and exits with a message outside one. tools/__init__.py is gone.
- validate and load read the schemas and SQL through the new
  paperspec.resources.path(), which finds them in a wheel and in an
  editable install alike, so they work anywhere the package is installed.
- check runs the rebuild as `python -m paperspec.cli.build`.
- build still writes the provenance tool label "paperspec tools/build.py":
  it is part of every hashed and signed fixture.
- pixi tasks and the check workflow run the commands; tools/README.md
  documents them, and the other docs name the commands instead of paths.

License
- LICENSE.md gives `src/` Apache-2.0 alongside `tools/`. Since the
  previous commit moved the code to src/, no row had covered it.

pixi run check passes (run as `python -m paperspec.cli.check` with src/ on
the path, since this environment cannot install the entry points); the
byte-for-byte rebuild matches, so no fixture or vector changed.
pixi.lock still needs `pixi lock`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 09:17:27 -04:00
..
2026-10-15 05:06:20 -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: paperspec-site 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 site           # writes _site/
pixi run site --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/www/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 runs on every push to main. It installs the environment from pixi.lock, runs pixi run quick, builds the site, and copies it with rsync to /srv/www/paperspec, the folder Caddy serves. A failed check stops the publish, so the site never serves a release that does not pass its own checks.

The copy is local: the linux-base runner starts each job in a container with the host's /srv/www mounted at the same path, so no key or secret is involved. On a runner without that mount the workflow still builds and checks the site, and says that it did not publish. SITE_ROOT and SITE_SLUG at the top of the workflow name the folder.

Only changed files are copied, so every other file keeps its Last-Modified and ETag and caches stay valid across releases. The environment in .pixi/envs is cached between runs under the hash of pixi.lock, so a fresh container installs it only when the lock file changes.

Distributing packages

A zipped package is an ordinary file, and the site serves the fixtures as such. For a team's own packages, the Gitea instance speaks the OCI distribution protocol, so packages can be pushed to and pulled from its package registry as OCI artifacts with ORAS, and signed there with cosign; the media type of the artifact is the package's, application/vnd.scienting.doc+zip. Nothing in the formats depends on how packages travel.