~ knotless Search/
↑↓ move↵ open⇧↵ all results

johnandersen777.bsky.social/knotless

git that lives in your Atmosphere account

Forked from chadtmiller.com/knotless

0
0
170 lines · 5.1 KB Raw History

Sites

A repository can have a website. You deploy a directory of files, such as a build's output, and knotless serves it at https://<owner>.knotless.page/<repo>/. The files are stored as blobs in your own account, in one record that each deploy replaces.

Pages explains how sites are stored and served, and the command reference lists every flag of knotless repo site.

Deploy a site

As the repository's owner, give knotless repo site the repository and the directory to deploy:

knotless repo site knotless://alice.example.com/blog dist

It uploads only the files the live site does not hold already, then replaces the site's record. It prints how many it uploaded and the address:

uploaded 3 of 41 files
https://alice-example-com.knotless.page/blog/

The new site is live within seconds. A visitor sees the old site or the new one, never a mix of the two.

The subdomain is your handle with each - doubled and each . turned into a -: alice.example.com is alice-example-com. It follows your handle, so it changes when your handle does.

A site holds 1 to 2,000 files.

Deploy a private site

A private repository's site is deployed the same way. It is kept in the repository's space, and only its members can read it. It is served at a host of its own, named by the repository's key and your plc id:

uploaded 3 of 41 files
https://3lbqz7ywmz22k-abcdefghijklmnopqrstuvwx.private.knotless.page/

The address stays the same when the repository is renamed. The site is served at the host's root, so build it with / as its base path.

A member who opens it is sent to knotless.dev to log in, if they are not already logged in, and comes back. Someone who is not a member gets a 404. A member you remove stops reading the site within a minute.

Build for the path

The site is served under /<repo>/, not at the root, so build it with that as its base path. In Vite, that is base:

// vite.config.js
export default { base: '/blog/' }

In SvelteKit it is kit.paths.base. A build with the wrong base loads its pages but not their scripts and styles.

Serve a single-page app

A single-page app routes in the browser, so every page has to load the app. Name the app's page as the fallback:

knotless repo site knotless://alice.example.com/app dist --fallback index.html

A request for a page that no file matches then gets index.html, with status 200, and the app's router takes the path from there. A request counts as one for a page when it accepts text/html, or when the last part of its path has no extension.

A file still comes first: /app/assets/main.js serves that file. A missing script or image gets a 404, not the app's HTML, so a broken build shows as one.

Add a 404 page

To answer a missing path with a page of your own, name it:

knotless repo site knotless://alice.example.com/blog dist --not-found 404.html

A path that no file matches gets that page with status 404. With a fallback too, pages get the fallback, and other files get the 404 page.

The fallback and the 404 page must each be one of the files you deploy.

Deploy on every push

The site shared step deploys from a workflow. It runs knotless repo site as the repository's owner, and installs knotless first if the image has none.

The step logs in with an app password of the owner's account. Make one at your PDS (on Bluesky, under Settings, Privacy and security, App passwords). Then give it to the runners as a secret, limited to the branch you deploy from:

printf %s "$APP_PASSWORD" | knotless secret knotless://alice.example.com/blog set SITE_PASSWORD --ref refs/heads/main

Then add a workflow that builds the site and deploys it, on a push to that branch only:

# .knotless/workflows/site.yml
on:
  push: {refs: [refs/heads/main]}
image: node:24
secrets: [SITE_PASSWORD]
steps:
  - name: build
    run: npm ci && npm run build
  - uses: chadtmiller.com/steps/site@1
    with: {dir: dist, fallback: index.html}
    secrets: [SITE_PASSWORD]

The step's inputs are dir, the directory to deploy, and optionally fallback, not-found, repo (this run's repository if not given) and appview. Pin it before you push, and commit the lock file:

knotless uses update
git add .knotless/uses.lock

Each deploy records the commit it was built from. Shared steps explains how uses works, and Workflows how to run a runner and give it secrets.

See what is live

With no directory, knotless repo site shows the live site: its address, how many files it holds, the commit it was built from, and when it was deployed:

knotless repo site knotless://alice.example.com/blog

The repository's page shows the site's address too, under its description. You don't need to add the address to the repository's links. A private repository's site is shown only to its members.

There is no history of deploys. To roll back, deploy an older commit's build again.

Take a site down

knotless repo site knotless://alice.example.com/blog --down

This deletes the site's record, and the site stops being served.