feat(install): curl|sh installer script (ADR-0055)
ci / gate (push) Successful in 3m19s
website / deploy (push) Successful in 1m58s

scripts/install.sh — POSIX sh, shellcheck-clean: detects uname OS/arch ->
target triple (Linux uses the static musl build; Windows rejected with a
Scoop/winget pointer), resolves the latest release (or RDBMS_VERSION),
downloads the asset + its .sha256 and verifies it, installs to
~/.local/bin with a PATH hint. RDBMS_OS/RDBMS_ARCH + --print-target are
testing seams. Verified end-to-end against the live public v0.1.0 (all
mappings, pinned + latest, checksum incl. tamper-rejection, install+run).

ADR-0055 + README index; plan-doc step 2 done + decisions recorded
(crates.io=yes, releases public, tracking via doc+ADR).
This commit is contained in:
claude@clouddev1
2026-06-17 19:41:34 +00:00
parent c30a6114b9
commit ef99e6c676
4 changed files with 305 additions and 28 deletions
+63 -28
View File
@@ -32,7 +32,20 @@ anything user-facing (taps, buckets).
---
## 2. `install.sh` (curl | sh) — DECIDED shape
## 2. `install.sh` (curl | sh) — DONE 2026-06-17 (ADR-0055)
**Shipped** `scripts/install.sh` (POSIX sh, shellcheck-clean). Verified
end-to-end against the live public `v0.1.0` release: platform mappings
(Linux/macOS × x86_64/aarch64; Windows + unknown arch error cleanly),
pinned (`RDBMS_VERSION`) and latest (`releases/latest`) paths, SHA-256
verification (incl. a tamper-rejection check), install to
`~/.local/bin`, PATH hint. **`install.ps1` (Windows) deferred** — Windows
users go via Scoop/winget (§3). The website copy that references the
`curl` command is the **website branch's** job (separate agent), later.
A **shellcheck CI gate** for `scripts/` is a recommended follow-up (not
added — shellcheck isn't in the flake yet; touches ADR-ci-002).
Original decided shape (for reference):
- **Hosted from the Gitea repo URL** on `git.lazyeval.net` (simplest):
`curl -fsSL https://git.lazyeval.net/oli/rdbms-playground/raw/branch/main/scripts/install.sh | sh`
@@ -72,11 +85,13 @@ per-release step to bump it. Ordered cheapest → most gatekept.
`cargo install cargo-binstall`). **Our instructions must say this.**
- Add `[package.metadata.binstall]` to `Cargo.toml` (pkg-url template →
our Gitea release assets; our naming already fits).
- **OPEN:** the frictionless `cargo binstall rdbms-playground` resolves
the crate via **crates.io**. Decision needed: **publish to crates.io?**
If not, document the `cargo binstall --git <gitea-url>` form instead.
*(Verify current cargo-binstall non-crates.io behaviour before
committing wording.)*
- **DECIDED (2026-06-17): publish to crates.io** — so the frictionless
`cargo binstall rdbms-playground` resolves the crate, and the project
is discoverable there. (A crates.io publish is its own small task:
metadata completeness — description/license/repository/keywords/readme
— and `cargo publish`; the `[package.metadata.binstall]` URL template
points binstall at our Gitea release assets.) *(Verify current
cargo-binstall behaviour when wiring.)*
### 3b. Scoop (Windows)
- A **bucket** repo under `lazyeval` on Gitea with a JSON manifest
@@ -113,29 +128,49 @@ per-release step to bump it. Ordered cheapest → most gatekept.
---
## Open decisions (need the user)
## Open decisions
1. **crates.io:** publish the crate? (changes the `cargo binstall` +
discoverability story).
2. **macOS signing — CONFIRMED BUG (2026-06-16).** `release-macos.yaml`
line 52 runs `codesign --force --sign -` (the `-` = **ad-hoc**), so a
downloaded binary is *not* properly signed — user-verified. The Apple
**Developer ID** identity was provisioned in the runner VM's keychain
(the CI agent asked for it) but the workflow never references it, so
it sits **unused**. Fix = a `release-macos.yaml` change: sign with
`codesign --sign "Developer ID Application: <Lazy Evaluation Ltd …>"`
against the keychain identity, **after** the `install_name_tool`
de-nix (which invalidates any signature), then ideally **notarize +
staple** (needs Apple notarytool creds — Apple ID + app-specific
password, or an App Store Connect API key — as runner secrets). A
distinct task from the version work; corrects the docs once landed.
3. **Issue tracking:** file Gitea issues for these (version; install.sh;
D3), or track via this plan + ADR only?
1. **crates.io:** **RESOLVED 2026-06-17 — yes, publish.** (See §3a.)
2. **Tracking:** **RESOLVED 2026-06-17 — doc + ADR only, no Gitea
issues.**
3. **Release downloads public:** **CONFIRMED 2026-06-17** — the Gitea
releases are publicly downloadable (no auth); `install.sh` relies on
it and was verified against the live `v0.1.0`.
### Still open / postponed
- **macOS signing — CONFIRMED BUG (2026-06-16), POSTPONED by the user
(2026-06-17)** pending the correct signing ID. Details:
- `release-macos.yaml` does `codesign --force --sign -` (ad-hoc) and has
**no signing scaffolding at all** (no keychain import, no secrets)
so a downloaded binary is *not* properly signed (user-verified).
- **The credential the user has is the wrong type:** `Apple Development:
Oliver Sturm (W687M898E4)` is a *development* cert (Gatekeeper won't
trust it for distribution). Distribution needs a **`Developer ID
Application`** cert (same format, different type). Signing under the
company name *"Lazy Evaluation Ltd"* would need an **Organization**
Apple Developer account; a personal account signs as "Oliver Sturm".
- **Notarization** (required with Developer ID for non-quarantined trust
on browser downloads): after signing, `xcrun notarytool submit`. Creds
= an **App Store Connect API key** (Issuer ID + Key ID + `.p8`,
recommended for CI) *or* Apple ID + app-specific password + Team ID.
A bare CLI binary can't be *stapled* (only bundles/dmg/pkg) — Gatekeeper
does an online check instead.
- **Urgency caveat:** the `curl|sh` path doesn't need any of this (curl
downloads aren't quarantined); signing matters for browser downloads
from the releases page. Fix when the right cert + creds exist; corrects
the ad-hoc docs once landed.
## Sequencing
1. **Version discipline** (ADR-0054) — `--version`/`-V` + `version`
command + CI tag-match guard + tests. **← building now.**
2. `scripts/install.sh` + confirm public download URLs.
3. Package managers, cheapest first: `cargo binstall` + Scoop → Homebrew
→ winget.
1. ✅ **Version discipline** (ADR-0054) — `--version`/`-V` + `version`
command + CI tag-match guard + tests.
2. ✅ **`scripts/install.sh`** (ADR-0055) — built + verified against the
live public release.
3. **← next:** package managers, cheapest first: `cargo binstall`
(+ crates.io publish) + Scoop → Homebrew (`lazyeval` tap) → winget
(komac / manual). Two `lazyeval` repos (tap + bucket) + CI push creds
to set up.
4. **Cut a release at a new version** — bump `Cargo.toml` (0.1.0 →
0.1.1/0.2.0; the ADR-0054 guard checks the tag), tag, push; the four
Linux/Windows targets build immediately. (macOS leg awaits signing.)