[CI/Build][Rust Frontend] Publish vllm-proto on crates.io (#56365)
Co-authored-by: OpenAI Codex <noreply@openai.com> Co-authored-by: Bugen Zhao <i@bugenzhao.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Signed-off-by: Julien Darve <jdarve@NVIDIA.com> Signed-off-by: Bugen Zhao <i@bugenzhao.com>
JulienDarve committed
Sep 11, 2026 at 01:28 UTC
69db1c26b4fe4474ab4c9df1c9701efac8bedde1
10 files changed
+168
-16
.github/workflows/proto-crate.yml
new
+70
@@ -0,0 +1,70 @@
1
+name: Rust proto crate
2
+
3
+on:
4
+ pull_request:
5
+ paths:
6
+ - "rust/proto/**"
7
+ - "rust/Cargo.toml"
8
+ - "rust/Cargo.lock"
9
+ - "rust-toolchain.toml"
10
+ - ".github/workflows/proto-crate.yml"
11
+ push:
12
+ tags:
13
+ - "proto-v*"
14
+ workflow_dispatch:
15
+
16
+permissions:
17
+ contents: read
18
+
19
+concurrency:
20
+ group: ${{ github.workflow }}-${{ github.ref }}
21
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
22
+
23
+jobs:
24
+ semver:
25
+ runs-on: ubuntu-latest
26
+ steps:
27
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
28
+ - uses: obi1kenobi/cargo-semver-checks-action@6b69fcf40e9b5fb17adeb57e4b6ecd020649a239 # v2
29
+ with:
30
+ manifest-path: rust/proto/Cargo.toml
31
+ package: vllm-proto
32
+
33
+ check:
34
+ runs-on: ubuntu-latest
35
+ steps:
36
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
37
+ - run: rustup show active-toolchain
38
+ - name: Check release version
39
+ if: github.event_name == 'push'
40
+ run: |
41
+ version=$(cargo metadata --manifest-path rust/Cargo.toml --no-deps --format-version 1 |
42
+ jq -er '.packages[] | select(.name == "vllm-proto") | .version')
43
+ if [[ "$GITHUB_REF_NAME" != "proto-v$version" ]]; then
44
+ echo "Tag $GITHUB_REF_NAME does not match vllm-proto version $version" >&2
45
+ exit 1
46
+ fi
47
+ - name: Verify package
48
+ run: cargo publish --manifest-path rust/proto/Cargo.toml --locked --dry-run
49
+
50
+ publish:
51
+ needs: [check, semver]
52
+ if: github.repository == 'vllm-project/vllm' && github.event_name == 'push'
53
+ runs-on: ubuntu-latest
54
+ environment: crates-io
55
+ permissions:
56
+ contents: read
57
+ id-token: write
58
+ steps:
59
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
60
+ with:
61
+ ref: ${{ github.sha }}
62
+ - run: rustup show active-toolchain
63
+ - name: Verify package before authentication
64
+ run: cargo publish --manifest-path rust/proto/Cargo.toml --locked --dry-run
65
+ - uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 # v1.0.5
66
+ id: auth
67
+ - name: Publish
68
+ env:
69
+ CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
70
+ run: cargo publish --manifest-path rust/proto/Cargo.toml --locked
.pre-commit-config.yaml
+2
-2
@@ -285,7 +285,7 @@ repos:
285
pass_filenames: false
286
require_serial: true
287
stages: [pre-commit] # Only run locally as Buildkite will cover this
288
- files: ^rust/(Cargo\.toml|src/.*/Cargo\.toml)$
288
+ files: ^rust/(Cargo\.toml|proto/Cargo\.toml|src/.*/Cargo\.toml)$
289
- id: rust-cargo-sort
290
name: Rust - Sort Cargo manifest sections
291
entry: tools/pre_commit/rust-check.sh sort --workspace
@@ -293,7 +293,7 @@ repos:
293
pass_filenames: false
294
require_serial: true
295
stages: [pre-commit] # Only run locally as Buildkite will cover this
296
- files: ^rust/(Cargo\.toml|src/.*/Cargo\.toml)$
296
+ files: ^rust/(Cargo\.toml|proto/Cargo\.toml|src/.*/Cargo\.toml)$
297
- id: rust-cargo-fmt
298
name: Rust - Format code
299
entry: tools/pre_commit/rust-check.sh fmt
rust/Cargo.lock
+13
-4
@@ -5938,6 +5938,18 @@ dependencies = [
5938
"xgrammar-structural-tag",
5939
]
5940
5941
+[[package]]
5942
+name = "vllm-proto"
5943
+version = "0.1.0"
5944
+dependencies = [
5945
+ "prost",
5946
+ "prost-types",
5947
+ "protox",
5948
+ "tonic",
5949
+ "tonic-prost",
5950
+ "tonic-prost-build",
5951
+]
5952
+
5953
[[package]]
5954
name = "vllm-server"
5955
version = "0.1.0"
@@ -5960,9 +5972,7 @@ dependencies = [
5972
"libc",
5973
"llm-multimodal",
5974
"openssl",
5963
- "prost",
5975
"prost-types",
5965
- "protox",
5976
"rmp-serde",
5977
"rmpv",
5978
"serde",
@@ -5982,8 +5992,6 @@ dependencies = [
5992
"tokio-util",
5993
"tonic",
5994
"tonic-health",
5985
- "tonic-prost",
5986
- "tonic-prost-build",
5995
"tower",
5996
"tower-http",
5997
"tracing",
@@ -5997,6 +6005,7 @@ dependencies = [
6005
"vllm-engine-core-client",
6006
"vllm-llm",
6007
"vllm-metrics",
6008
+ "vllm-proto",
6009
"vllm-text",
6010
"vllm-tokenizer",
6011
"zeromq",
rust/Cargo.toml
+2
@@ -1,5 +1,6 @@
1
[workspace]
2
members = [
3
+ "proto",
4
"src/bench",
5
"src/build-info",
6
"src/chat",
@@ -146,6 +147,7 @@ vllm-llm = { path = "src/llm" }
147
vllm-managed-engine = { path = "src/managed-engine" }
148
vllm-metrics = { path = "src/metrics" }
149
vllm-parser = { path = "src/parser" }
150
+vllm-proto = { version = "0.1.0", path = "proto" }
151
vllm-server = { path = "src/server" }
152
vllm-text = { path = "src/text" }
153
vllm-tokenizer = { path = "src/tokenizer" }
rust/proto/Cargo.toml
new
+22
@@ -0,0 +1,22 @@
1
+[package]
2
+name = "vllm-proto"
3
+version = "0.1.0"
4
+edition.workspace = true
5
+license.workspace = true
6
+description = "Protobuf messages and gRPC bindings for the vLLM Rust frontend"
7
+repository = "https://github.com/vllm-project/vllm"
8
+readme = "README.md"
9
+include = ["*.proto", "src/**", "build.rs", "Cargo.toml", "README.md"]
10
+
11
+[dependencies]
12
+prost.workspace = true
13
+prost-types.workspace = true
14
+tonic.workspace = true
15
+tonic-prost.workspace = true
16
+
17
+[build-dependencies]
18
+protox.workspace = true
19
+tonic-prost-build.workspace = true
20
+
21
+[lints]
22
+workspace = true
rust/proto/README.md
+50
@@ -10,3 +10,53 @@ The schema is published to `buf.build/vllm-project/vllm`:
10
- Buf commits and generated SDK versions are immutable and can be pinned by consumers.
11
12
Repository setup requires a `BUF_TOKEN` GitHub Actions secret with permission to create and push the public Buf module. Register the Prost and Tonic generated SDKs for the `main` and `nightly` labels once so subsequent pushes generate them automatically.
13
+
14
+## Rust crate
15
+
16
+`vllm-proto` exposes the Prost message types and Tonic client and server modules for both APIs:
17
+
18
+```toml
19
+[dependencies]
20
+vllm-proto = "0.1"
21
+```
22
+
23
+For example, import `vllm_proto::inference_client::InferenceClient` or
24
+`vllm_proto::control_client::ControlClient`. The vLLM frontend uses this same crate.
25
+The package includes the canonical `.proto` files and generates bindings during
26
+compilation using `protox` and `tonic-prost-build`. Consumers do not need Buf
27
+credentials, the vLLM checkout, or a separately installed `protoc`.
28
+
29
+### Versioning and releases
30
+
31
+The crate has its own version in `Cargo.toml`, independent of the vLLM release
32
+number and the other Rust workspace crates. Release it when changes to the
33
+schema, generated Rust API, or dependencies require a new version. Review both
34
+Rust API and protobuf wire compatibility when choosing the version bump;
35
+a wire-compatible schema addition can still break Rust callers.
36
+
37
+On pull requests and releases, `cargo-semver-checks` compares the crate with its
38
+latest published version. Include any required version bump in the protocol
39
+change PR. This check becomes available after the first manual publication.
40
+
41
+1. Update the crate version and the `vllm-proto` workspace dependency together,
42
+ and update `rust/Cargo.lock`.
43
+2. Run `cargo publish --manifest-path rust/proto/Cargo.toml --locked --dry-run`
44
+ and the frontend gRPC tests. Record the tested vLLM releases or revisions in
45
+ the release notes; matching crate versions alone do not establish runtime compatibility.
46
+3. After the change merges, create a `proto-v<version>` tag on that commit.
47
+ The `proto-crate.yml` workflow checks that the tag matches the crate version,
48
+ verifies the package, and publishes it to crates.io.
49
+
50
+Use `proto-v*` tags so they do not trigger Buf's `v*` release workflow. There is
51
+no scheduled crate publication. Pull requests and manual workflow runs only
52
+verify packaging, including on forks. Retry a failed release by rerunning its
53
+tag workflow; crates.io versions cannot be overwritten.
54
+
55
+### Publisher setup
56
+
57
+A vLLM maintainer must publish the first version and establish the crate's owners.
58
+For subsequent releases, configure [crates.io Trusted Publishing](https://crates.io/docs/trusted-publishing)
59
+for repository `vllm-project/vllm`, workflow `proto-crate.yml`, and environment
60
+`crates-io`. Configure that GitHub environment to allow `proto-v*` release tags.
61
+Only tag pushes in the upstream repository can publish; forks do not obtain
62
+publishing credentials.
rust/proto/build.rs
renamed
+1
-1
@@ -3,7 +3,7 @@
3
4
fn main() -> Result<(), Box<dyn std::error::Error>> {
5
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
6
- let proto_dir = std::path::PathBuf::from(format!("{manifest_dir}/../../proto"));
6
+ let proto_dir = std::path::PathBuf::from(manifest_dir);
7
let protos = [
8
proto_dir.join("control.proto"),
9
proto_dir.join("inference.proto"),
rust/proto/src/lib.rs
new
+6
@@ -0,0 +1,6 @@
1
+// SPDX-License-Identifier: Apache-2.0
2
+// SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3
+
4
+//! Protobuf messages and gRPC clients and servers for vLLM's Inference and Control APIs.
5
+
6
+tonic::include_proto!("vllm");
rust/src/server/Cargo.toml
+1
-6
@@ -19,7 +19,6 @@ itertools.workspace = true
19
libc.workspace = true
20
llm-multimodal.workspace = true
21
openssl.workspace = true
22
-prost.workspace = true
22
prost-types.workspace = true
23
rmpv.workspace = true
24
serde.workspace = true
@@ -37,7 +36,6 @@ tokio-stream.workspace = true
36
tokio-util.workspace = true
37
tonic.workspace = true
38
tonic-health.workspace = true
40
-tonic-prost.workspace = true
39
tower.workspace = true
40
tower-http.workspace = true
41
tracing.workspace = true
@@ -51,12 +49,9 @@ vllm-chat.workspace = true
49
vllm-engine-core-client.workspace = true
50
vllm-llm.workspace = true
51
vllm-metrics.workspace = true
52
+vllm-proto.workspace = true
53
vllm-text.workspace = true
54
56
-[build-dependencies]
57
-protox.workspace = true
58
-tonic-prost-build.workspace = true
59
-
55
[dev-dependencies]
56
anyhow.workspace = true
57
async-openai = { workspace = true, features = ["full"] }
rust/src/server/src/grpc/mod.rs
+1
-3
@@ -9,9 +9,7 @@ mod health;
9
mod inference;
10
11
/// Generated protobuf/gRPC types for the `vllm` package.
12
-pub mod pb {
13
- tonic::include_proto!("vllm");
14
-}
12
+pub use vllm_proto as pb;
13
14
pub(crate) use control::ControlGrpcService;
15
pub use control::ControlServiceImpl;