0091: The website lives in its own repository

On this page

Status: accepted. Reverses 0068.

Context

The website and its docs were built in this repository, as components and content beside the app (0068), so a change could update the app, its docs and its feature page in one pull request. The site has been rebuilt as its own Laravel project, ShortLeash/web, worked on by a web developer with their own tooling, deploys and checks. Keeping a copy of it here would mean two websites drifting apart, CI building one nobody serves, and a lockfile carrying its dependencies. Some of what the site shows is generated from this repository, though: the changelog, the third-party notices, the CLI reference, and the decision records.

Decision

  • This repository is the desktop app. apps/web is gone, with its Netlify configuration, checks, launch configuration and recipes. What's shared stays in packages/: the design tokens, icons and brand drawings the app uses.

  • ADRs and architecture docs stay here, in docs/adr/ and docs/architecture/, beside the code they explain. They're plain Markdown whose links work on GitHub: relative links between records, https://shortleash.dev/docs/<page> for user docs.

  • Each release publishes a feed. The release workflow uploads to R2 (downloads.shortleash.dev), under releases/vX.Y.Z/ and, with a 5-minute cache, latest/:

    • CHANGELOG.md and THIRD_PARTY_NOTICES.md, under the names the site's ReleaseFeed reads, with the changelog's ## [x.y.z] - YYYY-MM-DD headings;
    • checksums.json, each installer's SHA-256 and size;
    • cli.md, the CLI reference from the release's own built leash docs --markdown (so it's no longer committed, and nothing has to check it for drift);
    • docs/adr/*.md and docs/architecture/*.md, with docs/index.json listing each one's path, title and description (scripts/feed-docs.py), since R2 can't be listed over its public domain. latest/docs/ holds only the current release's files.

    The purge clears the latest/ feed files with the installers. The site reads the feed at request time, so a release needs no website deploy, and the Netlify build hook is gone.

  • User docs, feature pages and the privacy policy change in a companion pull request to ShortLeash/web, linked from this repository's pull request (its template asks), instead of in the same pull request. The rule that the privacy policy changes with anything that stores data or goes online stays; it now spans two pull requests.

  • Screenshots come from here, into the web repository. just screenshots captures the mocked UI into $WEB_REPO/public/screenshots, and just cli-docs writes the CLI reference into $WEB_REPO for docs written before a release.

  • The app's links are checked against the live site. CI's links job asks shortleash.dev for every https://shortleash.dev/… URL in apps/desktop (scripts/check-app-links.py), so a page the site moves or drops fails here.

Consequences

  • CI no longer builds a website, and the lockfile and notices lose its dependencies (Newsreader among them, which only the site used).
  • A change's docs can lag its code, or land first, across two repositories. The companion pull request line and the release feed narrow the gap. Each release publishes its CLI reference and records, so they match what shipped once the website reads them from the feed; until the website does, it shows the copies it keeps, which a person updates.
  • Between releases, the site's changelog, CLI reference and records show the last release, not main.
  • The site's own checks (links, accessibility, budgets) are the web repository's to run.
  • The canvas's website boards belong to the web repository; the app's boards stay with the app.