Add allod site preview to serve a site with the generator its build pins #180

Closed
opened 2026-09-09 21:52:05 +01:00 by vnprc-agent · 0 comments
Contributor

Let an author see a site change in a browser before publishing it, rendered by the same generator version the deploy build uses, with one command run from anywhere inside the site repository.

Primary goals:

  • One command, no setup — allod site preview starts a live-reloading local server for the site whose site.toml is found by walking up from the current directory, the way deploy already resolves the root. The author needs no generator on PATH and no knowledge of which nixpkgs the site pins.
  • Same generator as the build — the server is the site flake's own locked zola, started as nix shell --inputs-from <root> nixpkgs#zola --command zola serve .... What the author sees is rendered by the version allod site deploy will build with, and a channel bump in the site repository moves both together. A bare zola serve with whatever is on PATH would not have that property.
  • Available where sites are edited — sites are written on dev machines, which carry neither a hosting credential nor rclone. Preview must not be gated on the site build tag; that tag exists to keep the destructive deploy off exactly those machines.
  • Local links stay local — zola rewrites base_url to its listening address under serve, so navigating the preview never escapes to the live site. Preview never reads the rclone config, never runs the remote preflight, and takes no --config.
  • The rest passes through — --port, --interface, --base-url, --drafts and --open mirror zola's flags; anything after -- goes to zola verbatim. Default is zola's own: 127.0.0.1:1111.

Current state and specifics

The manual equivalent works today and is the whole implementation of the happy path: from a site repository, nix shell --inputs-from . nixpkgs#zola --command zola serve starts zola 0.21.0 on a site whose lock pins nixos-25.11, builds 23 pages, and rewrites every link to http://127.0.0.1:1111/.... Nobody discovers that command, and it is easy to run the wrong zola instead.

The site namespace is registered from init() in cmd/allod/site.go:243, in a file that begins //go:build site. An untagged build carries no site word at all (cmd/allod/main.go:37-64; README, "Optional namespaces"). A preview that lived only in the tagged build would exist only on the publishing host, which is the one machine nobody edits a site on. So this change splits the namespace: preview, findSiteRoot (cmd/allod/site.go:272) and the site.toml parser compile unconditionally, and the tagged file adds deploy, check and config to that same namespace. registerNamespace panics on a duplicate word (cmd/allod/main.go:60), so the tagged file extends the namespace rather than registering a second site. Usage text lists only the commands the binary carries: on a dev machine allod site shows preview alone, and allod site deploy there is an unknown command, which is true.

