[Build] Propagate vLLM version to Rust binaries (#52593)

Signed-off-by: Bugen Zhao <i@bugenzhao.com> Co-authored-by: Nick Hill <nickhill123@gmail.com> Co-authored-by: Andreas Karatzas <akaratza@amd.com>

Bugen Zhao committed Aug 18, 2026 at 16:37 UTC c89d692cb5fa430ddca06a9e16682977a18b55dc
24 files changed +135 -39
.buildkite/scripts/ci-bake-rocm.sh
+4 -4
@@ -23,8 +23,8 @@ DEFAULT_CI_BASE_METADATA_VERSION="3"
23 # local-source stages rather than unreachable remote-fetch alternatives.
24 DEFAULT_ROCM_CSRC_CONTENT_FILES=".dockerignore requirements/common.txt requirements/rocm.txt pyproject.toml setup.py CMakeLists.txt cmake csrc vllm/envs.py vllm/__init__.py tools/build_rust.py"
25 DEFAULT_ROCM_CSRC_DOCKERFILE_STAGES="base fetch_vllm_0 fetch_vllm build_vllm_dependencies rocm-triton-kernels csrc-build"
26 -DEFAULT_ROCM_RUST_CONTENT_FILES=".dockerignore requirements/build/rust.txt rust/Cargo.lock rust/Cargo.toml rust/proto rust/src rust-toolchain.toml tools/build_rust.py tools/install_protoc.sh build_rust.sh"
27 -DEFAULT_ROCM_RUST_DOCKERFILE_STAGES="base rust_toolchain_input_0 rust-toolchain-input rust_input_0 rust-input rust-toolchain rust-build"
26 +DEFAULT_ROCM_RUST_CONTENT_FILES=".dockerignore .git_archival.txt pyproject.toml requirements/build/rust.txt rust/Cargo.lock rust/Cargo.toml rust/proto rust/src rust-toolchain.toml tools/build_rust.py tools/install_protoc.sh build_rust.sh"
27 +DEFAULT_ROCM_RUST_DOCKERFILE_STAGES="base fetch_vllm_0 fetch_vllm vllm-version rust_toolchain_input_0 rust-toolchain-input rust_input_0 rust-input rust-toolchain rust-build"
28 # Docker's 128-character tag limit minus the longest cache prefix
29 # ("csrc-rocm-branch-" and "rust-rocm-branch-", both 17 characters).
30 ROCM_CACHE_BRANCH_TAG_MAX_LEN=111
@@ -523,8 +523,8 @@ prepare_ci_build_context() {
523 return 1
524 fi
525
526 - # setuptools-scm understands Git's stable archive format, so full-source
527 - # wheels retain their exact version without copying mutable Git history.
526 + # setuptools-scm understands Git's stable archive format, so wheels and
527 + # Rust artifacts retain their exact version without copying Git history.
528 if ! is_ci_base_target; then
529 write_ci_git_archival_metadata "${source_root}" "${context_root}" \
530 || return $?
.buildkite/test-amd.yaml
+1 -1
@@ -2356,7 +2356,7 @@ steps:
2356 - export VLLM_USE_RUST_FRONTEND=1
2357 - export VLLM_WORKER_MULTIPROC_METHOD=spawn
2358 - PYTHONPATH=/vllm-workspace pytest -v -s entrypoints/serve/dev/rpc/test_collective_rpc.py
2359 - - pytest -v -s entrypoints/serve/instrumentator/test_basic.py -k "not show_version and not server_load"
2359 + - pytest -v -s entrypoints/serve/instrumentator/test_basic.py -k "not server_load"
2360 - pytest -v -s entrypoints/scale_out/token_in_token_out/test_serving_tokens.py -k "not stream and not lora and not test_generate_logprobs and not stop_string_workflow"
2361 - pytest -v -s entrypoints/serve/instrumentator/test_metrics.py -k "text and not show and not run_batch and not test_metrics_counts and not test_metrics_exist"
2362 - pytest -v -s entrypoints/serve/tokenize/test_tokenization.py -k "not tokenizer_info"
.buildkite/test_areas/rust_frontend.yaml
+1 -1
@@ -58,7 +58,7 @@ steps:
58 - export VLLM_WORKER_MULTIPROC_METHOD=spawn
59 - PYTHONPATH=/vllm-workspace pytest -v -s entrypoints/serve/dev/rpc/test_collective_rpc.py
60 # server_load can be flaky under the Rust frontend; keep it excluded for now.
61 - - pytest -v -s entrypoints/serve/instrumentator/test_basic.py -k "not show_version and not server_load"
61 + - pytest -v -s entrypoints/serve/instrumentator/test_basic.py -k "not server_load"
62 # test_generate_logprobs expects Python-style top_logprobs truncation (dedup sampled + cap at max(k, 1)).
63 - pytest -v -s entrypoints/scale_out/token_in_token_out/test_serving_tokens.py -k "not stream and not lora and not test_generate_logprobs and not stop_string_workflow"
64 - pytest -v -s entrypoints/serve/instrumentator/test_metrics.py -k "text and not show and not run_batch and not test_metrics_counts and not test_metrics_exist"
docker/Dockerfile
+5
@@ -279,11 +279,16 @@ ENV CARGO_BUILD_JOBS=4
279 # separate local sccache daemon while sharing the same remote cache backend.
280 ENV SCCACHE_SERVER_PORT=4227
281
282 +# Only Rust inputs are present, so suppress the artificial dirty state caused
283 +# by other tracked files being absent from this build stage.
284 +ENV SETUPTOOLS_SCM_PRETEND_METADATA={dirty=false}
285 +
286 # Build the release artifacts. Cache cargo registry/git, but not target/,
287 # because stale target metadata can outlive source updates across BuildKit
288 # cache reuse.
289 RUN --mount=type=cache,target=/root/.cargo/registry,sharing=locked \
290 --mount=type=cache,target=/root/.cargo/git,sharing=locked \
291 + --mount=type=bind,source=.git,target=.git \
292 --mount=type=secret,id=aws-credentials,target=/root/.aws/credentials,required=false \
293 if [ "$USE_SCCACHE" = "1" ]; then \
294 if [ -n "${SCCACHE_ENDPOINT}" ]; then export SCCACHE_ENDPOINT="${SCCACHE_ENDPOINT}"; fi; \
docker/Dockerfile.cpu
+5
@@ -166,11 +166,16 @@ COPY build_rust.sh build_rust.sh
166 # (rustc spawns enough concurrent processes to hit RLIMIT_NOFILE otherwise).
167 ENV CARGO_BUILD_JOBS=4
168
169 +# Only Rust inputs are present, so suppress the artificial dirty state caused
170 +# by other tracked files being absent from this build stage.
171 +ENV SETUPTOOLS_SCM_PRETEND_METADATA={dirty=false}
172 +
173 # Build the release artifacts. Cache cargo registry/git, but not target/,
174 # because stale target metadata can outlive source updates across BuildKit
175 # cache reuse.
176 RUN --mount=type=cache,target=/root/.cargo/registry,sharing=locked \
177 --mount=type=cache,target=/root/.cargo/git,sharing=locked \
178 + --mount=type=bind,source=.git,target=.git \
179 --mount=type=secret,id=aws-credentials,target=/root/.aws/credentials,required=false \
180 if [ "$USE_SCCACHE" = "1" ]; then \
181 export RUSTC_WRAPPER=sccache; \
docker/Dockerfile.rocm
+23 -12
@@ -125,6 +125,18 @@ ONBUILD RUN git clone ${VLLM_REPO} \
125 && git fetch upstream ; fi
126 FROM fetch_vllm_${REMOTE_VLLM} AS fetch_vllm
127
128 +# Resolve the device-independent source version once for every downstream
129 +# artifact. setuptools-scm reads Git metadata for local/remote sources and the
130 +# archive metadata generated for canonical CI contexts.
131 +FROM fetch_vllm AS vllm-version
132 +ARG COMMON_WORKDIR
133 +RUN --mount=type=cache,id=vllm-rocm-uv,target=/root/.cache/uv \
134 + cd ${COMMON_WORKDIR}/vllm \
135 + && uv pip install --system -r requirements/build/rust.txt \
136 + && python3 -c \
137 + "from setuptools_scm import get_version; print(get_version())" \
138 + > /vllm-version.txt
139 +
140 # -----------------------
141 # Rust/protoc toolchain inputs
142 #
@@ -238,6 +250,7 @@ COPY --from=rust-input /rust-input/vllm/rust rust
250 COPY --from=rust-input /rust-input/vllm/rust-toolchain.toml rust-toolchain.toml
251 COPY --from=rust-input /rust-input/vllm/tools/build_rust.py tools/build_rust.py
252 COPY --from=rust-input /rust-input/vllm/build_rust.sh build_rust.sh
253 +COPY --from=vllm-version /vllm-version.txt /tmp/vllm-version.txt
254
255 # Build the release binary. Cargo's registry/git caches can be written by
256 # concurrent BuildKit jobs on shared workers, so lock those cache mounts while
@@ -249,6 +262,7 @@ RUN --mount=type=cache,id=vllm-rocm-cargo-registry,target=/root/.cargo/registry,
262 export RUSTC_WRAPPER=sccache \
263 && sccache --show-stats; \
264 fi \
265 + && export SETUPTOOLS_SCM_PRETEND_VERSION="$(cat /tmp/vllm-version.txt)" \
266 && bash build_rust.sh \
267 && test -x vllm/vllm-rs \
268 && if [ "$USE_SCCACHE" = "1" ]; then \
@@ -334,6 +348,7 @@ RUN --mount=type=bind,source=pyproject.toml,target=${COMMON_WORKDIR}/vllm/pyproj
348 FROM build_vllm_dependencies AS build_vllm
349 COPY --from=fetch_vllm ${COMMON_WORKDIR}/vllm ${COMMON_WORKDIR}/vllm
350 COPY --from=csrc-build ${COMMON_WORKDIR}/vllm/dist /precompiled-wheels
351 +COPY --from=vllm-version /vllm-version.txt /tmp/vllm-version.txt
352
353 # Drop the pre-built Rust artifacts into the source tree. setup.py detects
354 # them and ships them as-is, skipping the local Rust build.
@@ -341,6 +356,7 @@ COPY --from=rust-build ${COMMON_WORKDIR}/vllm/vllm/vllm-rs ${COMMON_WORKDIR}/vll
356 COPY --from=rust-build ${COMMON_WORKDIR}/vllm/vllm/_rust_*.so ${COMMON_WORKDIR}/vllm/vllm/
357
358 RUN cd "${COMMON_WORKDIR}/vllm" \
359 + && export SETUPTOOLS_SCM_PRETEND_VERSION="$(cat /tmp/vllm-version.txt)" \
360 && export VLLM_USE_PRECOMPILED=1 \
361 && export VLLM_PRECOMPILED_WHEEL_LOCATION="$(ls /precompiled-wheels/*.whl)" \
362 && export VLLM_DOCKER_BUILD_CONTEXT=1 \
@@ -640,6 +656,7 @@ FROM fetch_vllm AS build_vllm_wheel_release
656
657 ARG COMMON_WORKDIR
658 ARG ROCM_TRITON_KERNELS_COMMIT
659 +COPY --from=vllm-version /vllm-version.txt /tmp/vllm-version.txt
660 COPY --from=rocm-triton-kernels \
661 /opt/rocm-triton-kernels /opt/rocm-triton-kernels
662 ENV TRITON_KERNELS_SRC_DIR=/opt/rocm-triton-kernels
@@ -678,17 +695,12 @@ RUN if [ "$GIT_REPO_CHECK" != "0" ]; then \
695 cd vllm && bash tools/check_repo.sh; \
696 fi
697
681 -# Extract version from git BEFORE any modifications (pin_rocm_dependencies.py modifies requirements/rocm.txt)
682 -# This ensures setuptools_scm sees clean repo state for version detection
683 -RUN --mount=type=bind,source=.git,target=vllm/.git \
684 - --mount=type=cache,target=/root/.cache/uv \
698 +# Install the packaging helpers before modifying requirements/rocm.txt.
699 +RUN --mount=type=cache,target=/root/.cache/uv \
700 grep -Fq "set(TRITON_KERNELS_TAG \"${ROCM_TRITON_KERNELS_COMMIT}\")" \
701 vllm/cmake/external_projects/triton_kernels.cmake \
702 && cd vllm \
688 - && uv pip install --system setuptools_scm regex \
689 - && VLLM_VERSION=$(python3 -c "import setuptools_scm; print(setuptools_scm.get_version())") \
690 - && echo "Detected vLLM version: ${VLLM_VERSION}" \
691 - && echo "${VLLM_VERSION}" > /tmp/vllm_version.txt
703 + && uv pip install --system setuptools_scm regex
704
705 # Fail if git-based package dependencies are found in requirements files
706 # (uv doesn't handle git+ URLs well, and packages should be distributed on PyPI)
@@ -726,13 +738,12 @@ RUN --mount=type=cache,target=/root/.cache/uv \
738 && echo "Building vLLM with custom wheels from /install" \
739 && uv pip install --system --find-links /install -r requirements/rocm.txt
740
729 -# Build wheel using pre-extracted version to avoid dirty state from modified requirements/rocm.txt
741 +# Build wheel using the shared source version to avoid dirty state from modified requirements/rocm.txt
742 # (setup.py auto-detects ccache/sccache in PATH)
731 -RUN --mount=type=bind,source=.git,target=vllm/.git \
732 - --mount=type=cache,id=vllm-rocm-ccache,target=/root/.cache/ccache \
743 +RUN --mount=type=cache,id=vllm-rocm-ccache,target=/root/.cache/ccache \
744 cd vllm \
745 && export CCACHE_BASEDIR="$PWD" \
735 - && export SETUPTOOLS_SCM_PRETEND_VERSION=$(cat /tmp/vllm_version.txt) \
746 + && export SETUPTOOLS_SCM_PRETEND_VERSION="$(cat /tmp/vllm-version.txt)" \
747 && echo "Building wheel with version: ${SETUPTOOLS_SCM_PRETEND_VERSION}" \
748 && MAX_JOBS="${MAX_JOBS:-$(nproc)}" python3 setup.py bdist_wheel --dist-dir=dist
749
docker/Dockerfile.rocm_gfx1250
+23 -12
@@ -127,6 +127,17 @@ ONBUILD RUN git clone ${VLLM_REPO} \
127 && git fetch upstream ; fi
128 FROM fetch_vllm_${REMOTE_VLLM} AS fetch_vllm
129
130 +# Resolve the device-independent source version once for every downstream
131 +# artifact. setuptools-scm reads Git metadata from local and remote sources.
132 +FROM fetch_vllm AS vllm-version
133 +ARG COMMON_WORKDIR
134 +RUN --mount=type=cache,id=vllm-rocm-uv,target=/root/.cache/uv \
135 + cd ${COMMON_WORKDIR}/vllm \
136 + && uv pip install --system -r requirements/build/rust.txt \
137 + && python3 -c \
138 + "from setuptools_scm import get_version; print(get_version())" \
139 + > /vllm-version.txt
140 +
141 # -----------------------
142 # Rust build stage
143 # Builds the `vllm-rs` frontend in a dedicated stage so the wheel build stages
@@ -152,6 +163,8 @@ RUN --mount=type=cache,id=vllm-rocm-uv,target=/root/.cache/uv \
163 cd ${COMMON_WORKDIR}/vllm \
164 && uv pip install --system -r requirements/build/rust.txt
165
166 +COPY --from=vllm-version /vllm-version.txt /tmp/vllm-version.txt
167 +
168 # Build the release binary. Cargo's registry/git caches can be written by
169 # concurrent BuildKit jobs on shared workers, so lock those cache mounts while
170 # keeping the cache benefit. Do not cache target/, because stale target metadata
@@ -159,6 +172,7 @@ RUN --mount=type=cache,id=vllm-rocm-uv,target=/root/.cache/uv \
172 RUN --mount=type=cache,id=vllm-rocm-cargo-registry,target=/root/.cargo/registry,sharing=locked \
173 --mount=type=cache,id=vllm-rocm-cargo-git,target=/root/.cargo/git,sharing=locked \
174 cd ${COMMON_WORKDIR}/vllm \
175 + && export SETUPTOOLS_SCM_PRETEND_VERSION="$(cat /tmp/vllm-version.txt)" \
176 && bash build_rust.sh \
177 && test -x vllm/vllm-rs
178
@@ -211,6 +225,7 @@ ARG COMMON_WORKDIR
225 ENV VLLM_TARGET_DEVICE=rocm
226
227 COPY --from=csrc-build ${COMMON_WORKDIR}/vllm/dist /precompiled-wheels
228 +COPY --from=vllm-version /vllm-version.txt /tmp/vllm-version.txt
229
230 # Drop the pre-built Rust artifacts into the source tree. setup.py detects
231 # them and ships them as-is, skipping the local Rust build.
@@ -220,6 +235,7 @@ COPY --from=rust-build ${COMMON_WORKDIR}/vllm/vllm/_rust_*.so ${COMMON_WORKDIR}/
235 RUN --mount=type=cache,id=vllm-rocm-uv,target=/root/.cache/uv \
236 cd vllm \
237 && uv pip install --system -r requirements/rocm.txt \
238 + && export SETUPTOOLS_SCM_PRETEND_VERSION="$(cat /tmp/vllm-version.txt)" \
239 && export VLLM_USE_PRECOMPILED=1 \
240 && export VLLM_PRECOMPILED_WHEEL_LOCATION="$(ls /precompiled-wheels/*.whl)" \
241 && export VLLM_DOCKER_BUILD_CONTEXT=1 \
@@ -426,6 +442,7 @@ RUN /bin/bash -lc 'set -euo pipefail; \
442 FROM fetch_vllm AS build_vllm_wheel_release
443
444 ARG COMMON_WORKDIR
445 +COPY --from=vllm-version /vllm-version.txt /tmp/vllm-version.txt
446
447 # Drop the pre-built Rust artifacts into the source tree. setup.py detects
448 # them and ships them as-is, skipping the local Rust build.
@@ -461,15 +478,10 @@ RUN if [ "$GIT_REPO_CHECK" != "0" ]; then \
478 cd vllm && bash tools/check_repo.sh; \
479 fi
480
464 -# Extract version from git BEFORE any modifications (pin_rocm_dependencies.py modifies requirements/rocm.txt)
465 -# This ensures setuptools_scm sees clean repo state for version detection
466 -RUN --mount=type=bind,source=.git,target=vllm/.git \
467 - --mount=type=cache,target=/root/.cache/uv \
481 +# Install the packaging helpers before modifying requirements/rocm.txt.
482 +RUN --mount=type=cache,target=/root/.cache/uv \
483 cd vllm \
469 - && uv pip install --system setuptools_scm regex \
470 - && VLLM_VERSION=$(python3 -c "import setuptools_scm; print(setuptools_scm.get_version())") \
471 - && echo "Detected vLLM version: ${VLLM_VERSION}" \
472 - && echo "${VLLM_VERSION}" > /tmp/vllm_version.txt
484 + && uv pip install --system setuptools_scm regex
485
486 # Fail if git-based package dependencies are found in requirements files
487 # (uv doesn't handle git+ URLs well, and packages should be distributed on PyPI)
@@ -507,13 +519,12 @@ RUN --mount=type=cache,target=/root/.cache/uv \
519 && echo "Building vLLM with custom wheels from /install" \
520 && uv pip install --system --find-links /install -r requirements/rocm.txt
521
510 -# Build wheel using pre-extracted version to avoid dirty state from modified requirements/rocm.txt
522 +# Build wheel using the shared source version to avoid dirty state from modified requirements/rocm.txt
523 # (setup.py auto-detects ccache/sccache in PATH)
512 -RUN --mount=type=bind,source=.git,target=vllm/.git \
513 - --mount=type=cache,id=vllm-rocm-ccache,target=/root/.cache/ccache \
524 +RUN --mount=type=cache,id=vllm-rocm-ccache,target=/root/.cache/ccache \
525 cd vllm \
526 && export CCACHE_BASEDIR="$PWD" \
516 - && export SETUPTOOLS_SCM_PRETEND_VERSION=$(cat /tmp/vllm_version.txt) \
527 + && export SETUPTOOLS_SCM_PRETEND_VERSION="$(cat /tmp/vllm-version.txt)" \
528 && echo "Building wheel with version: ${SETUPTOOLS_SCM_PRETEND_VERSION}" \
529 && MAX_JOBS="${MAX_JOBS:-$(nproc)}" python3 setup.py bdist_wheel --dist-dir=dist
530
docker/Dockerfile.xpu
+5
@@ -28,8 +28,13 @@ COPY build_rust.sh build_rust.sh
28 # (rustc spawns enough concurrent processes to hit RLIMIT_NOFILE otherwise).
29 ENV CARGO_BUILD_JOBS=4
30
31 +# Only Rust inputs are present, so suppress the artificial dirty state caused
32 +# by other tracked files being absent from this build stage.
33 +ENV SETUPTOOLS_SCM_PRETEND_METADATA={dirty=false}
34 +
35 RUN --mount=type=cache,target=/root/.cargo/registry,sharing=locked \
36 --mount=type=cache,target=/root/.cargo/git,sharing=locked \
37 + --mount=type=bind,source=.git,target=.git \
38 bash build_rust.sh
39
40 FROM ubuntu:24.04 AS vllm-base
requirements/build/rust.txt
+1
@@ -1,4 +1,5 @@
1 # Dependencies for building Rust artifacts through setuptools-rust.
2 setuptools>=77.0.3,<81.0.0
3 +setuptools-scm>=9.2.0
4 setuptools-rust>=1.9.0
5 wheel
rust/Cargo.lock
+7
@@ -5505,9 +5505,14 @@ dependencies = [
5505 "tracing",
5506 "url",
5507 "uuid",
5508 + "vllm-build-info",
5509 "vllm-tracing",
5510 ]
5511
5512 +[[package]]
5513 +name = "vllm-build-info"
5514 +version = "0.1.0"
5515 +
5516 [[package]]
5517 name = "vllm-chat"
5518 version = "0.1.0"
@@ -5574,6 +5579,7 @@ dependencies = [
5579 "tracing",
5580 "uuid",
5581 "vllm-bench",
5582 + "vllm-build-info",
5583 "vllm-chat",
5584 "vllm-engine-core-client",
5585 "vllm-managed-engine",
@@ -5755,6 +5761,7 @@ dependencies = [
5761 "url",
5762 "uuid",
5763 "validator",
5764 + "vllm-build-info",
5765 "vllm-chat",
5766 "vllm-engine-core-client",
5767 "vllm-llm",
rust/Cargo.toml
+2
@@ -1,6 +1,7 @@
1 [workspace]
2 members = [
3 "src/bench",
4 + "src/build-info",
5 "src/chat",
6 "src/cmd",
7 "src/engine-core-client",
@@ -135,6 +136,7 @@ url = "2.5.7"
136 uuid = { version = "1.22.0", features = ["v4"] }
137 validator = { version = "0.20.0", features = ["derive"] }
138 vllm-bench = { path = "src/bench" }
139 +vllm-build-info = { path = "src/build-info" }
140 vllm-chat = { path = "src/chat" }
141 vllm-engine-core-client = { path = "src/engine-core-client" }
142 vllm-llm = { path = "src/llm" }
rust/src/bench/Cargo.toml
+1
@@ -34,6 +34,7 @@ tokio-stream.workspace = true
34 tracing.workspace = true
35 url.workspace = true
36 uuid.workspace = true
37 +vllm-build-info.workspace = true
38 vllm-tracing.workspace = true
39
40 [lints]
rust/src/bench/src/main.rs
+1 -1
@@ -12,7 +12,7 @@ use clap::Parser;
12 #[command(
13 name = "vllm-bench",
14 about = "Benchmark online serving throughput",
15 - version
15 + version = vllm_build_info::VERSION
16 )]
17 struct Cli {
18 #[command(flatten)]
rust/src/build-info/Cargo.toml new
+8
@@ -0,0 +1,8 @@
1 +[package]
2 +name = "vllm-build-info"
3 +version.workspace = true
4 +edition.workspace = true
5 +license.workspace = true
6 +
7 +[lints]
8 +workspace = true
rust/src/build-info/src/lib.rs new
+10
@@ -0,0 +1,10 @@
1 +// SPDX-License-Identifier: Apache-2.0
2 +// SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 +
4 +/// The vLLM package version supplied by the build system.
5 +///
6 +/// Direct Cargo builds fall back to the internal crate version.
7 +pub const VERSION: &str = match option_env!("VLLM_RS_BUILD_VERSION") {
8 + Some(version) => version,
9 + None => env!("CARGO_PKG_VERSION"),
10 +};
rust/src/cmd/Cargo.toml
+1
@@ -28,6 +28,7 @@ tokio-util.workspace = true
28 tracing.workspace = true
29 uuid.workspace = true
30 vllm-bench.workspace = true
31 +vllm-build-info.workspace = true
32 vllm-chat.workspace = true
33 vllm-engine-core-client.workspace = true
34 vllm-managed-engine.workspace = true
rust/src/cmd/src/cli.rs
+2 -1
@@ -39,7 +39,8 @@ use crate::cli::unsupported::UnsupportedArgs;
39 #[derive(Debug, Parser)]
40 #[command(
41 name = "vllm-rs",
42 - about = "Rust frontend and managed-engine CLI for vLLM."
42 + about = "Rust frontend and managed-engine CLI for vLLM.",
43 + version = vllm_build_info::VERSION
44 )]
45 pub struct Cli {
46 #[command(subcommand)]
rust/src/server/Cargo.toml
+1
@@ -45,6 +45,7 @@ tracing-subscriber.workspace = true
45 url.workspace = true
46 uuid.workspace = true
47 validator.workspace = true
48 +vllm-build-info.workspace = true
49 vllm-chat.workspace = true
50 vllm-engine-core-client.workspace = true
51 vllm-llm.workspace = true
rust/src/server/src/routes/tests.rs
+1 -1
@@ -1746,7 +1746,7 @@ async fn version_returns_engine_vllm_version() {
1746 json,
1747 json!({
1748 "version": "test-vllm-version",
1749 - "rust_frontend_version": env!("CARGO_PKG_VERSION"),
1749 + "rust_frontend_version": vllm_build_info::VERSION,
1750 })
1751 );
1752 }
rust/src/server/src/routes/version.rs
+1 -1
@@ -21,6 +21,6 @@ pub async fn version(State(state): State<Arc<AppState>>) -> Json<VersionResponse
21
22 Json(VersionResponse {
23 version,
24 - rust_frontend_version: env!("CARGO_PKG_VERSION"),
24 + rust_frontend_version: vllm_build_info::VERSION,
25 })
26 }
setup.py
+6 -1
@@ -1493,6 +1493,11 @@ if (
1493 ):
1494 cmdclass["build_rust"] = precompiled_build_rust
1495
1496 +# Resolve the Python version first because get_vllm_version() may set
1497 +# SETUPTOOLS_SCM_PRETEND_VERSION, which the Rust version should inherit.
1498 +vllm_version = get_vllm_version()
1499 +rust_build.prepare_build_environment()
1500 +
1501 # Rust artifacts, built via setuptools-rust and installed into the package
1502 # directory alongside the Python modules.
1503 rust_extensions = rust_build.rust_extensions(
@@ -1501,7 +1506,7 @@ rust_extensions = rust_build.rust_extensions(
1506
1507 setup(
1508 # static metadata should rather go in pyproject.toml
1504 - version=get_vllm_version(),
1509 + version=vllm_version,
1510 ext_modules=ext_modules,
1511 rust_extensions=rust_extensions,
1512 install_requires=get_requirements(),
tests/entrypoints/openai/test_uds.py
+5 -2
@@ -6,6 +6,7 @@ from tempfile import TemporaryDirectory
6 import httpx
7 import pytest
8
9 +from vllm import envs
10 from vllm.version import __version__ as VLLM_VERSION
11
12 from ...utils import RemoteOpenAIServer
@@ -40,5 +41,7 @@ async def test_show_version(server: RemoteOpenAIServer):
41 response = client.get(server.url_for("version"))
42 response.raise_for_status()
43
43 - # Tolerate additive fields (e.g. the Rust frontend reports its own version).
44 - assert response.json()["version"] == VLLM_VERSION
44 + payload = response.json()
45 + assert payload["version"] == VLLM_VERSION
46 + if envs.VLLM_USE_RUST_FRONTEND:
47 + assert payload["rust_frontend_version"] == VLLM_VERSION
tests/entrypoints/serve/instrumentator/test_basic.py
+5 -2
@@ -12,6 +12,7 @@ import requests
12 from fastapi import Request
13
14 from tests.utils import RemoteOpenAIServer
15 +from vllm import envs
16 from vllm.v1.engine.exceptions import EngineDeadError
17 from vllm.version import __version__ as VLLM_VERSION
18
@@ -83,8 +84,10 @@ async def test_show_version(server: RemoteOpenAIServer):
84 response = requests.get(server.url_for("version"))
85 response.raise_for_status()
86
86 - # Tolerate additive fields (e.g. the Rust frontend reports its own version).
87 - assert response.json()["version"] == VLLM_VERSION
87 + payload = response.json()
88 + assert payload["version"] == VLLM_VERSION
89 + if envs.VLLM_USE_RUST_FRONTEND:
90 + assert payload["rust_frontend_version"] == VLLM_VERSION
91
92
93 @pytest.mark.asyncio
tools/build_rust.py
+16
@@ -11,8 +11,23 @@ from pathlib import Path
11
12 from setuptools import setup
13 from setuptools_rust import Binding, RustExtension
14 +from setuptools_scm import get_version
15
16 ROOT_DIR = Path(__file__).resolve().parents[1]
17 +VLLM_RS_BUILD_VERSION = "VLLM_RS_BUILD_VERSION"
18 +
19 +
20 +def prepare_build_environment() -> str | None:
21 + """Set the device-independent vLLM source version for Rust artifacts."""
22 + version = os.getenv(VLLM_RS_BUILD_VERSION) or None
23 + if version is None:
24 + try:
25 + version = get_version(root=ROOT_DIR)
26 + except LookupError:
27 + return None
28 +
29 + os.environ[VLLM_RS_BUILD_VERSION] = version
30 + return version
31
32
33 def rust_extensions(*, optional: bool = False) -> list[RustExtension]:
@@ -61,6 +76,7 @@ def build_binary(build_rust_args: list[str]) -> None:
76
77
78 def main() -> None:
79 + prepare_build_environment()
80 build_binary(sys.argv[1:])
81
82