From 083af34ad36ed1fcbfbd6a6315ebe8dd4f4a81a0 Mon Sep 17 00:00:00 2001 From: Adam Basfop Cavendish Date: Tue, 15 Sep 2026 18:20:20 +0000 Subject: [PATCH] chore: prepare 0.0.1 crates.io release Set the crate and CLI version to 0.0.1, derive OpenAPI version metadata from Cargo and cover it with a contract assertion. Add crates.io package metadata and the initial changelog. Provide explicit Just publish and non-uploading dry-run recipes, verify crate packaging in CI and document the manual release process. Tags and the actual crates.io upload remain maintainer-controlled. --- .github/workflows/package.yml | 13 +++++++++ CHANGELOG.md | 53 +++++++++++++++++++++++++++++++++++ Cargo.lock | 2 +- Cargo.toml | 7 ++++- Justfile | 8 ++++++ README.md | 1 + docs/delivery.md | 38 +++++++++++++++++++++++-- examples/sdk/README.md | 4 +-- src/loader.rs | 2 +- tests/loading_contract.rs | 1 + 10 files changed, 122 insertions(+), 7 deletions(-) create mode 100644 CHANGELOG.md diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 30dee72..5d7edd7 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -6,6 +6,19 @@ permissions: contents: read jobs: + crate: + name: Crates.io dry run + runs-on: ubuntu-22.04 + timeout-minutes: 35 + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false + - uses: ./.github/actions/setup-rust + with: + cache-key: crate + - run: just publish-dry-run + release: name: Release binary # Keep the build compatible with the container's glibc 2.36. diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..fb91c83 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,53 @@ +# Changelog + +User-visible changes are recorded here. + +## Unreleased + +## 0.0.1 - 2026-09-15 + +### Added + +- Serve database-backed HTTP APIs from SQL files with explicitly typed parameters + and validated response schemas. Use SQLRest as a standalone process or embed + its Rust library. See [Getting started](docs/getting-started.md). +- Use local Turso databases or remote/shared PostgreSQL databases through the + same publication and request interfaces. +- Publish database configuration, forward migrations and SQL interfaces with + one operation. Persist configuration and recovery state in a fixed TOML-based + workspace so healthy databases recover after restart without registration + replay. Unregister without deleting database or source files. +- Execute requests transactionally, validating result columns, values and JSON + before commit. Enforce execution deadlines and maximum final rows with errors, + not silent truncation; enforce read-only GET and HEAD requests. +- Export OpenAPI 3.1 from the published interface snapshot, including + self-contained recursive response schemas, for client generation. +- Recover edited or missing migration files from saved original SQL history. + Poll publication/unregistration operations and inspect per-database status + through the management API. +- Keep public errors sanitized while retaining private driver diagnostics for + runtime operators; drain accepted work during graceful shutdown. +- Start from working [Todolist](examples/todolist/README.md) and + [Ledger](examples/ledger/README.md) examples for both backends, generated + TypeScript client examples, and a distributable + [Agent runtime skill](skills/sqlrest-runtime/SKILL.md). + +### Initial release boundaries + +- Linux is the verified delivery platform. Turso dependencies are pinned to + `0.8.0-pre.10`; PostgreSQL connections are currently explicitly unencrypted. +- Authentication, TLS termination and exposure protection belong to the Agent + runtime/deployer. Protect both HTTP listeners; SQL is trusted configuration, + not a sandbox. +- MySQL, down migrations, filesystem watchers and persistent operation queues + are not implemented. Operation history does not survive process restart. +- Large JSON integers are not automatically stringified for JavaScript clients. + Database backups remain the deployer's responsibility. + +### For contributors + +- Run local verification through the Justfile. CI runs quality, backend and SDK + checks in parallel, then requires every lane and container verification to + succeed through the aggregate `delivery` check. +- Generate SDKs with the pinned openapi-nexus release binary, without compiling + the generator from source. See [delivery verification](docs/delivery.md). diff --git a/Cargo.lock b/Cargo.lock index 220306a..5e14c38 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2709,7 +2709,7 @@ dependencies = [ [[package]] name = "sqlrest" -version = "0.1.0" +version = "0.0.1" dependencies = [ "aioduct", "axum", diff --git a/Cargo.toml b/Cargo.toml index 88db1bb..6cd89a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,15 @@ [package] name = "sqlrest" -version = "0.1.0" +version = "0.0.1" edition = "2024" rust-version = "1.98" license = "MIT OR Apache-2.0" description = "Typed SQL interfaces over HTTP" +repository = "https://github.com/rust-codegen-group/sqlrest" +readme = "README.md" +keywords = ["sql", "rest", "database", "agent", "turso"] +categories = ["database", "web-programming::http-server"] +publish = ["crates-io"] [dependencies] axum = "0.8" diff --git a/Justfile b/Justfile index 2f2593a..44a09ab 100644 --- a/Justfile +++ b/Justfile @@ -50,6 +50,14 @@ sdk-schema: release: cargo build --release --locked +# Verify the actual crate archive without uploading anything. +publish-dry-run: + cargo publish --locked --registry crates-io --dry-run + +# Upload the current crate to crates.io. Does not create or push Git tags. +publish: + cargo publish --locked --registry crates-io + # Package an existing release binary and exercise its container lifecycle. container: docker build --tag sqlrest:ci . diff --git a/README.md b/README.md index 9697088..2898188 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ do not expose the management port to users. No auth, TLS or CORS is installed. Includes restart, polling, history repair and checking behavior after publish. - [Container and verification](docs/delivery.md): pinned inputs, local image, complete test gates and CI. +- [Changelog](CHANGELOG.md): user-visible changes and release boundaries. ## Contracts diff --git a/docs/delivery.md b/docs/delivery.md index b8f9c23..ba1f59c 100644 --- a/docs/delivery.md +++ b/docs/delivery.md @@ -132,13 +132,14 @@ runs its lifecycle tests. These two remain separate from the default `all` group | `quality.yml` | Format, Clippy | Rust; native tools/cache only for Clippy | | `tests.yml` | Turso/default contracts, PostgreSQL contracts | PostgreSQL service only for its matrix entry | | `sdk.yml` | Turso SDK, PostgreSQL SDK, recursive schema | SDK tools; separate empty PostgreSQL service only for PG | -| `package.yml` | Release binary, then container lifecycle | Container downloads the binary built in the same run | +| `package.yml` | Crates.io dry run; release binary, then container lifecycle | Container downloads the binary built in the same run | The four workflows start independently. Database and SDK matrices use `fail-fast: false` so a failure does not cancel other diagnostic results. Composite actions in `.github/actions/` share Rust/native/cache setup and SDK tool installation. Rust comes from `rust-toolchain.toml`; Clippy, tests and release -use separate cache partitions. SDK jobs share the tests partition. +use separate cache partitions. SDK jobs share the tests partition; crate +verification has its own partition. The artifact is a candidate until the complete CI run succeeds; it is not a published release. @@ -151,6 +152,39 @@ push and pull-request runs for the same feature branch. No remote CI run or release is implied by checking in a workflow; local validation and hosted CI are distinct evidence. +## Publishing to crates.io + +`Cargo.toml` is the version source for the crate, CLI and exported OpenAPI. +Prepare a release PR updating its version, the root package in `Cargo.lock` +and `CHANGELOG.md`. Merge only after the complete `delivery` check passes, +including the crate dry run. + +From a clean checkout of that exact release commit, verify the crate archive: + +```sh +just publish-dry-run +``` + +This runs Cargo's packaging and build verification without uploading. It is +separate from the full backend/SDK tests and does not prove crates.io ownership +or token permissions. Authenticate with `cargo login --registry crates-io` or +provide `CARGO_REGISTRY_TOKEN` through your secret manager, then: + +```sh +just publish +``` + +This uploads the library and binary crate to crates.io. Cargo's clean-tree and +package-verification checks remain enabled. A published version cannot be +overwritten; inspect crates.io before retrying an upload with an uncertain result. +The maintainer creates and pushes the matching `v0.0.1` tag on the same commit. +Neither recipe creates tags, GitHub Releases or container releases, and CI never +uploads to crates.io automatically. + +After publication, consumers can install the CLI with +`cargo install sqlrest --version 0.0.1 --locked` or depend on +`sqlrest = "0.0.1"`. The native build prerequisites above still apply. + ## Embedding, backups and trust `Registry` and `http::Server` are public Rust entrypoints. Keep Tokio alive until diff --git a/examples/sdk/README.md b/examples/sdk/README.md index 6c3fa61..822e766 100644 --- a/examples/sdk/README.md +++ b/examples/sdk/README.md @@ -11,8 +11,8 @@ Verified inputs: - Node.js 24.15.0 and TypeScript 6.0.3 Download the pinned release binary, not the generator source. The shared CI/local -script downloads and extracts the Linux x86_64 musl archive. It requires Bash, -curl, tar and xz. Install TypeScript in a disposable tools directory or +Justfile recipe downloads and extracts the Linux x86_64 musl archive. It requires +Just 1.58.0, Bash, curl, tar and xz. Install TypeScript in a disposable tools directory or use an existing matching installation; put its `tsc` on PATH. ```sh diff --git a/src/loader.rs b/src/loader.rs index 6212be3..fa7f062 100644 --- a/src/loader.rs +++ b/src/loader.rs @@ -420,7 +420,7 @@ fn insert_body(schema: &mut Value, path: &[String], leaf: Value) { fn build_openapi(endpoints: &[Arc]) -> Result { let mut document = json!({ "openapi": "3.1.0", - "info": {"title": "SQLRest", "version": "0.1.0"}, + "info": {"title": "SQLRest", "version": env!("CARGO_PKG_VERSION")}, "paths": {}, "components": {"schemas": {}} }); diff --git a/tests/loading_contract.rs b/tests/loading_contract.rs index 44644ae..1c93282 100644 --- a/tests/loading_contract.rs +++ b/tests/loading_contract.rs @@ -45,6 +45,7 @@ fn snapshot_routes_body_and_openapi_are_one_contract() { 405 ); let openapi = snapshot.openapi("/db/personal"); + assert_eq!(openapi["info"]["version"], env!("CARGO_PKG_VERSION")); assert_eq!( openapi["components"]["schemas"]["PatchTodosByIdInput"]["properties"]["input"]["properties"] ["completed"]["type"],