docs: plan the road to public availability (versioning, install, packaging)
This commit is contained in:
@@ -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 (3a–3d)
|
||||
- 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.
|
||||
Reference in New Issue
Block a user