[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>
This commit is contained in:
JulienDarve
2026-09-11 16:28:52 +08:00
committed by GitHub
co-authored by OpenAI Codex Bugen Zhao mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
parent e3f755b732
commit 69db1c26b4
10 changed files with 168 additions and 16 deletions
+70
View File
@@ -0,0 +1,70 @@
name: Rust proto crate
on:
pull_request:
paths:
- "rust/proto/**"
- "rust/Cargo.toml"
- "rust/Cargo.lock"
- "rust-toolchain.toml"
- ".github/workflows/proto-crate.yml"
push:
tags:
- "proto-v*"
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
semver:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: obi1kenobi/cargo-semver-checks-action@6b69fcf40e9b5fb17adeb57e4b6ecd020649a239 # v2
with:
manifest-path: rust/proto/Cargo.toml
package: vllm-proto
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- run: rustup show active-toolchain
- name: Check release version
if: github.event_name == 'push'
run: |
version=$(cargo metadata --manifest-path rust/Cargo.toml --no-deps --format-version 1 |
jq -er '.packages[] | select(.name == "vllm-proto") | .version')
if [[ "$GITHUB_REF_NAME" != "proto-v$version" ]]; then
echo "Tag $GITHUB_REF_NAME does not match vllm-proto version $version" >&2
exit 1
fi
- name: Verify package
run: cargo publish --manifest-path rust/proto/Cargo.toml --locked --dry-run
publish:
needs: [check, semver]
if: github.repository == 'vllm-project/vllm' && github.event_name == 'push'
runs-on: ubuntu-latest
environment: crates-io
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: ${{ github.sha }}
- run: rustup show active-toolchain
- name: Verify package before authentication
run: cargo publish --manifest-path rust/proto/Cargo.toml --locked --dry-run
- uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 # v1.0.5
id: auth
- name: Publish
env:
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
run: cargo publish --manifest-path rust/proto/Cargo.toml --locked
+2 -2
View File
@@ -285,7 +285,7 @@ repos:
pass_filenames: false
require_serial: true
stages: [pre-commit] # Only run locally as Buildkite will cover this
files: ^rust/(Cargo\.toml|src/.*/Cargo\.toml)$
files: ^rust/(Cargo\.toml|proto/Cargo\.toml|src/.*/Cargo\.toml)$
- id: rust-cargo-sort
name: Rust - Sort Cargo manifest sections
entry: tools/pre_commit/rust-check.sh sort --workspace
@@ -293,7 +293,7 @@ repos:
pass_filenames: false
require_serial: true
stages: [pre-commit] # Only run locally as Buildkite will cover this
files: ^rust/(Cargo\.toml|src/.*/Cargo\.toml)$
files: ^rust/(Cargo\.toml|proto/Cargo\.toml|src/.*/Cargo\.toml)$
- id: rust-cargo-fmt
name: Rust - Format code
entry: tools/pre_commit/rust-check.sh fmt
+13 -4
View File
@@ -5938,6 +5938,18 @@ dependencies = [
"xgrammar-structural-tag",
]
[[package]]
name = "vllm-proto"
version = "0.1.0"
dependencies = [
"prost",
"prost-types",
"protox",
"tonic",
"tonic-prost",
"tonic-prost-build",
]
[[package]]
name = "vllm-server"
version = "0.1.0"
@@ -5960,9 +5972,7 @@ dependencies = [
"libc",
"llm-multimodal",
"openssl",
"prost",
"prost-types",
"protox",
"rmp-serde",
"rmpv",
"serde",
@@ -5982,8 +5992,6 @@ dependencies = [
"tokio-util",
"tonic",
"tonic-health",
"tonic-prost",
"tonic-prost-build",
"tower",
"tower-http",
"tracing",
@@ -5997,6 +6005,7 @@ dependencies = [
"vllm-engine-core-client",
"vllm-llm",
"vllm-metrics",
"vllm-proto",
"vllm-text",
"vllm-tokenizer",
"zeromq",
+2
View File
@@ -1,5 +1,6 @@
[workspace]
members = [
"proto",
"src/bench",
"src/build-info",
"src/chat",
@@ -146,6 +147,7 @@ vllm-llm = { path = "src/llm" }
vllm-managed-engine = { path = "src/managed-engine" }
vllm-metrics = { path = "src/metrics" }
vllm-parser = { path = "src/parser" }
vllm-proto = { version = "0.1.0", path = "proto" }
vllm-server = { path = "src/server" }
vllm-text = { path = "src/text" }
vllm-tokenizer = { path = "src/tokenizer" }
+22
View File
@@ -0,0 +1,22 @@
[package]
name = "vllm-proto"
version = "0.1.0"
edition.workspace = true
license.workspace = true
description = "Protobuf messages and gRPC bindings for the vLLM Rust frontend"
repository = "https://github.com/vllm-project/vllm"
readme = "README.md"
include = ["*.proto", "src/**", "build.rs", "Cargo.toml", "README.md"]
[dependencies]
prost.workspace = true
prost-types.workspace = true
tonic.workspace = true
tonic-prost.workspace = true
[build-dependencies]
protox.workspace = true
tonic-prost-build.workspace = true
[lints]
workspace = true
+50
View File
@@ -10,3 +10,53 @@ The schema is published to `buf.build/vllm-project/vllm`:
- Buf commits and generated SDK versions are immutable and can be pinned by consumers.
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.
## Rust crate
`vllm-proto` exposes the Prost message types and Tonic client and server modules for both APIs:
```toml
[dependencies]
vllm-proto = "0.1"
```
For example, import `vllm_proto::inference_client::InferenceClient` or
`vllm_proto::control_client::ControlClient`. The vLLM frontend uses this same crate.
The package includes the canonical `.proto` files and generates bindings during
compilation using `protox` and `tonic-prost-build`. Consumers do not need Buf
credentials, the vLLM checkout, or a separately installed `protoc`.
### Versioning and releases
The crate has its own version in `Cargo.toml`, independent of the vLLM release
number and the other Rust workspace crates. Release it when changes to the
schema, generated Rust API, or dependencies require a new version. Review both
Rust API and protobuf wire compatibility when choosing the version bump;
a wire-compatible schema addition can still break Rust callers.
On pull requests and releases, `cargo-semver-checks` compares the crate with its
latest published version. Include any required version bump in the protocol
change PR. This check becomes available after the first manual publication.
1. Update the crate version and the `vllm-proto` workspace dependency together,
and update `rust/Cargo.lock`.
2. Run `cargo publish --manifest-path rust/proto/Cargo.toml --locked --dry-run`
and the frontend gRPC tests. Record the tested vLLM releases or revisions in
the release notes; matching crate versions alone do not establish runtime compatibility.
3. After the change merges, create a `proto-v<version>` tag on that commit.
The `proto-crate.yml` workflow checks that the tag matches the crate version,
verifies the package, and publishes it to crates.io.
Use `proto-v*` tags so they do not trigger Buf's `v*` release workflow. There is
no scheduled crate publication. Pull requests and manual workflow runs only
verify packaging, including on forks. Retry a failed release by rerunning its
tag workflow; crates.io versions cannot be overwritten.
### Publisher setup
A vLLM maintainer must publish the first version and establish the crate's owners.
For subsequent releases, configure [crates.io Trusted Publishing](https://crates.io/docs/trusted-publishing)
for repository `vllm-project/vllm`, workflow `proto-crate.yml`, and environment
`crates-io`. Configure that GitHub environment to allow `proto-v*` release tags.
Only tag pushes in the upstream repository can publish; forks do not obtain
publishing credentials.
@@ -3,7 +3,7 @@
fn main() -> Result<(), Box<dyn std::error::Error>> {
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
let proto_dir = std::path::PathBuf::from(format!("{manifest_dir}/../../proto"));
let proto_dir = std::path::PathBuf::from(manifest_dir);
let protos = [
proto_dir.join("control.proto"),
proto_dir.join("inference.proto"),
+6
View File
@@ -0,0 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Copyright contributors to the vLLM project
//! Protobuf messages and gRPC clients and servers for vLLM's Inference and Control APIs.
tonic::include_proto!("vllm");
+1 -6
View File
@@ -19,7 +19,6 @@ itertools.workspace = true
libc.workspace = true
llm-multimodal.workspace = true
openssl.workspace = true
prost.workspace = true
prost-types.workspace = true
rmpv.workspace = true
serde.workspace = true
@@ -37,7 +36,6 @@ tokio-stream.workspace = true
tokio-util.workspace = true
tonic.workspace = true
tonic-health.workspace = true
tonic-prost.workspace = true
tower.workspace = true
tower-http.workspace = true
tracing.workspace = true
@@ -51,12 +49,9 @@ vllm-chat.workspace = true
vllm-engine-core-client.workspace = true
vllm-llm.workspace = true
vllm-metrics.workspace = true
vllm-proto.workspace = true
vllm-text.workspace = true
[build-dependencies]
protox.workspace = true
tonic-prost-build.workspace = true
[dev-dependencies]
anyhow.workspace = true
async-openai = { workspace = true, features = ["full"] }
+1 -3
View File
@@ -9,9 +9,7 @@ mod health;
mod inference;
/// Generated protobuf/gRPC types for the `vllm` package.
pub mod pb {
tonic::include_proto!("vllm");
}
pub use vllm_proto as pb;
pub(crate) use control::ControlGrpcService;
pub use control::ControlServiceImpl;