# ADR-0055: `curl | sh` install script (`scripts/install.sh`) ## Status Accepted — **implemented 2026-06-17** (plan: `docs/plans/20260616-public-availability.md`, step 2). Step 2 on the road to public availability, building on ADR-0054 (versioned releases) and ADR-ci-001/003 (the Gitea releases it downloads from). Tracked by the plan + this ADR (no Gitea issue — user decision, 2026-06-17). ## Context Until now, installing meant: find the releases page, work out which of the six assets matches your machine, download it, `chmod +x`, move it onto `PATH`, and (on macOS) wonder about Gatekeeper. That is too much friction for a teaching tool aimed at beginners. The Gitea releases are **publicly downloadable** (confirmed), with deterministic asset names (`rdbms-playground--[.exe]`) and `.sha256` sidecars (ADR-ci-003), and a `releases/latest` API — enough to script a one-liner install. ## Decision Ship **`scripts/install.sh`**, run as `curl -fsSL /scripts/install.sh | sh`: - **POSIX `sh`** (no bashisms) — it runs under the `sh` of `curl | sh`; kept **shellcheck-clean** (`-s sh`). - **Platform detection** from `uname` → target triple: Linux → `-unknown-linux-musl` (the fully-static build — one universal Linux artifact, no glibc/version coupling), macOS → `-apple-darwin`; `x86_64`/`amd64` and `aarch64`/`arm64` both map. **Windows is rejected** with a pointer to Scoop/winget/the releases page (the binary is a `.exe`, not a `curl|sh` target). - **Version:** the `releases/latest` API tag by default; `RDBMS_VERSION` pins a specific tag. - **Integrity:** always download the `.sha256` sidecar and **verify** (`sha256sum`/`shasum -a 256`); a mismatch aborts the install. HTTPS only. - **Install location:** `~/.local/bin` by default (user-writable, no sudo), overridable via `RDBMS_INSTALL_DIR`; prints a PATH hint if the dir isn't on `PATH`. - **macOS note:** a `curl` download is **not** Gatekeeper-quarantined, so the binary runs as-is even while it is only ad-hoc-signed; proper Developer-ID signing + notarization (for *browser* downloads) is a separate, postponed task (see the plan's signing item). - **Testing seams:** `RDBMS_OS`/`RDBMS_ARCH` force detection and `--print-target` prints the resolved triple and exits — so the mapping is checkable without a download. ### Rejected / deferred - **Hosting the script on the website domain** (Cloudflare): nicer URL, but adds a moving part; the **Gitea repo raw URL** is simplest and the binaries live there anyway (user decision). The website may later *reference* the same command. - **`install.ps1` (Windows):** deferred — Windows users go via Scoop / winget (D3, §3). - **Uploading `install.sh` as a release asset** for a stable link: optional; the branch raw URL is fine for now. ## Consequences - A first-time user runs one line and gets a checksum-verified binary on `PATH`. The website's install copy (website branch, separate agent) can point at this command. - **Verified end-to-end** (2026-06-17) against the live public `v0.1.0`: all four Linux/macOS platform mappings + Windows/unknown-arch rejection; pinned and latest paths; checksum verification incl. a tamper-rejection check; install + run on Linux x86_64. (The installed `v0.1.0` predates `--version`, ADR-0054 — a non-issue, and the reason to cut a new release.) - **No automated regression guard in CI yet:** shellcheck isn't in the flake, and there's no shell-test harness here (no bats). Recommended follow-up: add a `shellcheck scripts/*.sh` gate (touches ADR-ci-002 — needs shellcheck in the devShell). For now the guard is local shellcheck + the documented end-to-end verification.