From 984bc30256b559003be5935ff720b74e62c473ad Mon Sep 17 00:00:00 2001 From: "claude@clouddev1" Date: Mon, 15 Jun 2026 16:31:58 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20record=20CI=20branch=20work=20=E2=80=94?= =?UTF-8?q?=20D1/D2=20done,=20TT5=20partial,=20handoff=2070?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit requirements.md: D1 (all six cross-platform binaries) and D2 (no-runtime- deps, per-platform) done; D3 noted (binaries shipped, package managers pending); TT5 partial (gate + macOS test live; Windows build-only; Tier-4 unwired). CLAUDE.md: add the CI/release decision (-> docs/ci/adr) + update the deferred list. Adds handoff 70 summarising the pipeline + follow-ups (incl. the versioning gap). --- CLAUDE.md | 27 +++++++- docs/handoff/20260615-handoff-70.md | 101 ++++++++++++++++++++++++++++ docs/requirements.md | 37 +++++++++- 3 files changed, 160 insertions(+), 5 deletions(-) create mode 100644 docs/handoff/20260615-handoff-70.md diff --git a/CLAUDE.md b/CLAUDE.md index bfd358d..483b89d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -108,6 +108,23 @@ Current decisions at a glance (each backed by an ADR): SQL `select` / `with` / `insert` / `update` / `delete` (ADR-0039). `EXPLAIN QUERY PLAN` never executes, so explaining a destructive command is safe. +- **Continuous integration & release** (built on the `ci` branch, + 2026-06-15; decisions in `docs/ci/adr/` — **ADR-ci-001/002/003**, + a namespace kept separate from the main ADR sequence to avoid + cross-branch number collisions, like the website's): a self-hosted + **Gitea Actions** pipeline built on a **nix flake** (pinned Rust + `1.95.0` — one source of toolchain for dev *and* CI) plus a + prebuilt CI image. **Gate** (`ci.yaml`): `clippy -D warnings` + + `cargo test` on every branch push / PR. **Release** on a `v*` tag + (`release.yaml`): the four non-macOS **D1** targets cross-built + with `cargo-zigbuild` (Linux musl static + standalone Windows + `.exe`); the two macOS targets via the **dispatched** + `release-macos.yaml` on a Tart Apple-Silicon runner (de-nix the + `libiconv` load path + ad-hoc re-sign). All published to a Gitea + release with `.sha256`s. **`fmt` is intentionally not gated yet** + (the tree isn't stock-`rustfmt`-clean). `workflow_dispatch` is + Gitea-default-branch-only, so `release-macos` is dispatchable once + this lands on `main`. ## Repository layout @@ -344,8 +361,14 @@ not yet implemented: Ctrl-Enter submits. - **Tab completion** (I3), **syntax highlighting** (I4). - **ER diagram export** (V3). -- **CI** (TT5): test infrastructure exists; CI workflow not - yet configured. +- **Full TT5** (CI): the pipeline is live (see the CI decision + above / `docs/ci/adr/`), but "all tiers on all OSes" isn't + complete — **Windows is build-only** (cross-compiled, not + executed: no Windows runner) and **Tier 4** (PTY, TT4) isn't + wired in CI. +- **D3 packaging**: prebuilt binaries + checksums ship to Gitea + releases, but the Homebrew / Scoop / winget / `cargo binstall` + manifests are not done. ## Handoff notes diff --git a/docs/handoff/20260615-handoff-70.md b/docs/handoff/20260615-handoff-70.md new file mode 100644 index 0000000..6bbd741 --- /dev/null +++ b/docs/handoff/20260615-handoff-70.md @@ -0,0 +1,101 @@ +# Session handoff — 2026-06-15 (70) + +Seventieth handover. A dedicated infrastructure session, run on a separate +**`ci`** branch (in a worktree), that built the project's **entire CI/CD +pipeline** on the self-hosted Gitea Actions runner — from nothing to a live +gate plus a six-target cross-platform release. Net: the **CI** / +`requirements.md` **TT5** item and **D1**/**D2** are now done; **D3** and a +couple of TT5 tails remain. Decisions are recorded in a new ADR namespace, +**`docs/ci/adr/`** (ADR-ci-001/002/003), kept separate from the main integer +ADR sequence to avoid cross-branch number collisions (the same split the +website branch uses — and it paid off: `main` independently took ADR-0049 this +period, which would have collided). + +## §1. State at handoff + +**Branch:** `ci` (worktree). **`main` has been merged into `ci`** (commit +`138e766`, clean — `ci` and `main` touched disjoint files) so the gate runs +against current `main` before CI lands there. Working tree clean except the +in-progress doc updates from this handoff. Pushes/promotion are the user's +step. + +**Gate verified locally on the merged code:** `clippy -D warnings` clean; +**`cargo test` 2488 passing / 0 failing / 1 ignored** (the long-standing +`friendly` doctest). main's features came in with their tests (2424 → 2488). + +**Pipeline (`.gitea/workflows/`):** + +- `build-ci-image.yaml` — builds + pushes the CI image (`node:22-bookworm-slim` + + single-user nix + the flake's devShell pre-warmed) to the Gitea registry. + Triggers only on image-input changes (Dockerfile / flake / toolchain). +- `ci.yaml` — the gate: `clippy -D warnings` + `cargo test`, branch pushes + PRs + (docs-only changes skipped). +- `release.yaml` — on a `v*` tag: `test` → `build` matrix over the **four + non-macOS** targets via `cargo-zigbuild`, upload to the Gitea release. +- `release-macos.yaml` — **workflow_dispatch** (tag input) on the Tart + Apple-Silicon runner (`runs-on: macos`): test → build both `*-apple-darwin` + → de-nix `libiconv` + ad-hoc re-sign → upload. + +**Verified live this session:** the 4-target release published **8 assets** +(binary + `.sha256` each) for tag `v.0.0.0-citest3`; the macOS build was proven +portable (system-only deps) + signed + launches on the runner. + +## §2. What was built (and the non-obvious bits) + +- **Nix flake** (ADR-ci-002, relocated from a would-be `main` ADR-0049): one + pinned toolchain (`1.95.0`) for dev *and* CI; `cargo-zigbuild` + `zig` (Linux + only) for the cross targets; `apple-sdk` on darwin. +- **Runner facts** (ADR-ci-001): jobs run *inside* a container (`ci-public` → + `catthehacker/ubuntu`), so host nix is unreachable — hence the baked image. + The Mac runner is **host execution**; its label is `macos` (`:host` in the + registration is the act_runner backend, not part of the label). +- **Cross-compile** (ADR-ci-003): `cargo-zigbuild` for the 4 non-macOS targets. + Windows needs an **empty `libsynchronization.a` stub** (`ci/winstub/`, wired + via `.cargo/config.toml`) — std links `-lsynchronization`, absent from + rust-overlay's toolchain + zig's mingw, but forwarded by `kernel32`. +- **macOS** (ADR-ci-003 amendment): built on **real Apple hardware** (Tart), so + the SDK is fully licensed — no osxcross grey area. The darwin stdenv bakes a + `/nix/store` `libiconv` path into the binary; the build rewrites it to + `/usr/lib/libiconv.2.dylib` (`install_name_tool`) and re-signs ad-hoc + (`codesign -f -s -`; `install_name_tool` invalidates the signature, arm64 + refuses unsigned). A guard fails the build on any remaining `/nix/store` dep. +- **Cache hygiene (Mac):** the runner wipes the workspace each run, so cargo + `target/` never accumulates; the persistent nix store is bounded by + **generation** (record the devShell in a persistent profile, keep the 2 + newest via `nix-env --delete-generations +2`, GC the rest). First sweep + reclaimed a ~3.8 GB one-time backlog of build scaffolding (source + build-only + deps, *not* re-installed toolchains). + +## §3. Immediate next steps (user) + +1. **Push `ci`** → the gate re-runs in CI (should be green; no image rebuild — + the merge didn't touch the flake/Dockerfile). +2. **Promote:** `git checkout main && git merge ci` — a **fast-forward** (`ci` + already contains `main`) — then push `main`. CI goes live; `release-macos` + becomes dispatchable (workflow_dispatch needs the default branch). +3. **First real release:** tag `v0.1.0` (auto-builds the 4 Linux/Windows + assets), then **dispatch `release-macos` for `v0.1.0`** with the Mac up (adds + the 2 macOS assets) → a full 6-binary release. +4. **Cleanup:** delete the `v.0.0.0-citest*` test tags + their releases. +5. **Runner-side:** add `min-free`/`max-free` to the Mac's `/etc/nix/nix.conf` + as a hands-off nix-store backstop. + +## §4. Known gaps / follow-ups + +- **Versioning is not wired into the binary** (flagged by the user). The release + **git tag is nowhere in the produced binary** — there is no `--version` flag, + no `CARGO_PKG_VERSION` use anywhere in `src/`, and the release workflows use + the tag only for the *release name* + *asset filenames* + (`rdbms-playground--`). `Cargo.toml` is a static `version = + "0.1.0"`, decoupled from the tag. So a `v0.5.0` tag yields a `…-v0.5.0-…` + asset whose binary knows nothing of "0.5.0". To fix later: add a `--version` + flag, and inject the tag at build time (e.g. a `build.rs` reading a + CI-provided env, or bumping `Cargo.toml` as part of tagging) so the binary and + the release agree. +- **D3 packaging** — Homebrew / Scoop / winget / `cargo binstall` manifests + (asset naming is already binstall-friendly). +- **TT5 tails** — Windows is build-only (no execution runner); Tier-4 PTY (TT4) + is unwired in CI. +- **`fmt` gate** — deliberately off (tree isn't stock-`rustfmt`-clean); revisit + on `main`. +- **Website → Cloudflare** deploy — the separate, simpler workflow, still to do. diff --git a/docs/requirements.md b/docs/requirements.md index d3fc046..eeb7c79 100644 --- a/docs/requirements.md +++ b/docs/requirements.md @@ -61,11 +61,32 @@ since ADR-0027.) ## Distribution and install -- [ ] **D1** Cross-platform binaries: Linux, macOS, Windows on +- [x] **D1** Cross-platform binaries: Linux, macOS, Windows on x86_64 and aarch64. -- [ ] **D2** Single static binary, no runtime dependencies. + *(Done 2026-06-15 — CI produces all six. The four non-macOS + targets (Linux musl + Windows gnu/gnullvm × x86_64/aarch64) are + cross-built from the Linux runner with `cargo-zigbuild` on a `v*` + tag (`release.yaml`); the two `*-apple-darwin` targets build + natively on a Tart Apple-Silicon runner via the dispatched + `release-macos.yaml`. All uploaded to the Gitea release with a + `.sha256` each. Decisions in `docs/ci/adr/` (ADR-ci-001/002/003). + Runtime-verified by the user: Linux x86_64 + Windows aarch64; the + others are link-clean / valid format.)* +- [x] **D2** Single static binary, no runtime dependencies. + *(Done 2026-06-15, per platform: **Linux** is fully static (musl + + `crt-static`); **Windows** is a standalone `.exe` (Zig statically + links libc — no mingw runtime DLLs); **macOS** links only system + libraries (`libSystem` + the AppKit/Foundation frameworks — + inherent on every Mac, never user-installed; the build rewrites the + one nix-store `libiconv` path to `/usr/lib` and re-signs ad-hoc). + No target requires anything the user must install. ADR-ci-003.)* - [ ] **D3** Released via prebuilt binaries plus Homebrew, Scoop, `winget`, and `cargo binstall`. + *(Prebuilt binaries + checksums now published to Gitea releases + (D1); the package-manager manifests (Homebrew / Scoop / winget / + `cargo binstall`) remain to do. The asset naming + `rdbms-playground--` is already binstall-friendly. + Tracked under ADR-ci-003 "Deferred".)* ## TUI shell @@ -878,8 +899,18 @@ since ADR-0027.) PTY. Correcting a stale `CLAUDE.md` line that read "Tier 4 is wired only for the listed critical flows" — it was not wired at all. Genuinely deferred.)* -- [ ] **TT5** CI runs all tiers on Linux, macOS, and Windows on +- [/] **TT5** CI runs all tiers on Linux, macOS, and Windows on stable Rust. + *(Partial, 2026-06-15. **CI is live** on the self-hosted Gitea + Actions (`docs/ci/adr/`): the gate runs `clippy -D warnings` + + `cargo test` (Tiers 1–3) on the **Linux** runner for every branch + push / PR, and `release-macos` runs the suite natively on the + **macOS** runner. **Windows is build-only** — cross-compiled, not + executed (no Windows runner). **Tier 4** (PTY, TT4) is still + unwired, so "all tiers" is not yet fully met. "Stable Rust" is + satisfied by the flake's pinned `1.95.0` (a stable release, not + nightly). Remaining for full TT5: a Windows execution runner and + Tier-4 PTY in CI.)* ## Cross-cutting