[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:
co-authored by
OpenAI Codex
Bugen Zhao
mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
parent
e3f755b732
commit
69db1c26b4
@@ -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
|
||||
@@ -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
|
||||
|
||||
Generated
+13
-4
@@ -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",
|
||||
|
||||
@@ -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" }
|
||||
|
||||
@@ -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
|
||||
@@ -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"),
|
||||
@@ -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");
|
||||
@@ -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"] }
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user