From 6b9adea1435958dad0f0ef35520e371d54e9f0ef Mon Sep 17 00:00:00 2001 From: Iain McGinniss <309153+iainmcgin@users.noreply.github.com> Date: Fri, 15 May 2026 23:27:21 +0000 Subject: [PATCH] release: bump workspace to 0.6.0, finalize changelog and docs Everything targeted for 0.6.0 is on main: feature-gated codegen (#117/#118/#119), file-level extern path routing for descriptor.proto (#114), closed-enum bound relaxation (#115), serde_json re-export (#112), view Serialize impls (#106), empty-file omission (#107), with_* setters (#93), MessageName trait (#108), BSR plugin docs and bsr-quickstart example (#116), and the LTO release profile (#85). Version bump: - Workspace version 0.5.2 -> 0.6.0. - Inter-crate version constraints in [workspace.dependencies] and the per-crate Cargo.toml files that hardcode them (buffa-build, buffa-codegen, protoc-gen-buffa, protoc-gen-buffa-packaging). - Cargo.lock updated. CHANGELOG: - [Unreleased] -> [0.6.0] - 2026-05-15. New empty [Unreleased] section. - Comparison links: add [0.6.0], [0.5.2], [0.5.1] (the latter two were missing); fix [Unreleased] base from v0.5.0 to v0.6.0. Documentation accuracy fixes: - docs/guide.md: rewrite the "Descriptor types" section. The previous text said descriptor message types referenced as fields with views/json/text "will not currently compile; please file an issue" -- contradicting #118, which made exactly this work. The section now documents the new requirement: enable matching buffa-descriptor features when descriptor message types are referenced as fields. - docs/guide.md: bump 11 inline `version = "0.5"` examples to "0.6". - docs/guide.md: bump release-binary download instructions and BSR remote-plugin pin guidance from v0.5.2/v0.5.3 to v0.6.0. - docs/guide.md: add a paragraph in the JSON section noting view types implement serde::Serialize directly when generate_json is enabled (#106), with the extension-field and serialize_map(None) caveats. - docs/migration-from-prost.md, docs/migration-from-protobuf.md, README.md, examples/bsr-quickstart/Cargo.toml: bump "0.5" -> "0.6". Deliberately NOT changed: - examples/bsr-quickstart/buf.gen.yaml stays pinned to v0.5.2: the checked-in src/gen/ was generated by that BSR plugin version, and the v0.6.0 BSR plugin doesn't exist until Buf publishes the bump in bufbuild/plugins. Update both together post-release. - README.md benchmark caption stays "measured at v0.5.0" -- benchmarks have not been re-run. --- CHANGELOG.md | 7 ++- Cargo.lock | 16 +++---- Cargo.toml | 14 +++--- README.md | 2 +- buffa-build/Cargo.toml | 2 +- buffa-codegen/Cargo.toml | 2 +- docs/guide.md | 61 +++++++++++++++++---------- docs/migration-from-prost.md | 10 ++--- docs/migration-from-protobuf.md | 12 +++--- examples/bsr-quickstart/Cargo.toml | 4 +- protoc-gen-buffa-packaging/Cargo.toml | 2 +- protoc-gen-buffa/Cargo.toml | 2 +- 12 files changed, 78 insertions(+), 56 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fd9dbd..19749e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ## [Unreleased] +## [0.6.0] - 2026-05-15 + ### Added - **Generated message structs now include `with_(value) -> Self` @@ -745,7 +747,10 @@ This release publishes: MSRV: Rust 1.85. -[Unreleased]: https://github.com/anthropics/buffa/compare/v0.5.0...HEAD +[Unreleased]: https://github.com/anthropics/buffa/compare/v0.6.0...HEAD +[0.6.0]: https://github.com/anthropics/buffa/compare/v0.5.2...v0.6.0 +[0.5.2]: https://github.com/anthropics/buffa/compare/v0.5.1...v0.5.2 +[0.5.1]: https://github.com/anthropics/buffa/compare/v0.5.0...v0.5.1 [0.5.0]: https://github.com/anthropics/buffa/compare/v0.4.0...v0.5.0 [0.4.0]: https://github.com/anthropics/buffa/compare/v0.3.0...v0.4.0 [0.3.0]: https://github.com/anthropics/buffa/compare/v0.2.0...v0.3.0 diff --git a/Cargo.lock b/Cargo.lock index b97e200..08e1502 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,7 +58,7 @@ checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "buffa" -version = "0.5.2" +version = "0.6.0" dependencies = [ "arbitrary", "base64", @@ -72,7 +72,7 @@ dependencies = [ [[package]] name = "buffa-build" -version = "0.5.2" +version = "0.6.0" dependencies = [ "buffa", "buffa-codegen", @@ -81,7 +81,7 @@ dependencies = [ [[package]] name = "buffa-codegen" -version = "0.5.2" +version = "0.6.0" dependencies = [ "buffa", "buffa-descriptor", @@ -95,7 +95,7 @@ dependencies = [ [[package]] name = "buffa-descriptor" -version = "0.5.2" +version = "0.6.0" dependencies = [ "arbitrary", "buffa", @@ -105,7 +105,7 @@ dependencies = [ [[package]] name = "buffa-test" -version = "0.5.2" +version = "0.6.0" dependencies = [ "arbitrary", "buffa", @@ -118,7 +118,7 @@ dependencies = [ [[package]] name = "buffa-types" -version = "0.5.2" +version = "0.6.0" dependencies = [ "arbitrary", "buffa", @@ -523,7 +523,7 @@ dependencies = [ [[package]] name = "protoc-gen-buffa" -version = "0.5.2" +version = "0.6.0" dependencies = [ "buffa", "buffa-codegen", @@ -531,7 +531,7 @@ dependencies = [ [[package]] name = "protoc-gen-buffa-packaging" -version = "0.5.2" +version = "0.6.0" dependencies = [ "buffa", "buffa-codegen", diff --git a/Cargo.toml b/Cargo.toml index 85d95e2..91783dc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ exclude = [ ] [workspace.package] -version = "0.5.2" +version = "0.6.0" edition = "2021" rust-version = "1.85" license = "Apache-2.0" @@ -42,18 +42,18 @@ lto = true codegen-units = 1 [workspace.dependencies] -buffa = { path = "buffa", version = "0.5.2", default-features = false } -buffa-types = { path = "buffa-types", version = "0.5.2" } +buffa = { path = "buffa", version = "0.6.0", default-features = false } +buffa-types = { path = "buffa-types", version = "0.6.0" } # `default-features = false` keeps the codegen toolchain (`buffa-codegen` / # `buffa-build` / `protoc-gen-buffa`) lean — descriptor types are read at # codegen time via the binary codec only, never serialised to JSON / text or # borrowed as views, so the codegen build graph carries no `serde` / # `serde_json` / `base64`. Downstream consumers whose protos reference # `descriptor.proto` types as fields enable the features they need. -buffa-descriptor = { path = "buffa-descriptor", version = "0.5.2", default-features = false } -buffa-codegen = { path = "buffa-codegen", version = "0.5.2" } -buffa-build = { path = "buffa-build", version = "0.5.2" } -buffa-test = { path = "buffa-test", version = "0.5.2" } +buffa-descriptor = { path = "buffa-descriptor", version = "0.6.0", default-features = false } +buffa-codegen = { path = "buffa-codegen", version = "0.6.0" } +buffa-build = { path = "buffa-build", version = "0.6.0" } +buffa-test = { path = "buffa-test", version = "0.6.0" } base64 = { version = "0.22", default-features = false, features = ["alloc"] } bytes = { version = "1", default-features = false } hashbrown = { version = "0.15", default-features = false, features = ["default-hasher"] } diff --git a/README.md b/README.md index a4e867d..b5e5211 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ These are gaps we intend to address in future releases: ## Semver and API stability -Buffa is pre-1.0. We follow the [Rust community convention](https://doc.rust-lang.org/cargo/reference/semver.html) for 0.x crates: breaking changes increment the **minor** version (0.1.x → 0.2.0), additive changes increment the **patch** version (0.1.0 → 0.1.1). Pin to a minor version (`buffa = "0.5"`) to avoid surprises. +Buffa is pre-1.0. We follow the [Rust community convention](https://doc.rust-lang.org/cargo/reference/semver.html) for 0.x crates: breaking changes increment the **minor** version (0.1.x → 0.2.0), additive changes increment the **patch** version (0.1.0 → 0.1.1). Pin to a minor version (`buffa = "0.6"`) to avoid surprises. The generated code API (struct shapes, `Message` trait, `MessageView` trait, `EnumValue`, `MessageField`) is considered the primary stability surface. Internal helper modules marked `#[doc(hidden)]` (`__private`, `__buffa_*` fields) may change at any time. diff --git a/buffa-build/Cargo.toml b/buffa-build/Cargo.toml index 329d02f..f8fc83d 100644 --- a/buffa-build/Cargo.toml +++ b/buffa-build/Cargo.toml @@ -13,6 +13,6 @@ categories = ["development-tools::build-utils"] rustdoc-args = ["--cfg", "docsrs"] [dependencies] -buffa = { path = "../buffa", version = "0.5.2" } +buffa = { path = "../buffa", version = "0.6.0" } buffa-codegen = { workspace = true } tempfile = "3" diff --git a/buffa-codegen/Cargo.toml b/buffa-codegen/Cargo.toml index ede6ebe..9171e5d 100644 --- a/buffa-codegen/Cargo.toml +++ b/buffa-codegen/Cargo.toml @@ -11,7 +11,7 @@ categories = ["development-tools::build-utils"] [dependencies] # `path` wins for local workspace development; `version` is used on publish. -buffa = { path = "../buffa", version = "0.5.2" } +buffa = { path = "../buffa", version = "0.6.0" } # Codegen reads descriptors via the binary codec only — no views / json / # text. The workspace dep already declares `default-features = false`; add # back `std` (it's a build-time tool, never `no_std`). diff --git a/docs/guide.md b/docs/guide.md index c495255..c585454 100644 --- a/docs/guide.md +++ b/docs/guide.md @@ -9,11 +9,11 @@ Add buffa to your project: ```toml # Cargo.toml [dependencies] -buffa = "0.5" -buffa-types = "0.5" # well-known types (Timestamp, Duration, Any, etc.) +buffa = "0.6" +buffa-types = "0.6" # well-known types (Timestamp, Duration, Any, etc.) [build-dependencies] -buffa-build = "0.5" +buffa-build = "0.6" ``` ### Feature flags @@ -28,8 +28,8 @@ Both `buffa` and `buffa-types` share the same feature flag names: ```toml # Enable JSON support -buffa = { version = "0.5", features = ["json"] } -buffa-types = { version = "0.5", features = ["json"] } +buffa = { version = "0.6", features = ["json"] } +buffa-types = { version = "0.6", features = ["json"] } ``` ## Prerequisites @@ -196,7 +196,7 @@ This requires `buffa-types` as a dependency in your `Cargo.toml`: ```toml [dependencies] -buffa-types = "0.5" +buffa-types = "0.6" ``` `buffa-types` is a pure source crate — it does **not** run `protoc` or any code generation at build time. If your protos use WKTs but you generate your own Rust code ahead-of-time (via `buf generate` or a `protoc` script), then `buffa` + `buffa-types` is your entire runtime dependency surface. @@ -219,12 +219,20 @@ This disables the automatic mapping and routes all `google.protobuf.*` reference ```toml [dependencies] -buffa-descriptor = "0.5" +buffa-descriptor = "0.6" ``` If your protos import `descriptor.proto` only to declare custom options (`extend google.protobuf.MessageOptions { ... }`) and never reference a descriptor type as a *field type*, no `buffa-descriptor` dependency is required — extension declarations don't generate field-type references. -`buffa-descriptor` is generated without views, JSON, or text impls (it exists primarily to bootstrap `buffa-codegen`). Its **enum** types — the only descriptor types referenced as field types in practice — work with all codegen modes. Descriptor **message** types referenced as fields with `views=true`, `json=true`, or `text=true` will not currently compile; if you hit this, please [file an issue](https://github.com/anthropics/buffa/issues). +`buffa-descriptor` ships its view, JSON, text, and arbitrary impls behind crate features (`views`, `json`, `text`, `arbitrary`), all off by default. The codegen toolchain depends on it with `default-features = false`, so building `buffa-codegen` / `buffa-build` / `protoc-gen-buffa` doesn't pull in `serde` or `serde_json`. **If your protos reference a descriptor message type as a field type and you generate with `views=true`, `json=true`, or `text=true`, enable the matching `buffa-descriptor` features**: + +```toml +[dependencies] +# Codegen with .generate_views(true).generate_json(true) +buffa-descriptor = { version = "0.6", features = ["views", "json"] } +``` + +Descriptor **enum** types referenced as field types (the most common case — e.g. `google.protobuf.FieldDescriptorProto.Type` in protovalidate) work with the default feature set. The features are only needed for descriptor **message** types referenced as fields (e.g. `FileDescriptorSet`, `FileDescriptorProto`). If you hit a missing-impl error like `the trait bound FileDescriptorSet: serde::Deserialize is not satisfied`, add `buffa-descriptor` with the right features. A user-provided `.google.protobuf` extern_path covers descriptor types too — the auto-routing yields to it, preserving the behaviour from before `buffa-descriptor` routing existed. @@ -350,25 +358,25 @@ Download the binaries for your platform from the [releases page](https://github. ```sh # Download binaries + cosign signatures + certificates (both plugins match) -gh release download v0.5.2 --repo anthropics/buffa \ +gh release download v0.6.0 --repo anthropics/buffa \ --pattern 'protoc-gen-buffa*-linux-x86_64*' # Verify with GitHub attestations (requires gh CLI ≥ 2.49) -gh attestation verify protoc-gen-buffa-v0.5.2-linux-x86_64 --repo anthropics/buffa -gh attestation verify protoc-gen-buffa-packaging-v0.5.2-linux-x86_64 --repo anthropics/buffa +gh attestation verify protoc-gen-buffa-v0.6.0-linux-x86_64 --repo anthropics/buffa +gh attestation verify protoc-gen-buffa-packaging-v0.6.0-linux-x86_64 --repo anthropics/buffa # Or with cosign (standalone, no gh required) — shown for one binary cosign verify-blob \ - --signature protoc-gen-buffa-v0.5.2-linux-x86_64.sig \ - --certificate protoc-gen-buffa-v0.5.2-linux-x86_64.pem \ + --signature protoc-gen-buffa-v0.6.0-linux-x86_64.sig \ + --certificate protoc-gen-buffa-v0.6.0-linux-x86_64.pem \ --certificate-identity-regexp "github.com/anthropics/buffa" \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ - protoc-gen-buffa-v0.5.2-linux-x86_64 + protoc-gen-buffa-v0.6.0-linux-x86_64 # Install both -chmod +x protoc-gen-buffa-v0.5.2-linux-x86_64 protoc-gen-buffa-packaging-v0.5.2-linux-x86_64 -mv protoc-gen-buffa-v0.5.2-linux-x86_64 ~/.local/bin/protoc-gen-buffa -mv protoc-gen-buffa-packaging-v0.5.2-linux-x86_64 ~/.local/bin/protoc-gen-buffa-packaging +chmod +x protoc-gen-buffa-v0.6.0-linux-x86_64 protoc-gen-buffa-packaging-v0.6.0-linux-x86_64 +mv protoc-gen-buffa-v0.6.0-linux-x86_64 ~/.local/bin/protoc-gen-buffa +mv protoc-gen-buffa-packaging-v0.6.0-linux-x86_64 ~/.local/bin/protoc-gen-buffa-packaging ``` Available platforms: `linux-x86_64`, `linux-aarch64`, `darwin-x86_64`, `darwin-aarch64`, `windows-x86_64` (`.exe`). All releases include SHA-256 checksums, Sigstore cosign signatures, and signed SLSA build provenance for supply chain verification. @@ -409,7 +417,7 @@ pub mod example { mod gen; ``` -Pin the plugin version for reproducible builds: `remote: buf.build/anthropics/buffa:v0.5.3`. Match it to the `buffa` runtime crate version in your `Cargo.toml` — generated code from a newer plugin may reference items that don't exist in an older runtime. +Pin the plugin version for reproducible builds: `remote: buf.build/anthropics/buffa:v0.6.0`. Match it to the `buffa` runtime crate version in your `Cargo.toml` — generated code from a newer plugin may reference items that don't exist in an older runtime. The complete, runnable [`examples/bsr-quickstart/`](../examples/bsr-quickstart/) project uses this layout. @@ -1081,7 +1089,7 @@ Enable the `json` feature and `generate_json(true)` in your build config: ```toml # Cargo.toml [dependencies] -buffa = { version = "0.5", features = ["json"] } +buffa = { version = "0.6", features = ["json"] } # Required: generated `#[derive(::serde::Serialize, ::serde::Deserialize)]` # expands to `extern crate serde as _serde;`, so the consumer crate must # depend on `serde` directly. `serde_json` is *not* required by generated @@ -1118,6 +1126,15 @@ let json = serde_json::to_string(&msg)?; let msg: Person = serde_json::from_str(&json)?; ``` +When `generate_views(true)` is also enabled, generated **view** types implement +`serde::Serialize` directly, so you can serialize a decoded view to JSON without +first calling `to_owned_message()`. `OwnedView` has a blanket `Serialize` impl +too, so `serde_json::to_string(&owned_view)` works the same way. Two limitations +relative to the owned form: extension fields are not included in view JSON output +(serialize the owned form to include them), and the view impl uses +`serialize_map(None)`, which `serde_json` accepts but length-prefixed formats like +`bincode` reject — use the owned form for those serializers. + ### JSON parse options For lenient parsing (e.g., ignoring unknown enum string values): @@ -1143,7 +1160,7 @@ Enable the `text` feature and `generate_text(true)`: ```toml # Cargo.toml [dependencies] -buffa = { version = "0.5", features = ["text"] } +buffa = { version = "0.6", features = ["text"] } ``` ```rust,ignore @@ -1274,8 +1291,8 @@ let obj = Struct::from_fields([ Buffa works without `std` (requires `alloc`): ```toml -buffa = { version = "0.5", default-features = false } -buffa-types = { version = "0.5", default-features = false } +buffa = { version = "0.6", default-features = false } +buffa-types = { version = "0.6", default-features = false } ``` In `no_std` mode: diff --git a/docs/migration-from-prost.md b/docs/migration-from-prost.md index ce38c63..064e066 100644 --- a/docs/migration-from-prost.md +++ b/docs/migration-from-prost.md @@ -9,12 +9,12 @@ A step-by-step guide for migrating an existing prost-based project to buffa. [dependencies] -prost = "0.13" -prost-types = "0.13" -+buffa = "0.5" -+buffa-types = "0.5" ++buffa = "0.6" ++buffa-types = "0.6" [build-dependencies] -prost-build = "0.13" -+buffa-build = "0.5" ++buffa-build = "0.6" ``` If you use JSON serialization via `pbjson`: @@ -23,8 +23,8 @@ If you use JSON serialization via `pbjson`: [dependencies] -pbjson = "0.7" -pbjson-types = "0.7" -+buffa = { version = "0.5", features = ["json"] } -+buffa-types = { version = "0.5", features = ["json"] } ++buffa = { version = "0.6", features = ["json"] } ++buffa-types = { version = "0.6", features = ["json"] } serde_json = "1" - -[build-dependencies] diff --git a/docs/migration-from-protobuf.md b/docs/migration-from-protobuf.md index 0a26275..443ee5f 100644 --- a/docs/migration-from-protobuf.md +++ b/docs/migration-from-protobuf.md @@ -12,13 +12,13 @@ This guide covers migration from both versions of the `protobuf` crate: ```diff [dependencies] -protobuf = "3" -+buffa = "0.5" -+buffa-types = "0.5" ++buffa = "0.6" ++buffa-types = "0.6" [build-dependencies] -protobuf-codegen = "3" -protoc-bin-vendored = "3" # if using vendored protoc -+buffa-build = "0.5" ++buffa-build = "0.6" ``` ### From Google v4 @@ -26,12 +26,12 @@ This guide covers migration from both versions of the `protobuf` crate: ```diff [dependencies] -protobuf = "=4.33.1-release" -+buffa = "0.5" -+buffa-types = "0.5" ++buffa = "0.6" ++buffa-types = "0.6" [build-dependencies] -protobuf-codegen = "=4.33.1-release" -+buffa-build = "0.5" ++buffa-build = "0.6" ``` ## 2. Rewrite `build.rs` diff --git a/examples/bsr-quickstart/Cargo.toml b/examples/bsr-quickstart/Cargo.toml index 7bd70a4..c773434 100644 --- a/examples/bsr-quickstart/Cargo.toml +++ b/examples/bsr-quickstart/Cargo.toml @@ -16,8 +16,8 @@ plugin with `file_per_package=true` and a hand-written `mod.rs`. See # example also acts as a forward-compat canary: if an in-tree runtime change # ever breaks code generated by the published plugin, this example fails to # build. In a real downstream project, use crates.io versions instead: -# buffa = { version = "0.5", features = ["json"] } -# buffa-types = { version = "0.5", features = ["json"] } +# buffa = { version = "0.6", features = ["json"] } +# buffa-types = { version = "0.6", features = ["json"] } # serde = { version = "1", features = ["derive"] } # serde_json = "1" buffa = { path = "../../buffa", features = ["json"] } diff --git a/protoc-gen-buffa-packaging/Cargo.toml b/protoc-gen-buffa-packaging/Cargo.toml index c05efb4..2ef3289 100644 --- a/protoc-gen-buffa-packaging/Cargo.toml +++ b/protoc-gen-buffa-packaging/Cargo.toml @@ -10,5 +10,5 @@ keywords = ["protobuf", "protocol-buffers", "protoc", "plugin", "codegen"] categories = ["development-tools::build-utils", "command-line-utilities"] [dependencies] -buffa = { path = "../buffa", version = "0.5.2" } +buffa = { path = "../buffa", version = "0.6.0" } buffa-codegen = { workspace = true } diff --git a/protoc-gen-buffa/Cargo.toml b/protoc-gen-buffa/Cargo.toml index 8d7b115..e82f08c 100644 --- a/protoc-gen-buffa/Cargo.toml +++ b/protoc-gen-buffa/Cargo.toml @@ -10,5 +10,5 @@ keywords = ["protobuf", "protocol-buffers", "protoc", "plugin", "codegen"] categories = ["development-tools::build-utils", "command-line-utilities"] [dependencies] -buffa = { path = "../buffa", version = "0.5.2" } +buffa = { path = "../buffa", version = "0.6.0" } buffa-codegen = { workspace = true }