docs: plan the road to public availability (versioning, install, packaging)

This commit is contained in:
claude@clouddev1
2026-06-16 15:57:48 +00:00
parent 628b250db6
commit fe9d58e037
+141
View File
@@ -0,0 +1,141 @@
# Plan — road to public availability (versioning + install + packaging)
Status: **planning** (2026-06-16). Captures the decisions taken in
discussion plus the open questions, so the work can proceed in steps.
The versioning piece is being implemented first and is recorded as a
decision in **ADR-0054**; the install-script and package-manager pieces
are roadmap items here until each is built.
Scope note: this repo lives on the self-hosted Gitea at
`git.lazyeval.net` (`oli/rdbms-playground`); releases publish there
(ADR-ci-001/003). Publication branding uses the company name **Lazy
Evaluation Ltd → `lazyeval`**, not the personal `oli` username, for
anything user-facing (taps, buckets).
---
## 1. Versioning + version surfaces — DECIDED (→ ADR-0054, building now)
- **`Cargo.toml` `version` is the single source of truth.** `--version`
reads `env!("CARGO_PKG_VERSION")` (compile-time, no deps).
- **Two surfaces:** a `--version` / `-V` CLI flag (prints + exits, like
`--help`), and an in-app **`version`** app command.
- **CI discipline:** `release.yaml` gains a guard that asserts the pushed
tag `vX.Y.Z` equals `CARGO_PKG_VERSION`, and **fails the release on
mismatch** — so the binary's self-reported version, the release name,
and the downloaded asset always agree.
- **Release ritual:** bump `Cargo.toml` → commit → tag `v<that number>`
→ push tag. (The guard enforces it.)
- Optional enrichment (not decided): a `build.rs` baking a git short-hash
+ build date so non-tagged dev builds read `0.2.0 (a1b2c3d)`. Good for
bug reports; can be added later.
---
## 2. `install.sh` (curl | sh) — DECIDED shape
- **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`
(exact raw-URL form to confirm against the Gitea version).
- **Behaviour:** POSIX `sh`; detect `uname` OS+arch → target triple
(Linux → the **musl static** build, our universal Linux artifact);
query the latest release via the Gitea API
(`/repos/oli/rdbms-playground/releases/latest`) → tag → deterministic
asset name `rdbms-playground-<tag>-<target>`; download + **verify the
`.sha256`**; install to `~/.local/bin` (fallback `/usr/local/bin` with
a sudo prompt); `chmod +x`; print a PATH hint if needed.
- **macOS:** binaries are signed (see §4 signing note); a `curl`
download does **not** apply the Gatekeeper quarantine xattr, so the
installed binary runs without `xattr` faff.
- **Windows:** not `curl | sh` — provide a PowerShell `install.ps1`
(`irm … | iex`) and/or steer to Scoop/winget (§3).
- **Security posture:** HTTPS only; in-script checksum verification;
document the download-inspect-run alternative (`curl|sh` is a trust
tradeoff).
- **Deliverables we own now:** `scripts/install.sh` (+ later
`install.ps1`); confirm releases are **publicly downloadable**; decide
whether to also upload `install.sh` as a release asset for a stable
link. Website copy referencing the command is the **website branch's**
job (separate agent), later.
---
## 3. D3 — package managers (roadmap; each layers on the release assets)
Common thread: a manifest pointing at our checksummed assets + a
per-release step to bump it. Ordered cheapest → most gatekept.
### 3a. `cargo binstall`
- **Bootstrapping matters (user-flagged):** `binstall` is **not** a
built-in cargo subcommand — users must install **`cargo-binstall`**
first (its own `curl|sh`/PowerShell installer, or
`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.)*
### 3b. Scoop (Windows)
- A **bucket** repo under `lazyeval` on Gitea with a JSON manifest
(`.exe` URL + hash + `autoupdate`). Release job commits the bump.
- Users: `scoop bucket add lazyeval <gitea-url>; scoop install rdbms-playground`.
### 3c. Homebrew (macOS/Linux)
- A **company-branded tap**`lazyeval/homebrew-tap` (on Gitea) — with a
Ruby formula (per-arch `url` + `sha256`). Release job commits the bump.
- Users: `brew tap lazyeval/tap https://git.lazyeval.net/lazyeval/homebrew-tap`
then `brew install lazyeval/tap/rdbms-playground` (the explicit-URL tap
form, since the `user/repo` shorthand assumes GitHub).
- *"Notability bars"* = the acceptance criteria for the default
**homebrew-core** tap (must be sufficiently popular/maintained). Our
own `lazyeval` tap sidesteps that entirely — no review gate.
### 3d. winget (Windows)
- Manifests are YAML PR'd to `microsoft/winget-pkgs` (reviewed by MS).
- **`wingetcreate` is Windows-only** (.NET) — no good without a Windows
runner. **Automatic path to evaluate first: `komac`** — a
cross-platform (Rust) winget manifest creator/submitter that runs on
our **Linux** CI. *(Verify komac's current capabilities/auth model.)*
- **Fallback:** a manual YAML PR per release — acceptable given releases
are infrequent (user-confirmed).
### Cross-cutting (3a3d)
- Two extra repos (tap + bucket) under `lazyeval`, with CI push
credentials — setup TBD (user: "we'll figure that out").
- **`cargo-dist`/"dist"** automates installers + Homebrew + CI, but is
**GitHub-Actions/Releases-centric**; on self-hosted Gitea it won't drop
in cleanly (installer-script generation might be reusable). Likely
hand-roll the manifests + a small "update on release" job instead.
*(Verify cargo-dist's current Gitea support before fully ruling out.)*
---
## Open decisions (need the user)
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?
## 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.