From 56c5b0165ce1c100daf80bb9bc987a8d3180dd56 Mon Sep 17 00:00:00 2001 From: devolutionsbot <31221910+devolutionsbot@users.noreply.github.com> Date: Mon, 29 Jun 2026 14:35:49 -0400 Subject: [PATCH] chore(release): prepare for publishing --- Cargo.lock | 58 ++++---- Cargo.toml | 2 +- policies/rust/now-policy-api/CHANGELOG.md | 129 ++++++++++++++++++ policies/rust/now-policy-api/Cargo.toml | 60 ++++---- .../now-policy-server-template/CHANGELOG.md | 129 ++++++++++++++++++ .../now-policy-server-template/Cargo.toml | 74 +++++----- protocols/rust/now-proto-pdu/CHANGELOG.md | 122 +++++++++++++++++ protocols/rust/now-proto-pdu/Cargo.toml | 2 +- 8 files changed, 478 insertions(+), 98 deletions(-) create mode 100644 policies/rust/now-policy-api/CHANGELOG.md create mode 100644 policies/rust/now-policy-server-template/CHANGELOG.md diff --git a/Cargo.lock b/Cargo.lock index 41d05be..a6be7e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -135,9 +135,9 @@ checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593" [[package]] name = "cc" -version = "1.2.64" +version = "1.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad887fd958be91b5098c0248def011f4523ab786cd411be668777e55063501f" +checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" dependencies = [ "find-msvc-tools", "shlex", @@ -328,9 +328,9 @@ checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-timer" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" +checksum = "af43fadb8a98512d547e37b4e92e0ced13e205c061b87b4623eff01d918d6968" [[package]] name = "futures-util" @@ -562,9 +562,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "js-sys" -version = "0.3.102" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" dependencies = [ "cfg-if", "futures-util", @@ -585,9 +585,9 @@ checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "log" -version = "0.4.32" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "matchit" @@ -597,9 +597,9 @@ checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" [[package]] name = "mime" @@ -660,7 +660,7 @@ version = "0.0.0" [[package]] name = "now-proto-pdu" -version = "0.4.3" +version = "0.4.4" dependencies = [ "bitflags", "ironrdp-core", @@ -739,18 +739,18 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.45" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" dependencies = [ "proc-macro2", ] [[package]] name = "regex" -version = "1.12.3" +version = "1.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" dependencies = [ "aho-corasick", "memchr", @@ -771,9 +771,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "relative-path" @@ -1001,9 +1001,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.117" +version = "2.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" dependencies = [ "proc-macro2", "quote", @@ -1089,9 +1089,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.11+spec-1.1.0" +version = "0.25.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" +checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" dependencies = [ "indexmap", "toml_datetime", @@ -1215,9 +1215,9 @@ checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" [[package]] name = "wasm-bindgen" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" dependencies = [ "cfg-if", "once_cell", @@ -1228,9 +1228,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1238,9 +1238,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" dependencies = [ "bumpalo", "proc-macro2", @@ -1251,9 +1251,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" dependencies = [ "unicode-ident", ] diff --git a/Cargo.toml b/Cargo.toml index aa3ba62..4078ba9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ keywords = ["rdp", "remote-desktop", "network", "client", "protocol"] categories = ["network-programming"] [workspace.dependencies] -now-proto-pdu = { version = "0.1", path = "protocols/rust/now-proto-pdu" } +now-proto-pdu = { version = "0.4", path = "protocols/rust/now-proto-pdu" } now-proto-fuzzing = { version = "0.1", path = "protocols/rust/now-proto-fuzzing" } [profile.test.package.proptest] diff --git a/policies/rust/now-policy-api/CHANGELOG.md b/policies/rust/now-policy-api/CHANGELOG.md new file mode 100644 index 0000000..cf2abdb --- /dev/null +++ b/policies/rust/now-policy-api/CHANGELOG.md @@ -0,0 +1,129 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + +## [[0.1.0](https://github.com/Devolutions/now-libraries/releases/tag/now-policy-api-v0.1.0)] - 2026-06-29 + +### Features + +- Implement broker APIs and dotnet client ([#76](https://github.com/Devolutions/now-libraries/issues/76)) ([5d343c5f2e](https://github.com/Devolutions/now-libraries/commit/5d343c5f2e611511762812c61238dfec0699daf2)) + + ## Summary + + Adds the package broker API/client foundation to `now-proto` across Rust + and .NET. + + The main goal is to keep the broker protocol definition + implementation-agnostic and transport-independent while making Rust the + source of truth for schema/OpenAPI generation. .NET implementations and + clients can then validate against the generated contract and stay + synchronized with the Rust API model. + + ## Architecture + + ### Rust contract source of truth + + `policies/rust/now-policy-api` defines the canonical package broker wire + model: + + - request, response, status, health, capabilities, and error DTOs; + - package-manager enums and strongly validated newtypes; + - API version and default broker pipe name constants; + - fixed `RequestKind` / `ResponseKind` marker types that serialize as + constant strings and validate discriminator values on deserialization; + - OpenAPI output under + `policies/rust/now-policy-api/openapi/now-policy-api.yaml`. + + This crate intentionally contains no broker implementation. Its purpose + is to describe the protocol shape, generate OpenAPI, and provide a + stable Rust model for tests and server facades. + + ### Rust server facade and mock template + + `policies/rust/now-policy-server-template` provides the implementation + boundary around the API crate: + + - `PackageBrokerServer` trait as the server-side facade; + - Axum router/template that maps HTTP endpoints to the facade without + embedding policy/package-manager logic; + - fixture-backed mock broker for deterministic request/response testing; + - sample request, response, and scenario documents derived from the + Uniget broker shape; + - OpenAPI generation tool that writes the contract back into the API + crate. + + This keeps real broker behavior out of `now-proto` while still allowing + the API to be exercised end-to-end. + + ### Transport-independent message shape + + The protocol now treats request/response identity as part of the body + schema instead of HTTP metadata: + + - `RequestKind` and `RequestVersion` live at the top level of request + messages. + - `ResponseKind` and `ResponseVersion` live at the top level of response + messages. + + This keeps the schema usable if the broker later moves away from + HTTP-over-named-pipe to another transport. + + ### .NET API package + + `policies/dotnet/Devolutions.Now.Policy.Api` mirrors the Rust schema in + C#: + + - API constants, JSON serialization options, and policy-model + compatibility conversions are centralized here. + - Tests validate DTO behavior against the Rust-generated OpenAPI and + shared sample documents. + + This package contains only API types and no transport/client execution + logic. + + ### .NET client package + + `policies/dotnet/Devolutions.Now.Policy.Client` contains the actual + client behavior: + + - `BrokerClient` exposes high-level methods for health, capabilities, + evaluate, execute, and operation status. + - `BrokerClientOptions` is the single configuration entry point. + - Client context fields are filled implicitly where possible, including + effective user, client version, executable path, transport, timestamps, + and generated request IDs. + - Public request wrapper types avoid exposing raw wire DTO fields that + the client owns. + - `IBrokerTransport` abstracts transport so named pipes are only one + implementation detail. + - `NamedPipeBrokerTransport` handles the current HTTP-over-named-pipe + transport. + - Capabilities are fetched and cached before operation/status requests + so unsupported operations fail locally before sending the request. + + ### Test and fixture strategy + + Shared Rust sample documents are used as contract fixtures for both Rust + and .NET. The Rust server-template tests verify sample deserialization, + mock broker behavior, and router/facade wiring. The .NET tests validate + DTO schema compatibility, fixed discriminator handling, policy enum + compatibility, fake transport behavior, capability preflight, error + mapping, and client-generated request metadata. + + ## Changes + + - Added Rust `now-policy-api` and `now-policy-server-template` crates. + - Added generated package broker OpenAPI contract. + - Added shared request/response/scenario samples. + - Added .NET `Devolutions.Now.Policy.Api` and + `Devolutions.Now.Policy.Client` projects. + - Added .NET client/API tests using fake transport and Rust fixture + validation. + - Updated Cargo workspace, .NET solution, NuGet publishing workflow, and + package documentation. + + diff --git a/policies/rust/now-policy-api/Cargo.toml b/policies/rust/now-policy-api/Cargo.toml index b583b47..7129ffe 100644 --- a/policies/rust/now-policy-api/Cargo.toml +++ b/policies/rust/now-policy-api/Cargo.toml @@ -1,30 +1,30 @@ -[package] -name = "now-policy-api" -version = "0.1.0" -edition = "2024" -license.workspace = true -homepage.workspace = true -repository.workspace = true -authors.workspace = true -readme = "README.md" -description = "Implementation-agnostic Devolutions NOW policy package broker API model" -publish = true - -[lints] -workspace = true - -[features] -default = [] -policy-compat = ["dep:now-policy"] - -[dependencies] -base64 = "0.22" -chrono = { version = "0.4", features = ["serde"] } -derive_more = { version = "2", features = ["as_ref", "deref", "display", "from"] } -now-policy = { version = "0.1", path = "../now-policy", optional = true } -schemars = { version = "0.8", features = ["chrono"] } -semver = "1" -serde = { version = "1", features = ["derive"] } -serde_json = "1" -strum = { version = "0.27", features = ["derive"] } -thiserror = "2" +[package] +name = "now-policy-api" +version = "0.1.0" +edition = "2024" +license.workspace = true +homepage.workspace = true +repository.workspace = true +authors.workspace = true +readme = "README.md" +description = "Implementation-agnostic Devolutions NOW policy package broker API model" +publish = true + +[lints] +workspace = true + +[features] +default = [] +policy-compat = ["dep:now-policy"] + +[dependencies] +base64 = "0.22" +chrono = { version = "0.4", features = ["serde"] } +derive_more = { version = "2", features = ["as_ref", "deref", "display", "from"] } +now-policy = { version = "0.1", path = "../now-policy", optional = true } +schemars = { version = "0.8", features = ["chrono"] } +semver = "1" +serde = { version = "1", features = ["derive"] } +serde_json = "1" +strum = { version = "0.27", features = ["derive"] } +thiserror = "2" diff --git a/policies/rust/now-policy-server-template/CHANGELOG.md b/policies/rust/now-policy-server-template/CHANGELOG.md new file mode 100644 index 0000000..158fa14 --- /dev/null +++ b/policies/rust/now-policy-server-template/CHANGELOG.md @@ -0,0 +1,129 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + +## [[0.1.0](https://github.com/Devolutions/now-libraries/releases/tag/now-policy-server-template-v0.1.0)] - 2026-06-29 + +### Features + +- Implement broker APIs and dotnet client ([#76](https://github.com/Devolutions/now-libraries/issues/76)) ([5d343c5f2e](https://github.com/Devolutions/now-libraries/commit/5d343c5f2e611511762812c61238dfec0699daf2)) + + ## Summary + + Adds the package broker API/client foundation to `now-proto` across Rust + and .NET. + + The main goal is to keep the broker protocol definition + implementation-agnostic and transport-independent while making Rust the + source of truth for schema/OpenAPI generation. .NET implementations and + clients can then validate against the generated contract and stay + synchronized with the Rust API model. + + ## Architecture + + ### Rust contract source of truth + + `policies/rust/now-policy-api` defines the canonical package broker wire + model: + + - request, response, status, health, capabilities, and error DTOs; + - package-manager enums and strongly validated newtypes; + - API version and default broker pipe name constants; + - fixed `RequestKind` / `ResponseKind` marker types that serialize as + constant strings and validate discriminator values on deserialization; + - OpenAPI output under + `policies/rust/now-policy-api/openapi/now-policy-api.yaml`. + + This crate intentionally contains no broker implementation. Its purpose + is to describe the protocol shape, generate OpenAPI, and provide a + stable Rust model for tests and server facades. + + ### Rust server facade and mock template + + `policies/rust/now-policy-server-template` provides the implementation + boundary around the API crate: + + - `PackageBrokerServer` trait as the server-side facade; + - Axum router/template that maps HTTP endpoints to the facade without + embedding policy/package-manager logic; + - fixture-backed mock broker for deterministic request/response testing; + - sample request, response, and scenario documents derived from the + Uniget broker shape; + - OpenAPI generation tool that writes the contract back into the API + crate. + + This keeps real broker behavior out of `now-proto` while still allowing + the API to be exercised end-to-end. + + ### Transport-independent message shape + + The protocol now treats request/response identity as part of the body + schema instead of HTTP metadata: + + - `RequestKind` and `RequestVersion` live at the top level of request + messages. + - `ResponseKind` and `ResponseVersion` live at the top level of response + messages. + + This keeps the schema usable if the broker later moves away from + HTTP-over-named-pipe to another transport. + + ### .NET API package + + `policies/dotnet/Devolutions.Now.Policy.Api` mirrors the Rust schema in + C#: + + - API constants, JSON serialization options, and policy-model + compatibility conversions are centralized here. + - Tests validate DTO behavior against the Rust-generated OpenAPI and + shared sample documents. + + This package contains only API types and no transport/client execution + logic. + + ### .NET client package + + `policies/dotnet/Devolutions.Now.Policy.Client` contains the actual + client behavior: + + - `BrokerClient` exposes high-level methods for health, capabilities, + evaluate, execute, and operation status. + - `BrokerClientOptions` is the single configuration entry point. + - Client context fields are filled implicitly where possible, including + effective user, client version, executable path, transport, timestamps, + and generated request IDs. + - Public request wrapper types avoid exposing raw wire DTO fields that + the client owns. + - `IBrokerTransport` abstracts transport so named pipes are only one + implementation detail. + - `NamedPipeBrokerTransport` handles the current HTTP-over-named-pipe + transport. + - Capabilities are fetched and cached before operation/status requests + so unsupported operations fail locally before sending the request. + + ### Test and fixture strategy + + Shared Rust sample documents are used as contract fixtures for both Rust + and .NET. The Rust server-template tests verify sample deserialization, + mock broker behavior, and router/facade wiring. The .NET tests validate + DTO schema compatibility, fixed discriminator handling, policy enum + compatibility, fake transport behavior, capability preflight, error + mapping, and client-generated request metadata. + + ## Changes + + - Added Rust `now-policy-api` and `now-policy-server-template` crates. + - Added generated package broker OpenAPI contract. + - Added shared request/response/scenario samples. + - Added .NET `Devolutions.Now.Policy.Api` and + `Devolutions.Now.Policy.Client` projects. + - Added .NET client/API tests using fake transport and Rust fixture + validation. + - Updated Cargo workspace, .NET solution, NuGet publishing workflow, and + package documentation. + + diff --git a/policies/rust/now-policy-server-template/Cargo.toml b/policies/rust/now-policy-server-template/Cargo.toml index ec0393d..c620169 100644 --- a/policies/rust/now-policy-server-template/Cargo.toml +++ b/policies/rust/now-policy-server-template/Cargo.toml @@ -1,37 +1,37 @@ -[package] -name = "now-policy-server-template" -version = "0.1.0" -edition = "2024" -license.workspace = true -homepage.workspace = true -repository.workspace = true -authors.workspace = true -readme = "README.md" -description = "Reusable Devolutions NOW package broker server facade, mock, and OpenAPI generator" -publish = true - -[lints] -workspace = true - -[features] -default = [] -policy-compat = ["dep:now-policy", "now-policy-api/policy-compat"] - -[dependencies] -aide = { version = "0.14", features = ["axum", "axum-json"] } -async-trait = "0.1" -axum = { version = "0.8", default-features = false, features = ["json"] } -now-policy-api = { version = "0.1", path = "../now-policy-api" } -now-policy = { version = "0.1", path = "../now-policy", optional = true } -schemars = "0.8" -serde = { version = "1", features = ["derive"] } -serde_json = "1" -serde_yaml = "0.9" - -[dev-dependencies] -tokio = { version = "1.52", features = ["macros", "rt"] } -tower = { version = "0.5", features = ["util"] } - -[[bin]] -name = "generate-now-policy-api-openapi" -path = "tools/generate_openapi.rs" +[package] +name = "now-policy-server-template" +version = "0.1.0" +edition = "2024" +license.workspace = true +homepage.workspace = true +repository.workspace = true +authors.workspace = true +readme = "README.md" +description = "Reusable Devolutions NOW package broker server facade, mock, and OpenAPI generator" +publish = true + +[lints] +workspace = true + +[features] +default = [] +policy-compat = ["dep:now-policy", "now-policy-api/policy-compat"] + +[dependencies] +aide = { version = "0.14", features = ["axum", "axum-json"] } +async-trait = "0.1" +axum = { version = "0.8", default-features = false, features = ["json"] } +now-policy-api = { version = "0.1", path = "../now-policy-api" } +now-policy = { version = "0.1", path = "../now-policy", optional = true } +schemars = "0.8" +serde = { version = "1", features = ["derive"] } +serde_json = "1" +serde_yaml = "0.9" + +[dev-dependencies] +tokio = { version = "1.52", features = ["macros", "rt"] } +tower = { version = "0.5", features = ["util"] } + +[[bin]] +name = "generate-now-policy-api-openapi" +path = "tools/generate_openapi.rs" diff --git a/protocols/rust/now-proto-pdu/CHANGELOG.md b/protocols/rust/now-proto-pdu/CHANGELOG.md index 6832d98..3f69cc3 100644 --- a/protocols/rust/now-proto-pdu/CHANGELOG.md +++ b/protocols/rust/now-proto-pdu/CHANGELOG.md @@ -6,6 +6,128 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [[0.4.4](https://github.com/Devolutions/now-libraries/compare/now-proto-pdu-v0.4.3...now-proto-pdu-v0.4.4)] - 2026-06-29 + +### Features + +- Implement broker APIs and dotnet client ([#76](https://github.com/Devolutions/now-libraries/issues/76)) ([5d343c5f2e](https://github.com/Devolutions/now-libraries/commit/5d343c5f2e611511762812c61238dfec0699daf2)) + + ## Summary + + Adds the package broker API/client foundation to `now-proto` across Rust + and .NET. + + The main goal is to keep the broker protocol definition + implementation-agnostic and transport-independent while making Rust the + source of truth for schema/OpenAPI generation. .NET implementations and + clients can then validate against the generated contract and stay + synchronized with the Rust API model. + + ## Architecture + + ### Rust contract source of truth + + `policies/rust/now-policy-api` defines the canonical package broker wire + model: + + - request, response, status, health, capabilities, and error DTOs; + - package-manager enums and strongly validated newtypes; + - API version and default broker pipe name constants; + - fixed `RequestKind` / `ResponseKind` marker types that serialize as + constant strings and validate discriminator values on deserialization; + - OpenAPI output under + `policies/rust/now-policy-api/openapi/now-policy-api.yaml`. + + This crate intentionally contains no broker implementation. Its purpose + is to describe the protocol shape, generate OpenAPI, and provide a + stable Rust model for tests and server facades. + + ### Rust server facade and mock template + + `policies/rust/now-policy-server-template` provides the implementation + boundary around the API crate: + + - `PackageBrokerServer` trait as the server-side facade; + - Axum router/template that maps HTTP endpoints to the facade without + embedding policy/package-manager logic; + - fixture-backed mock broker for deterministic request/response testing; + - sample request, response, and scenario documents derived from the + Uniget broker shape; + - OpenAPI generation tool that writes the contract back into the API + crate. + + This keeps real broker behavior out of `now-proto` while still allowing + the API to be exercised end-to-end. + + ### Transport-independent message shape + + The protocol now treats request/response identity as part of the body + schema instead of HTTP metadata: + + - `RequestKind` and `RequestVersion` live at the top level of request + messages. + - `ResponseKind` and `ResponseVersion` live at the top level of response + messages. + + This keeps the schema usable if the broker later moves away from + HTTP-over-named-pipe to another transport. + + ### .NET API package + + `policies/dotnet/Devolutions.Now.Policy.Api` mirrors the Rust schema in + C#: + + - API constants, JSON serialization options, and policy-model + compatibility conversions are centralized here. + - Tests validate DTO behavior against the Rust-generated OpenAPI and + shared sample documents. + + This package contains only API types and no transport/client execution + logic. + + ### .NET client package + + `policies/dotnet/Devolutions.Now.Policy.Client` contains the actual + client behavior: + + - `BrokerClient` exposes high-level methods for health, capabilities, + evaluate, execute, and operation status. + - `BrokerClientOptions` is the single configuration entry point. + - Client context fields are filled implicitly where possible, including + effective user, client version, executable path, transport, timestamps, + and generated request IDs. + - Public request wrapper types avoid exposing raw wire DTO fields that + the client owns. + - `IBrokerTransport` abstracts transport so named pipes are only one + implementation detail. + - `NamedPipeBrokerTransport` handles the current HTTP-over-named-pipe + transport. + - Capabilities are fetched and cached before operation/status requests + so unsupported operations fail locally before sending the request. + + ### Test and fixture strategy + + Shared Rust sample documents are used as contract fixtures for both Rust + and .NET. The Rust server-template tests verify sample deserialization, + mock broker behavior, and router/facade wiring. The .NET tests validate + DTO schema compatibility, fixed discriminator handling, policy enum + compatibility, fake transport behavior, capability preflight, error + mapping, and client-generated request metadata. + + ## Changes + + - Added Rust `now-policy-api` and `now-policy-server-template` crates. + - Added generated package broker OpenAPI contract. + - Added shared request/response/scenario samples. + - Added .NET `Devolutions.Now.Policy.Api` and + `Devolutions.Now.Policy.Client` projects. + - Added .NET client/API tests using fake transport and Rust fixture + validation. + - Updated Cargo workspace, .NET solution, NuGet publishing workflow, and + package documentation. + + + ## [[0.4.3](https://github.com/Devolutions/now-proto/compare/now-proto-pdu-v0.4.2...now-proto-pdu-v0.4.3)] - 2026-05-15 ### Features diff --git a/protocols/rust/now-proto-pdu/Cargo.toml b/protocols/rust/now-proto-pdu/Cargo.toml index 7458624..3dcebd4 100644 --- a/protocols/rust/now-proto-pdu/Cargo.toml +++ b/protocols/rust/now-proto-pdu/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "now-proto-pdu" -version = "0.4.3" +version = "0.4.4" readme = "README.md" description = "NOW protocol PDU encoding and decoding" edition.workspace = true