142 lines
7.1 KiB
Markdown
142 lines
7.1 KiB
Markdown
# 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.
|