The generator is hardcoded to zola. The site derivation owns the choice of generator (the site repository's nix/site.nix) and preview cannot read it. When a second generator appears, the shape is a generator key in site.toml or a preview app the site flake exposes, not a guess in this command; site.toml ignores unknown keys today (cmd/allod/site.go:318), so adding one later is compatible. Until then, zola is the one value in use.

Preview binds loopback by default and a dev machine's firewall does not open it. Viewing from the host's browser is an SSH tunnel: ssh -L 1111:127.0.0.1:1111 <vm> and then http://127.0.0.1:1111. The usage text should say so, because that is where the first user will be stuck.

Validation: on an untagged build inside a site repository, allod site preview prints the URL and serves with live reload, allod site deploy is unknown, and allod site outside a site repository fails the way deploy does today (cmd/allod/site.go:289). On a -tags site build, allod site lists all four commands. Both go test ./... and go test -tags site ./... cover the namespace in both shapes, as the README already requires.

Scope

In: the preview command, the namespace split between tagged and untagged builds, usage text, tests, and the README's "Optional namespaces" section.

Out: generator abstraction (trigger: a second generator in a site repository); deployment package changes (dev machines already build cmd/allod untagged, so the command arrives with the next pin advance); and the hosting credential lifecycle, which is allod/tools#163 and allod/tools#164 (both closed) plus the deployment-side composition they left to each deployment.

Let an author see a site change in a browser before publishing it, rendered by the same generator version the deploy build uses, with one command run from anywhere inside the site repository. Primary goals: - **One command, no setup** — `allod site preview` starts a live-reloading local server for the site whose `site.toml` is found by walking up from the current directory, the way `deploy` already resolves the root. The author needs no generator on PATH and no knowledge of which nixpkgs the site pins. - **Same generator as the build** — the server is the site flake's own locked zola, started as `nix shell --inputs-from <root> nixpkgs#zola --command zola serve ...`. What the author sees is rendered by the version `allod site deploy` will build with, and a channel bump in the site repository moves both together. A bare `zola serve` with whatever is on PATH would not have that property. - **Available where sites are edited** — sites are written on dev machines, which carry neither a hosting credential nor rclone. Preview must not be gated on the `site` build tag; that tag exists to keep the destructive deploy off exactly those machines. - **Local links stay local** — zola rewrites `base_url` to its listening address under `serve`, so navigating the preview never escapes to the live site. Preview never reads the rclone config, never runs the remote preflight, and takes no `--config`. - **The rest passes through** — `--port`, `--interface`, `--base-url`, `--drafts` and `--open` mirror zola's flags; anything after `--` goes to zola verbatim. Default is zola's own: `127.0.0.1:1111`. ### Current state and specifics The manual equivalent works today and is the whole implementation of the happy path: from a site repository, `nix shell --inputs-from . nixpkgs#zola --command zola serve` starts zola 0.21.0 on a site whose lock pins nixos-25.11, builds 23 pages, and rewrites every link to `http://127.0.0.1:1111/...`. Nobody discovers that command, and it is easy to run the wrong zola instead. The `site` namespace is registered from `init()` in `cmd/allod/site.go:243`, in a file that begins `//go:build site`. An untagged build carries no `site` word at all (`cmd/allod/main.go:37-64`; README, "Optional namespaces"). A preview that lived only in the tagged build would exist only on the publishing host, which is the one machine nobody edits a site on. So this change splits the namespace: `preview`, `findSiteRoot` (`cmd/allod/site.go:272`) and the `site.toml` parser compile unconditionally, and the tagged file adds `deploy`, `check` and `config` to that same namespace. `registerNamespace` panics on a duplicate word (`cmd/allod/main.go:60`), so the tagged file extends the namespace rather than registering a second `site`. Usage text lists only the commands the binary carries: on a dev machine `allod site` shows `preview` alone, and `allod site deploy` there is an unknown command, which is true. The generator is hardcoded to zola. The site derivation owns the choice of generator (the site repository's `nix/site.nix`) and preview cannot read it. When a second generator appears, the shape is a `generator` key in `site.toml` or a `preview` app the site flake exposes, not a guess in this command; `site.toml` ignores unknown keys today (`cmd/allod/site.go:318`), so adding one later is compatible. Until then, zola is the one value in use. Preview binds loopback by default and a dev machine's firewall does not open it. Viewing from the host's browser is an SSH tunnel: `ssh -L 1111:127.0.0.1:1111 <vm>` and then `http://127.0.0.1:1111`. The usage text should say so, because that is where the first user will be stuck. Validation: on an untagged build inside a site repository, `allod site preview` prints the URL and serves with live reload, `allod site deploy` is unknown, and `allod site` outside a site repository fails the way `deploy` does today (`cmd/allod/site.go:289`). On a `-tags site` build, `allod site` lists all four commands. Both `go test ./...` and `go test -tags site ./...` cover the namespace in both shapes, as the README already requires. ### Scope In: the `preview` command, the namespace split between tagged and untagged builds, usage text, tests, and the README's "Optional namespaces" section. Out: generator abstraction (trigger: a second generator in a site repository); deployment package changes (dev machines already build `cmd/allod` untagged, so the command arrives with the next pin advance); and the hosting credential lifecycle, which is `allod/tools`#163 and `allod/tools`#164 (both closed) plus the deployment-side composition they left to each deployment.
vnprc closed this issue 2026-09-10 16:46:47 +01:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
allod/tools#180
No description provided.