aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authoruser <user@clank>2026-08-12 23:12:23 +0200
committeruser <user@clank>2026-08-12 23:12:23 +0200
commit4e647e2173a9817a2250666f8298b3b05d13ece5 (patch)
treedfef7492f7c64745961e55a45268faa8bda4515b /docs
parentbuild: ship the sl0ppi CLI in the tarball (diff)
downloadsl0ppi-4e647e2173a9817a2250666f8298b3b05d13ece5.tar.gz
sl0ppi-4e647e2173a9817a2250666f8298b3b05d13ece5.tar.xz
sl0ppi-4e647e2173a9817a2250666f8298b3b05d13ece5.zip
release: publish sl0ppi.sl0p.foo, and a script to keep it current
Phase 5, settled as build scripts rather than CI: make release tests, then a fresh static-musl tarball make publish render the site, upload, and verify against the live URL publish.sh is deliberately dumb -- rsync, then ask the live site whether it agrees (status codes plus a re-downloaded checksum) -- but it has two guard rails that matter: - it refuses to republish a version whose bytes differ from what is already live. /releases/ is cached for a year, so the same URL serving two different tarballs would be undebuggable. Bump VERSION instead. - artifacts upload before latest.json, so the pointer never names a file that is not downloadable yet. site/install.sh is POSIX sh and short on purpose, because people are being asked to pipe it into a shell. It reads latest.json, downloads the versioned artifact, VERIFIES ITS SHA256, and only then unpacks and runs the bundled installer. Refusal was tested for real by serving a doctored latest.json: it stops with a checksum mismatch and installs nothing. Verified end to end from the public URL, in a throwaway HOME with node, npm, bun, cargo and rustc replaced by poison stubs: curl -fsSL https://sl0ppi.sl0p.foo/install.sh | sh sl0ppij --version -> 0.45.0+sl0p1 pi --version -> 0.84.1 sl0ppi doctor -> all good The vhost itself is committed in the sl0pday repo, where that box's nginx config lives.
Diffstat (limited to 'docs')
-rw-r--r--docs/roadmap.md28
1 files changed, 24 insertions, 4 deletions
diff --git a/docs/roadmap.md b/docs/roadmap.md
index 0c251b9..fc9b47b 100644
--- a/docs/roadmap.md
+++ b/docs/roadmap.md
@@ -99,11 +99,31 @@ MVP is complete: discovery + idempotent tab diff, `up`/`ls`/`open`/`close`,
Deferred: `agent --resume` (needs the pir port off python3), fuzzy picker for
tab overflow, root order file, per-project eager.
-## Phase 5 — CI and distribution
+## Phase 5 — distribution ✅ (scripts, not CI)
-Deliberately last. `git.sl0p.foo` is a bare remote with no CI. When the rest
-works: a build host, a published tarball + checksum, and a one-liner installer
-URL.
+Live at **https://sl0ppi.sl0p.foo**.
+
+- `make release` — tests, then a fresh tarball
+- `make publish` — renders the site, uploads artifact + pointers, then asks the
+ live site whether it agrees (status codes plus a re-downloaded checksum)
+- `curl -fsSL https://sl0ppi.sl0p.foo/install.sh | sh` — verifies sha256 before
+ unpacking, and refuses to install anything on mismatch (tested by pointing it
+ at a doctored latest.json)
+
+The vhost lives in the sl0pday repo (`nginx/sl0p.conf`), because that is where
+that box's nginx config is deployed from. It is static-only: no app, no build on
+the box.
+
+Deliberately still not CI. A build host and a pipeline are worth it once there
+is more than one target to build, and the publish path is scripted either way.
+
+Guard rails worth knowing:
+
+- `publish.sh` refuses to overwrite an already-published version whose bytes
+ differ. `/releases/` is cached for a year, so republishing changed bytes under
+ one name would serve two different things to two people. Bump `VERSION`.
+- artifacts upload before pointers, so `latest.json` never names a file that is
+ not downloadable yet.
---