Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Changing the documentation

The documentation is an mdBook book built from the Markdown files under docs/. book.toml, at the repository root, configures it.

Where pages go

  • docs/user/ is the user guide, for people who run piqueld and deploy applications to it. Its pages say what piqueld does and how to use it, not how it is implemented.
  • docs/dev/ is the developer guide, for people who change piqueld: development setup, testing, architecture, and how to extend it.
  • docs/SUMMARY.md is the table of contents. A page it doesn’t list is not published, and a page it lists that doesn’t exist fails the build.
  • docs/openapi-v1.json, docs/application-manifest.schema.json and docs/piqueld-config.schema.json are generated by just generate; never edit them by hand. The book publishes them alongside its pages.
  • docs/user/reference/cli-commands.md, docs/user/reference/manifest-settings.md and docs/user/reference/configuration-settings.md are generated by just generate too. The first comes from piquelctl’s clap definitions, the others from the manifest types in crates/piqueld-core/src/manifest and the daemon’s configuration types in apps/piqueld/src/config, through their JSON Schemas. To change them, change the /// doc comments, which are also piquelctl --help and the schemas’ descriptions that editors show, keeping them about what the reader can see and do, then run just generate. Notes for developers go in // comments, which stay out of the schemas. The command reference’s layout and introduction are in apps/piquelctl/examples/cli_reference.rs, the settings references’ in apps/piqueld/examples/generate_openapi. just openapi-check, which CI runs, fails when a generated file is stale. .gitattributes marks every generated file so GitHub collapses it in pull request diffs; list a new one there too.

Images go in docs/images/; see screenshots.

Writing

  • Update the documentation in the same pull request as the change it describes.
  • Describe a feature through each of its surfaces: the dashboard, piquelctl, and the manifest. When a task can be done on more than one, show each way, in that order, and never present one as the only way. Keep each short: a subsection, or a sentence for a small change. If a surface can’t do it, say so.
  • Keep a page to one task or topic, and link to the reference rather than repeating it.
  • Describe how piqueld works now, not how it changed. Database migrations explain themselves in their SQL comments, and commit history records the rest.
  • Write placeholders in prose as `<name>` or \<name>. A bare <name> is an HTML tag: it hides the text, and just docs fails.

Style

Write so that someone new to piqueld can follow the page from top to bottom.

  • Start with the reader’s goal. Open each page with one or two sentences saying what it helps them do.
  • Keep sentences short, one idea per paragraph. A sentence that needs a parenthesis and a semicolon is two sentences.
  • Show, then explain. Put the command or manifest first, then say what it does and what the reader should see.
  • Number the steps of a procedure. Give each step one action.
  • Say where each command runs, on the host or on the reader’s machine, and keep the connection the same across a page’s examples.
  • Warn before a command that deletes data or can’t be undone, not after it.
  • Cover the main path first. Limits, edge cases and failure modes go at the end of the page, under Troubleshooting, or in the reference.
  • Leave internals out of the user guide. Explain what the reader can see and do; how the daemon does it belongs in the developer guide.
  • Address the reader as “you”, use the present tense, and write the labels of dashboard buttons and fields in bold, exactly as they appear.
  • Link a concept where it is first mentioned instead of explaining it again.

For example, rather than:

app apply saves configuration; app apply --deploy also creates a deployment and waits for its operation. Add --no-wait to return after acceptance.

write:

Save the manifest and deploy it:

piquelctl app apply --file notes.toml --deploy

The command waits until the deployment finishes. Without --deploy, it only saves the manifest.

The user guide’s feature guides share one outline:

# <Feature>

What it does and when to use it, in a sentence or two.

## Before you start

What the reader needs first: permissions, other features, external accounts.

## <Task>

Numbered steps, through the dashboard, `piquelctl`, and the manifest. Give
each task its own section, named after what the reader does, such as
"Deploy every push".

## Check that it works

## Troubleshooting

Reference pages list every setting instead, each with what it does and its default. The generated ones leave examples to the guides and the pages they link to, such as examples/piqueld.toml.

