diff --git a/.agents/roadmap_v1.md b/.agents/roadmap_v1.md index eb5a46133..4b08e35fd 100644 --- a/.agents/roadmap_v1.md +++ b/.agents/roadmap_v1.md @@ -72,6 +72,8 @@ issue is not yet placed. Keyed record: update in place, never append. | [#465](https://github.com/mudler/vllm.cpp/issues/465) | `ENG-RELEASE-WINDOWS` | LogprobsTensors per-request slice parameter shadows its member under native MSVC `/WX` | bug | | [#474](https://github.com/mudler/vllm.cpp/issues/474) | `ENG-RELEASE-WINDOWS` | MSVC stringizes a backslash-bearing raw literal inside CHECK and rejects the Windows argv expectation | bug | | [#475](https://github.com/mudler/vllm.cpp/issues/475) | `ENG-RELEASE-WINDOWS` | PR #446 release benchmark projection exceeds its page budget after merging current main | bug | +| [#499](https://github.com/mudler/vllm.cpp/issues/499) | `ENG-RELEASE-WINDOWS` | Release binaries report project version instead of prerelease identity | bug | +| [#500](https://github.com/mudler/vllm.cpp/issues/500) | `ENG-RELEASE-WINDOWS` | MSVC release build lacks ostream definition for string_view doctest diagnostics | bug | | [#170](https://github.com/mudler/vllm.cpp/issues/170) | `ENG-RELEASE-BINARIES` | Publish container images to GHCR (cuda, vulkan, cpu) | feature | | [#322](https://github.com/mudler/vllm.cpp/issues/322) | `ENG-RELEASE-BINARIES` | Release handoff collides with tracked checkout `assets` directory | bug | | [#406](https://github.com/mudler/vllm.cpp/issues/406) | `ENG-TRAILER-MERGE-ARTIFACTS` | The trailer gate fails on how commits LAND: GitHub's Co-authored-by displaces the trailer block | bug | diff --git a/.agents/specs/release-binary-matrix.md b/.agents/specs/release-binary-matrix.md index cf12ad8f6..fda8a9dde 100644 --- a/.agents/specs/release-binary-matrix.md +++ b/.agents/specs/release-binary-matrix.md @@ -18,7 +18,11 @@ request [#117](https://github.com/mudler/vllm.cpp/issues/117); hosted CI repair per-commit documentation checkpoint repair is tracked by [#448](https://github.com/mudler/vllm.cpp/issues/448); its archive-target checkpoint repair is tracked by -[#450](https://github.com/mudler/vllm.cpp/issues/450). +[#450](https://github.com/mudler/vllm.cpp/issues/450). The merged-SHA dry-run +repairs for exact prerelease identity and the native MSVC test translation unit +are tracked by [#499](https://github.com/mudler/vllm.cpp/issues/499) and +[#500](https://github.com/mudler/vllm.cpp/issues/500), specified together in +[release-dry-run-gate-repairs.md](release-dry-run-gate-repairs.md). ## Delivery topology diff --git a/.agents/specs/release-dry-run-gate-repairs.md b/.agents/specs/release-dry-run-gate-repairs.md new file mode 100644 index 000000000..b34a5b0b7 --- /dev/null +++ b/.agents/specs/release-dry-run-gate-repairs.md @@ -0,0 +1,262 @@ +# Merged-SHA release dry-run gate repairs + +Identity: `ENG-RELEASE-WINDOWS` + +Issues: +[#499](https://github.com/mudler/vllm.cpp/issues/499) and +[#500](https://github.com/mudler/vllm.cpp/issues/500) + +Parent specifications: +[release-binary-matrix.md](release-binary-matrix.md) and +[windows-binary-release.md](windows-binary-release.md) + +Related native compiler contract: +[windows-msvc-strict-build.md](windows-msvc-strict-build.md) + +Status: `READY`. The developer approved this bounded design on 2026-08-12. It +starts from exact main commit `e1087a8812c9b7d96fca5a813981f378fcace638` +after PR #446 merged. Implementation, a fresh review, the operator gate, and a +new non-publishing ten-tuple dry run remain required. + +## Scope + +Repair the two independent failures exposed by the first exact-merged-SHA +release dry run after PR #446: + +1. make the version compiled into every release `vllm-server` equal the exact + release identity supplied by the release plan, including `-pre.1`, while + preserving the existing backend suffix; and +2. make `tests/vt/test_cpu_isa_x86.cpp` own the standard stream definition its + doctest `std::string_view` diagnostics instantiate under MSVC. + +Keep CMake's numeric `project(vllm_cpp VERSION 0.0.3)` identity, archive names, +manifests, `VERSION` records, C ABI version, backend suffix policy, release +matrix, `/W4 /WX`, and the strict extracted-archive version validator +unchanged. Do not change production ISA selection, suppress a warning, alter a +release tuple, publish a tag or release, or fold an independent dry-run failure +into these issues. + +## Hosted baseline and root causes + +Manual workflow run +[`31607273683`](https://github.com/mudler/vllm.cpp/actions/runs/31607273683) +executed against exact merged SHA +`03ed25a5745ccbbfba7ce9e0f5a1c4a5251b7c30` with release identity +`0.0.3-pre.1`. + +Issue #499 affected six jobs after their Linux or macOS build and packaging +work had completed: + +| Tuple/job | Job ID | Observed gate | +|---|---:|---| +| Linux arm64 CPU | `94152936141` | extracted version mismatch | +| macOS arm64 Metal | `94152936210` | extracted version mismatch | +| Linux x86_64 Vulkan | `94152936237` | extracted version mismatch | +| Linux x86_64 CPU | `94152936310` | extracted version mismatch | +| Linux x86_64 musl CPU | `94152936346` | extracted version mismatch | +| macOS arm64 MLX | `94152936489` | extracted version mismatch | + +`CMakeLists.txt:12` declares only numeric project version `0.0.3` and +`CMakeLists.txt:689` configures `include/vllm/version.h.in`. That template +exports only the numeric `PROJECT_VERSION_{MAJOR,MINOR,PATCH}` components, and +`src/vllm/version.cpp:5-12` reconstructs `0.0.3` before applying the current +backend suffix. The release builders require `VERSION`, but their CMake +configure calls do not pass it: `scripts/build-cpu-release.sh:26-40`, +`scripts/build-linux-accelerator-release.sh:32-48`, +`scripts/build-macos-release.sh:29-43`, and +`scripts/build-windows-release.ps1:180-198`. They use `VERSION` later for the +archive and metadata, so the same archive contains manifest/`VERSION` identity +`0.0.3-pre.1` and a server that reports `0.0.3`. + +This is not a validator defect. `scripts/validate-release-archive.py:662-671`, +`:740-749`, and `:782-790` correctly require the extracted executable's output +to contain the manifest's exact version and the `VERSION` record's exact C ABI. +That comparison remains fail-closed. + +Issue #500 affected native Windows CPU job `94152936312` and Vulkan job +`94152936445`. Both failed while compiling +`tests/vt/test_cpu_isa_x86.cpp:112` through doctest's binary-expression +stringification. The operands are `std::string_view`; the translation unit +includes `` but not ``. Under this MSVC include closure, +`std::basic_ostream` is only forward-declared, so the library's +`operator<<(basic_ostream&, string_view)` instantiation produces incomplete +type, missing `iostate`, and cascading C2146/C2027/C2065 diagnostics. The +production x86 ISA code compiled far enough to reach this test-only boundary. + +## Design + +### Exact compiled build version + +Add a CMake cache string named `VLLM_CPP_BUILD_VERSION`. Its default is the +complete numeric `${PROJECT_VERSION}`, so developer and non-release builds keep +reporting `0.0.3` without a new required argument. Generate that string into +`include/vllm/version.h` and make `vllm::Version()` begin with the generated +build version instead of reconstructing the three numeric components. + +Preserve the existing backend suffix exactly after that identity. For example, +the default CPU build reports `0.0.3`, a prerelease CPU artifact reports +`0.0.3-pre.1`, and a prerelease CUDA artifact reports +`0.0.3-pre.1+cuda`. Do not derive the prerelease from the tag inside CMake and +do not change the numeric `PROJECT_VERSION`, shared-library `VERSION`/`SOVERSION`, +or C ABI version. + +All four release builder families pass their already-required `VERSION` value +to CMake as `-DVLLM_CPP_BUILD_VERSION=...`. The workflow remains responsible +for deriving the single release identity from `release/release-version.json` +and supplying it to each builder. CMake must reject an empty explicit build +version rather than silently reverting to the project version. + +The generated value is build metadata, not a second release authority. The +release plan, manifest, archive name, `VERSION` record, executable output, and +post-publication audit must still agree, and the extracted-archive validator +continues enforcing that agreement. + +### Explicit stream ownership in the MSVC test + +Add the standard `` definition directly to +`tests/vt/test_cpu_isa_x86.cpp`. This is a test translation-unit header-hygiene +repair: it makes doctest's diagnostic formatting valid without relying on a +transitive include. Do not change the compared `std::string_view` values, +doctest expressions, production x86 ISA code, compile flags, warning policy, or +standard-library formatting behavior. + +## RED-first tests and mutation evidence + +Implementation starts by capturing failures against the pinned baseline: + +1. Extend the version test contract so a default configuration requires exact + `0.0.3` plus the existing backend suffix, while a separate configure with + `-DVLLM_CPP_BUILD_VERSION=0.0.3-pre.1` requires exact `0.0.3-pre.1` plus that + same suffix. The prerelease arm must fail on the current numeric-only + `Version()` implementation. +2. Extend `tests/scripts/test_release_pipeline.py` over the real four builder + scripts. It must require each configure invocation to forward its existing + `VERSION` input through `VLLM_CPP_BUILD_VERSION`; deleting the argument, + substituting a literal, using `PROJECT_VERSION`, or omitting one builder + must fail. +3. Preserve or extend the archive-validation mutation proving that a server + output of `0.0.3` is rejected when manifest and `VERSION` declare + `0.0.3-pre.1`. No skip-version path may be introduced into a release job. +4. Extend the Windows portability suite over the real + `tests/vt/test_cpu_isa_x86.cpp` closure. It must require the explicit + standard stream definition used by the `std::string_view` doctest + expressions; removing it must fail the structural test and the native MSVC + compile. Comments, literals, or unrelated transitive includes are not valid + substitutes. + +Every mutation runs in a scratch copy and restores the candidate tree +byte-for-byte. A structural Linux result does not substitute for executing the +native MSVC compiler. + +## Gates + +Focused local gates are: + +1. the default and prerelease-configured `test_version` cases, including the + current backend-suffix arm; +2. `python3 -m unittest tests.scripts.test_release_pipeline -v` and the focused + release archive/metadata validator tests; +3. `python3 -m unittest tests.scripts.test_check_windows_portability -v` plus + the direct portability checker; and +4. clean CPU configure/build and `test_cpu_isa_x86` execution on the available + local host, followed by full unstaged, staged, and post-commit + `scripts/agent-preflight.sh`. + +Hosted acceptance requires native `windows-2022` CPU and Vulkan Release builds +to compile `test_cpu_isa_x86` under unchanged `/W4 /WX`, then execute their +existing focused runtime/ISA and archive gates. The six affected Linux, +macOS, and musl jobs must extract the archive and accept the exact +`0.0.3-pre.1` server identity. CUDA jobs must preserve their existing +`+cuda` suffix after the same prerelease identity. + +After merge, rerun the complete ten-tuple non-publishing workflow at the exact +merged SHA. Every required tuple, aggregate handoff, and verify job must be +green, and each archive/manifest/`VERSION`/executable identity must agree. +Manual dispatch must continue skipping attest and publish. Only that immutable +dry run can authorize the already-planned developer-controlled +`v0.0.3-pre.1` tag flow; the tag run must rebuild, attest, publish exactly 32 +assets, and pass the existing authenticated post-publication audit before any +binary-release claim advances. + +## Risks and stop conditions + +- A build-version string can accidentally become an independent release + authority or be lost through one platform's quoting. The single declaration + and all four builder mutations must keep the release graph closed. +- Replacing numeric component macros outright could break an internal consumer. + Preserve them unless their removal is separately proved and reviewed; only + `Version()` needs the full generated identity. +- Backend suffixes can be dropped or duplicated when the base string changes. + Exact CPU and CUDA expectations are required. +- A transitive stream include may make a local compiler green while MSVC stays + red. The test TU must own ``, and native compilation remains binding. +- Stop with `NEEDS_DECISION` if #500 requires any production ISA, behavior, + warning-level, or warning-suppression change. +- Stop with `NEEDS_CONTEXT` if a rerun exposes a direct diagnostic outside + these two root causes. File and specify an independent issue rather than + weakening a gate or silently expanding this repair. +- Do not tag or publish if any of the ten dry-run tuples, aggregate handoff, + verify job, exact version checks, or Windows native gates is not green on the + same merged SHA. A partial matrix is not release evidence. + +## Written-spec self-review + +- Scope is limited to exact compiled release identity and one test-TU stream + definition; release topology and production ISA behavior do not change. +- The CMake default, release override, backend suffix, four builder inputs, + strict validator, and native compiler boundary are explicit. +- RED tests and mutations fail for the two observed defects before code changes. +- Local, hosted, dry-run, tag-run, and post-publication evidence are separated; + none is inferred from another. + +## Outcome + +Implemented both bounded dry-run repairs without changing release topology, +production ISA behavior, warning policy, or validator strictness. + +- `VLLM_CPP_BUILD_VERSION` is now a non-empty CMake cache string defaulting to + `PROJECT_VERSION`. The generated version header retains the numeric component + macros and also carries that exact identity; `Version()` appends the existing + `+cuda` qualifier to it unchanged. +- The CPU, Linux accelerator, macOS, and Windows release builders each forward + their already-required `VERSION` value to CMake exactly once. +- `tests/vt/test_cpu_isa_x86.cpp` now owns the standard `` definition + required by its doctest diagnostics. + +RED evidence on the pinned candidate preceded implementation. The builder +contract reported zero `VLLM_CPP_BUILD_VERSION` arguments for all four builder +families, the portability contract reported no active `` include, and +a separately configured `0.0.3-pre.1` `test_version` failed because the binary +reported `0.0.3`. The retained strict-validator mutation rejects a numeric-only +server output when the manifest and `VERSION` declare `0.0.3-pre.1`. + +Focused green evidence: + +- release pipeline suite: 41 tests passed; +- Windows portability suite: 71 tests passed, followed by the direct checker; +- archive and platform metadata suites: 43 tests passed; +- an explicit empty build-version configure was rejected; and +- clean CPU builds passed the default and prerelease version tests. The clean + prerelease build also passed all 8,242 x86 ISA assertions. Server smoke output + was exactly `vllm.cpp 0.0.3 c-abi=17` by default and + `vllm.cpp 0.0.3-pre.1 c-abi=17` with the release override. + +The two hosted CUDA failures from dry run `31607273683` provide additional +root-cause evidence: jobs `94152936151` and `94152936356` both completed their +build and package phases and failed only because the extracted binary reported +the numeric project version. They did not expose a third repair within this +row's scope. + +Native Windows compilation, the complete ten-tuple non-publishing workflow, +and the tag-run publication/audit remain post-merge acceptance gates. No tag or +release is authorized by the local evidence alone. + +Fresh review of immutable implementation `e0b17eb9` found that the compiled +version test derived its default expectation from the same cache value under +test. Mutating the cache default from `${PROJECT_VERSION}` to `9.9.9` therefore +changed both subject and oracle and left the focused suite green. The review +loop adds an independent release-contract assertion over the real CMake cache +declaration. With the `9.9.9` mutation applied, that assertion failed exactly +with `9.9.9 != ${PROJECT_VERSION}`; after restoration it and the complete +42-test release pipeline suite passed. Production CMake and runtime code remain +unchanged by this follow-up. diff --git a/.agents/specs/windows-binary-release.md b/.agents/specs/windows-binary-release.md index dc8c2d89f..b8631178a 100644 --- a/.agents/specs/windows-binary-release.md +++ b/.agents/specs/windows-binary-release.md @@ -58,6 +58,11 @@ Release benchmark projection compaction: [#475](https://github.com/mudler/vllm.cpp/issues/475), specified in [release-benchmark-projection-compaction.md](release-benchmark-projection-compaction.md) +Merged-SHA release dry-run gate repairs: +[#499](https://github.com/mudler/vllm.cpp/issues/499) and +[#500](https://github.com/mudler/vllm.cpp/issues/500), specified in +[release-dry-run-gate-repairs.md](release-dry-run-gate-repairs.md) + Parent contract: [release-binary-matrix.md](release-binary-matrix.md) Planned publication: GitHub prerelease tag `v0.0.3-pre.1`. diff --git a/CMakeLists.txt b/CMakeLists.txt index 1357fce58..6f5b2e0dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,12 @@ vllm_cpp_forbid_in_source_build("${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}") project(vllm_cpp VERSION 0.0.3 LANGUAGES CXX) +set(VLLM_CPP_BUILD_VERSION "${PROJECT_VERSION}" CACHE STRING + "Exact version identity reported by this build") +if(VLLM_CPP_BUILD_VERSION STREQUAL "") + message(FATAL_ERROR "VLLM_CPP_BUILD_VERSION must not be empty") +endif() + # Native Windows release ABI: the core and every consumer use the static # MSVC/UCRT runtime (/MT in Release, /MTd in Debug), so the installed server # does not depend on a developer-machine CRT deployment. diff --git a/docs/USAGE.md b/docs/USAGE.md index 635e3e55c..8ff0590df 100644 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -22,6 +22,22 @@ example targets are named after the directories they are built from, so an in-source build makes the linker write each executable over its own source directory (issue #85). +### Setting the compiled build identity + +`vllm-server --version` reports the CMake project version by default. Release +packaging passes the complete release identity, including any prerelease +component, with `-DVLLM_CPP_BUILD_VERSION=`: + +```sh +cmake -S . -B build -DVLLM_CPP_BUILD_VERSION=0.0.3-pre.1 +``` + +The value must not be empty. CUDA builds append their existing `+cuda` +qualifier to this identity. This option controls only the compiled binary +identity; release archives must still use the repository release workflow so +their manifest, `VERSION` record, archive name, and executable are validated as +one version. + ### One ROCm-specific behaviour ROCm builds register the full V1 sampler surface (temperature, top-k/top-p, min-p, diff --git a/include/vllm/version.h.in b/include/vllm/version.h.in index 136c0abe1..04c7ff7ca 100644 --- a/include/vllm/version.h.in +++ b/include/vllm/version.h.in @@ -4,8 +4,9 @@ #define VLLM_CPP_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ #define VLLM_CPP_VERSION_MINOR @PROJECT_VERSION_MINOR@ #define VLLM_CPP_VERSION_PATCH @PROJECT_VERSION_PATCH@ +#define VLLM_CPP_BUILD_VERSION "@VLLM_CPP_BUILD_VERSION@" namespace vllm { -// Returns "MAJOR.MINOR.PATCH", plus "+cuda" when built with the CUDA backend. +// Returns the exact build identity, plus "+cuda" when built with that backend. std::string Version(); } // namespace vllm diff --git a/scripts/build-cpu-release.sh b/scripts/build-cpu-release.sh index 9e76abec5..ac4362300 100755 --- a/scripts/build-cpu-release.sh +++ b/scripts/build-cpu-release.sh @@ -25,6 +25,7 @@ fi cmake -S . -B "$build_dir" -G Ninja \ -DVLLM_CPP_BUILD_TESTS=ON \ + -DVLLM_CPP_BUILD_VERSION="$VERSION" \ -DVLLM_CPP_BUILD_EXAMPLES=ON \ -DVLLM_CPP_SERVER=ON \ -DVLLM_CPP_CUDA=OFF \ diff --git a/scripts/build-linux-accelerator-release.sh b/scripts/build-linux-accelerator-release.sh index 38ec8f938..c3545b45d 100755 --- a/scripts/build-linux-accelerator-release.sh +++ b/scripts/build-linux-accelerator-release.sh @@ -33,6 +33,7 @@ cmake -S . -B "$build_dir" -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ -DVLLM_CPP_BUILD_TESTS=ON \ + -DVLLM_CPP_BUILD_VERSION="$VERSION" \ -DVLLM_CPP_BUILD_EXAMPLES=ON \ -DVLLM_CPP_SERVER=ON \ -DVLLM_CPP_CUDA="$cuda" \ diff --git a/scripts/build-macos-release.sh b/scripts/build-macos-release.sh index 5d5c2ef07..284115034 100755 --- a/scripts/build-macos-release.sh +++ b/scripts/build-macos-release.sh @@ -29,6 +29,7 @@ fi cmake -S . -B "$build_dir" -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DVLLM_CPP_BUILD_TESTS=ON \ + -DVLLM_CPP_BUILD_VERSION="$VERSION" \ -DVLLM_CPP_BUILD_EXAMPLES=ON \ -DVLLM_CPP_SERVER=ON \ -DVLLM_CPP_CUDA=OFF \ diff --git a/scripts/build-windows-release.ps1 b/scripts/build-windows-release.ps1 index 1f29767d1..b8725cce1 100644 --- a/scripts/build-windows-release.ps1 +++ b/scripts/build-windows-release.ps1 @@ -183,6 +183,7 @@ Invoke-Checked cmake @( "-G", "Visual Studio 17 2022", "-A", "x64", "-DVLLM_CPP_BUILD_TESTS=ON", + "-DVLLM_CPP_BUILD_VERSION=$env:VERSION", "-DVLLM_CPP_BUILD_EXAMPLES=ON", "-DVLLM_CPP_SERVER=ON", "-DVLLM_CPP_CUDA=OFF", diff --git a/src/vllm/version.cpp b/src/vllm/version.cpp index e5dd01af7..dc56c1493 100644 --- a/src/vllm/version.cpp +++ b/src/vllm/version.cpp @@ -3,9 +3,7 @@ namespace vllm { std::string Version() { - std::string v = std::to_string(VLLM_CPP_VERSION_MAJOR) + "." + - std::to_string(VLLM_CPP_VERSION_MINOR) + "." + - std::to_string(VLLM_CPP_VERSION_PATCH); + std::string v = VLLM_CPP_BUILD_VERSION; #ifdef VLLM_CPP_CUDA v += "+cuda"; #endif diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9f9888f54..c2f717161 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -35,6 +35,12 @@ function(vllm_cpp_add_test name) endfunction() vllm_cpp_add_test(test_version vllm/test_version.cpp) +set(_vllm_cpp_expected_build_version "${PROJECT_VERSION}") +if(DEFINED VLLM_CPP_BUILD_VERSION) + set(_vllm_cpp_expected_build_version "${VLLM_CPP_BUILD_VERSION}") +endif() +target_compile_definitions(test_version PRIVATE + VLLM_CPP_EXPECTED_BUILD_VERSION="${_vllm_cpp_expected_build_version}") vllm_cpp_add_test(test_sampling_params vllm/test_sampling_params.cpp) vllm_cpp_add_test(test_punica_cpu vllm/lora/test_punica_cpu.cpp) vllm_cpp_add_test(test_lora_layers vllm/lora/test_lora_layers.cpp) diff --git a/tests/scripts/test_check_windows_portability.py b/tests/scripts/test_check_windows_portability.py index ab804eba6..a5202a936 100644 --- a/tests/scripts/test_check_windows_portability.py +++ b/tests/scripts/test_check_windows_portability.py @@ -547,6 +547,21 @@ def test_windows_command_line_expectation_is_not_stringized(self) -> None: r"\(\s*argv\s*\)\s*==\s*expected\s*\)\s*;", ) + def test_cpu_isa_test_owns_ostream_for_string_view_diagnostics(self) -> None: + source = (REPO / "tests/vt/test_cpu_isa_x86.cpp").read_text( + encoding="utf-8" + ) + directives = checker._cpp_directive_view(source) + includes = list( + re.finditer(r"(?m)^\s*#\s*include\s*\s*$", directives) + ) + self.assertEqual(len(includes), 1) + self.assertLess( + includes[0].start(), + directives.index('#include "doctest/doctest.h"'), + ) + self.assertIn("std::string_view::npos", source) + def test_posix_cache_source_requires_exact_not_win32_cmake_guard(self) -> None: source = "src/vt/cuda/nvfp4_persistent_cache.cpp" for condition, expected in (("NOT WIN32", {source}), ("WIN32", set()), ("NOT APPLE", set())): diff --git a/tests/scripts/test_release_archive.py b/tests/scripts/test_release_archive.py index 1fd17dc8f..1d85208e5 100755 --- a/tests/scripts/test_release_archive.py +++ b/tests/scripts/test_release_archive.py @@ -16,6 +16,7 @@ import unittest import zipfile from pathlib import Path +from unittest import mock ROOT = Path(__file__).resolve().parents[2] @@ -257,6 +258,39 @@ def bad_version(stage, manifest, sbom): result = self.run_validator(*paths) self.assertNotEqual(result.returncode, 0) + def test_prerelease_manifest_rejects_numeric_only_server_version(self) -> None: + with tempfile.TemporaryDirectory() as temporary: + root = Path(temporary) + server = root / "bin/vllm-server" + server.parent.mkdir(parents=True) + server.write_bytes(b"ELF fixture") + (root / "VERSION").write_text( + "version=0.0.3-pre.1\nc_abi_version=17\n", encoding="utf-8" + ) + manifest = self.manifest(Path("/bin/true")) + manifest["artifact"]["version"] = "0.0.3-pre.1" + + def fake_run(command): + if command[0] == "file": + return 0, "ELF 64-bit LSB executable, x86-64" + if command[0] == "readelf": + return 0, "" + if command[0] == "ldd": + return 0, "statically linked" + if command[-1] == "--help": + return 0, "usage: vllm-server" + if command[-1] == "--version": + return 0, "vllm.cpp 0.0.3 c-abi=17" + raise AssertionError(command) + + with mock.patch.object(self.tool.shutil, "which", return_value="tool"), \ + mock.patch.object(self.tool, "run", side_effect=fake_run): + errors = self.tool.inspect_linux(server, manifest, [], False) + self.assertIn( + "extracted vllm-server --version disagrees with VERSION/manifest", + errors, + ) + def test_build_path_and_undeclared_dynamic_dependency_fail(self) -> None: manifest = json.loads(FIXTURE.read_text(encoding="utf-8")) errors = self.tool.validate_linux_dynamic( diff --git a/tests/scripts/test_release_pipeline.py b/tests/scripts/test_release_pipeline.py index 343fb5855..0934524dc 100755 --- a/tests/scripts/test_release_pipeline.py +++ b/tests/scripts/test_release_pipeline.py @@ -6,6 +6,7 @@ import copy import importlib.util import json +import re import subprocess import sys import tempfile @@ -119,6 +120,16 @@ def test_release_version_declaration_is_the_single_prerelease_identity(self) -> cmake = (ROOT / "CMakeLists.txt").read_text(encoding="utf-8") self.assertIn("project(vllm_cpp VERSION 0.0.3 LANGUAGES CXX)", cmake) + def test_default_build_version_is_project_version(self) -> None: + cmake = (ROOT / "CMakeLists.txt").read_text(encoding="utf-8") + declaration = re.search( + r'^set\(VLLM_CPP_BUILD_VERSION\s+"([^"]*)"\s+CACHE\s+STRING\b', + cmake, + re.MULTILINE, + ) + self.assertIsNotNone(declaration, "missing build-version cache declaration") + self.assertEqual(declaration.group(1), "${PROJECT_VERSION}") + def test_release_version_declaration_rejects_every_identity_mismatch(self) -> None: original = json.loads(RELEASE_VERSION.read_text(encoding="utf-8")) mutations = { @@ -135,6 +146,39 @@ def test_release_version_declaration_rejects_every_identity_mismatch(self) -> No with self.assertRaises(ValueError): self.pipeline.validate_release_version(mutant) + def test_every_release_builder_forwards_exact_build_version_to_cmake(self) -> None: + shell_argument = '-DVLLM_CPP_BUILD_VERSION="$VERSION"' + for driver in BUILD_DRIVERS: + with self.subTest(driver=driver.name): + text = driver.read_text(encoding="utf-8") + self.assertEqual(text.count(shell_argument), 1) + for replacement in ( + "", + '-DVLLM_CPP_BUILD_VERSION="0.0.3-pre.1"', + '-DVLLM_CPP_BUILD_VERSION="$PROJECT_VERSION"', + ): + self.assertNotEqual( + text.replace(shell_argument, replacement, 1).count( + shell_argument + ), + 1, + ) + + powershell_argument = '"-DVLLM_CPP_BUILD_VERSION=$env:VERSION"' + text = WINDOWS_BUILD_DRIVER.read_text(encoding="utf-8") + self.assertEqual(text.count(powershell_argument), 1) + for replacement in ( + "", + '"-DVLLM_CPP_BUILD_VERSION=0.0.3-pre.1"', + '"-DVLLM_CPP_BUILD_VERSION=$env:PROJECT_VERSION"', + ): + self.assertNotEqual( + text.replace(powershell_argument, replacement, 1).count( + powershell_argument + ), + 1, + ) + def test_workflow_has_two_exact_native_windows_preview_lanes(self) -> None: workflow = WORKFLOW.read_text(encoding="utf-8") for job, backend, build_dir in ( diff --git a/tests/vllm/test_version.cpp b/tests/vllm/test_version.cpp index fd98f0f7e..2bef92289 100644 --- a/tests/vllm/test_version.cpp +++ b/tests/vllm/test_version.cpp @@ -2,12 +2,11 @@ #include "vllm/version.h" -TEST_CASE("Version reports semver from project()") { - auto v = vllm::Version(); - CHECK(v.rfind("0.0.3", 0) == 0); // starts with MAJOR.MINOR.PATCH +TEST_CASE("Version reports the exact configured build identity") { + std::string expected = VLLM_CPP_EXPECTED_BUILD_VERSION; #ifndef VLLM_CPP_CUDA - CHECK(v == "0.0.3"); + CHECK(vllm::Version() == expected); #else - CHECK(v == "0.0.3+cuda"); + CHECK(vllm::Version() == expected + "+cuda"); #endif } diff --git a/tests/vt/test_cpu_isa_x86.cpp b/tests/vt/test_cpu_isa_x86.cpp index d302fee55..a12152cac 100644 --- a/tests/vt/test_cpu_isa_x86.cpp +++ b/tests/vt/test_cpu_isa_x86.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include