Files
rdbms-playground/docs/plans/20260616-public-availability.md
T
claude@clouddev1 ef99e6c676
ci / gate (push) Successful in 3m19s
website / deploy (push) Successful in 1m58s
feat(install): curl|sh installer script (ADR-0055)
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).
2026-06-17 19:41:34 +00:00

9.1 KiB
Raw Blame History

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) — 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 (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).
  • 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 (.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 taplazyeval/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

  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.
  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.)