Screenshots

Show the dashboard where it helps the reader find their way, such as the first time a guide uses a page, and each meaningful step of a procedure done in the dashboard.

Screenshots are generated, never taken by hand, so they always match the dashboard. Regenerate them all after changing a page they show:

just setup-playwright   # once
just docs-screenshots

The recipe runs the specs in tests/playwright/screenshots/ with the daemon of the browser tests, in a mode where it deploys to an in-memory Docker engine: deployments succeed, services report healthy, and commands run in them exit with 0. Each spec seeds example data the way its guide does, then saves each page into docs/images/<section>/. The daemon runs no ingress gateway, so screenshots show HTTPS ingress as disabled, as on a daemon with the default configuration. It shows webhook URLs on hooks.example.com, as the guides configure it, but nothing listens there.

Each image records a fingerprint of the page it shows: its content and styles, not its pixels, which vary slightly from run to run. The recipe shoots a page again only when its fingerprint changed, so a run that changes nothing leaves the images untouched. CI runs it with --update-snapshots=none, and fails when an image shows an older version of its page:

just docs-screenshots --update-snapshots=none

To add a screenshot, extend the spec of its guide, or add a spec for a new guide. screenshots/docs.ts holds the helpers:

  • one helper per page or state, such as overview, which waits for its data to settle. Add one for each new page you show.
  • helpers for the dashboard steps the guides take, such as createApplication, so a spec seeds its data in the dashboard where the guide shows it.
  • manifest, which reads a TOML block of a guide, and Piquelctl, which applies it and runs the guide’s other commands.
  • GitHost, whose repositories the daemon reads at the URLs the guides use, such as https://github.com/example/blog.git. Its commits get the same IDs on every run.
  • shoot(page, '<section>/<name>', through, from), which saves the page, 1280 pixels wide and cut just below the element through, as docs/images/<section>/<name>.png. With from, the image starts just above that element instead of at the top of the page. It first replaces IDs and digests with fixed ones, and moves every date by the same amount, the earliest to a fixed one, so the images don’t change from run to run.
await newApplication(page, 'hello');
await shoot(page, 'getting-started/new-application');
await createApplication(page, 'hello');
// …
await overview(page);
await shoot(page, 'getting-started/overview', page.getByRole('region', { name: 'Recent deployments' }));

Link each image with a relative path, and give it alt text that says what it shows, for readers who can’t see it:

![The dashboard's Overview: one healthy application and its succeeded deployment](../../images/getting-started/overview.png)
  • Link to another page with its path relative to the current page. From a page in docs/user/operations/, for example, the manifest’s routes are [routes](../reference/manifest.md#routes). These links work both on GitHub and in the book.
  • Link to a repository file outside docs/ with its GitHub URL on main, such as https://github.com/sourceorigin-dev/piqueld/blob/main/examples/piqueld.toml (tree instead of blob for a directory). A relative path would break in the book. The link check resolves these URLs against your checkout, so the file must exist on your branch, and fails links to any other branch or commit.
  • A heading’s anchor is its text in lower case, with spaces replaced by hyphens and punctuation removed. Renaming a heading breaks the links to it; the link check finds them.

Building and checking

nix develop provides mdBook and lychee at the versions flake.lock pins. Without Nix, install them with cargo install --locked mdbook lychee.

just docs-serve   # serves the book on localhost:3000, rebuilding on every change
just docs         # builds the book into target/book and checks it

just docs fails on any mdBook warning, then checks with lychee every link and heading anchor in the built book and in the repository’s other Markdown files, such as README.md. It works offline, so it doesn’t check links to other websites; CI would otherwise fail whenever one of them is down.

The docs CI job runs just docs on every pull request, drafts included, because a change anywhere in the repository can break a link to it. It uses nix develop .#docs, so CI and your shell run the same versions.

Every push to main publishes the book at https://docs.piqueld.dev; see publishing piqueld.dev. To read a branch’s book as it would be published, deploy it to a preview.