diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1dc8c29..75164d4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -127,12 +127,36 @@ jobs: echo "tag=${tag}" } >> "$GITHUB_OUTPUT" + # Bumps the root `[package]` version only. That is sufficient *because* no + # intra-workspace path dependency carries a `version = "…"` requirement — + # a `minor` bump to 0.2.0 against a sibling asking for `^0.1.0` fails + # resolution here with "failed to select a version", which is exactly how + # the first attempt at this release died. Those requirements only ever + # existed to satisfy crates.io publishing, which this repo does not do. + # + # So: do not add `version` back to a `tinymemory*` path dependency. The + # guard below fails with that explanation rather than cargo's, which does + # not mention the cause. - name: Update crate version env: CRATE_NAME: ${{ steps.version.outputs.crate_name }} NEXT_VERSION: ${{ steps.version.outputs.next_version }} run: | set -euo pipefail + + offenders="$( + grep -rn --include=Cargo.toml -E \ + '^tinymemory(-api|-core|-tinycortex)? *= *\{[^}]*version *=' . || true + )" + if [[ -n "$offenders" ]]; then + echo "An intra-workspace path dependency carries a version requirement:" >&2 + echo "$offenders" >&2 + echo >&2 + echo "Bumping the root package will fail to resolve against it. Nothing here" >&2 + echo "is published to crates.io, so drop the 'version' key and keep 'path'." >&2 + exit 1 + fi + perl -0pi -e 's/(\[package\][\s\S]*?\nversion = ")[^"]+(")/$1$ENV{NEXT_VERSION}$2/' Cargo.toml cargo update -p "$CRATE_NAME" --precise "$NEXT_VERSION" diff --git a/Cargo.toml b/Cargo.toml index a09fa7d..9dc5f07 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,7 +55,7 @@ exclude = [ # The contract itself. Re-exported wholesale from `src/lib.rs` so a host takes # one dependency rather than two, and so `tinymemory::MemoryProvider` and # `tinymemory_api::provider::MemoryProvider` are the same type. -tinymemory-api = { path = "api", version = "0.1.1" } +tinymemory-api = { path = "api" } # The mandatory capability families are `async fn`s on object-safe traits. async-trait = "0.1" # `Memory` is anyhow-typed; `mandatory::engine_error` maps it onto `MemoryError`. diff --git a/adapters/tinycortex/Cargo.toml b/adapters/tinycortex/Cargo.toml index a0eb4db..dc04faf 100644 --- a/adapters/tinycortex/Cargo.toml +++ b/adapters/tinycortex/Cargo.toml @@ -13,8 +13,8 @@ repository = "https://github.com/tinyhumansai/tinymemory" [dependencies] # The contract this adapter targets. -tinymemory = { path = "../..", version = "0.1" } -tinymemory-api = { path = "../../api", version = "0.1.1" } +tinymemory = { path = "../.." } +tinymemory-api = { path = "../../api" } # The engine being adapted. A version requirement rather than a path, so a host # that already pins its own TinyCortex checkout unifies both onto one copy # through its `[patch.crates-io]`; the workspace root patches it to the nested diff --git a/core/Cargo.toml b/core/Cargo.toml index 8ea5592..0e20535 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -15,8 +15,8 @@ readme = "../README.md" [dependencies] # The contract. `tinymemory-core` implements and consumes it; the host seam # traits (config, event sink, embeddings, chat) live in `tinymemory_api::host`. -tinymemory-api = { path = "../api", version = "0.1.1" } -tinymemory = { path = "..", version = "0.1.0" } +tinymemory-api = { path = "../api" } +tinymemory = { path = ".." } # The default embedded engine. `store/`, `tree/` and `sync/` drive it directly; # `tinycortex-api` is a direct dependency because `tinycortex::memory` aliases @@ -67,7 +67,7 @@ block2 = { version = "0.6", optional = true } [dev-dependencies] # `TestHostConfig` — the concrete `MemoryHostConfig` the extracted test suites # build, since `Config` is a trait object and cannot be `Default`ed. -tinymemory-api = { path = "../api", version = "0.1.1", features = ["test-support"] } +tinymemory-api = { path = "../api", features = ["test-support"] } tempfile = "3" tokio = { version = "1", features = ["test-util"] } diff --git a/crates/tinymemory-module/Cargo.toml b/crates/tinymemory-module/Cargo.toml index 93cfb15..bbda847 100644 --- a/crates/tinymemory-module/Cargo.toml +++ b/crates/tinymemory-module/Cargo.toml @@ -25,14 +25,14 @@ crate-type = ["rlib", "cdylib"] # The contract. Every type crossing the bus is one of these, and all of them # already carry serde impls — which is why this module needs no `wire` module of # its own, unlike the tinywallet one. -tinymemory-api = { path = "../../api", version = "0.1.1" } +tinymemory-api = { path = "../../api" } # `MemoryTraitProvider`, which pairs a `Memory` backend with a driver id. -tinymemory = { path = "../..", version = "0.1.0" } +tinymemory = { path = "../.." } # The engine and the seam that adapts it. Carrying these is the entire point of # the module: they are 14.7s of the host's critical build path, and a host that # loads this binary compiles neither. -tinymemory-core = { path = "../../core", version = "0.1.0" } -tinymemory-tinycortex = { path = "../../adapters/tinycortex", version = "0.1.0" } +tinymemory-core = { path = "../../core" } +tinymemory-tinycortex = { path = "../../adapters/tinycortex" } tinycortex = { version = "0.1" } # TinyBus provides the typed service interface and the dynamic module host ABI. # Reached by path now that this crate is its own workspace root: the nested diff --git a/deny.toml b/deny.toml index 25b6aee..049b6f9 100644 --- a/deny.toml +++ b/deny.toml @@ -31,6 +31,23 @@ confidence-threshold = 0.9 # Duplicate versions bloat build times; review them rather than ignoring them. multiple-versions = "warn" wildcards = "deny" +# ...except on a path dependency of a crate that is never published. +# +# `wildcards = "deny"` exists to stop an *unpinned registry* dependency, where +# "any version" means whatever crates.io serves next. A version-less `{ path = +# "api" }` is not that: it resolves to the copy in this repo, at this commit, and +# cannot float. +# +# The version keys were removed from the intra-workspace path deps deliberately +# (see the release workflow's bump step): they only ever existed to satisfy +# crates.io publishing, which this repo does not do, and a sibling requiring +# `^0.1.0` makes a `minor` release bump fail to resolve. cargo-deny scores those +# as wildcards, so without this the two requirements contradict each other. +# +# Scoped, not blanket: cargo-deny only applies it to crates marked +# `publish = false`, which every crate here is. Publishing one again would put +# this error back, correctly. +allow-wildcard-paths = true # Crates that must never enter the dependency graph. deny = []