openvmm: expose release and development build identity - #4137
Closed
Ben Hillis (benhillis) wants to merge 6 commits into
Closed
openvmm: expose release and development build identity#4137Ben Hillis (benhillis) wants to merge 6 commits into
Ben Hillis (benhillis) wants to merge 6 commits into
Conversation
added 6 commits
July 31, 2026 11:55
`openvmm --version` did not exist, and there was nothing to report if it had: the workspace set no `version`, so every crate in it was `0.0.0`. OpenVMM ships as a source archive that packagers build themselves, which rules out the usual approach of having CI inject a version at build time -- the packager builds long after our pipeline has exited, from a tree with no git history to recover a version from. The version therefore has to be committed to the tree. QEMU, systemd, the kernel, cloud-hypervisor and rustc all do this, and each falls back gracefully when `.git` is absent rather than deriving the release version from a tag. So: set `version` in `[workspace.package]`, inherit it in `openvmm` and `openvmm_entry`, and wire up clap's `version`. `OPENVMM_PKGVERSION` lets a packager append their own build identity, as QEMU's `-Dpkgversion` and cloud-hypervisor's `CH_EXTRA_VERSION` do; an empty value is ignored, since build systems routinely pass an undefined variable through as "". Two things fall out of that: - The Windows VERSIONINFO resource is a second version surface, stamped from `OPENVMM_MAJOR`/`MINOR`/`PATCH`/`REVISION` and defaulting to `0.0.0.0`. No in-repo caller sets those, so leaving it alone would have left one binary reporting `0.1.0-dev` from `--version` and `0.0.0.0` from its file properties. It now defaults to the crate version, with the env vars still overriding per-component so a pipeline can stamp a build number in. - `cargo xtask fmt` deliberately strips `version` from `[package]`, partly because doing so also makes a crate unpublishable. The three crates on its exception list now set `publish = false` explicitly, restoring the property the lint was relying on. Verified by building `openvmm` from an extracted archive with no `.git` anywhere above it, which is the case that actually matters.
The workspace version advances only in the reviewed pull request that selects the next release. Development-build identity is added separately from the committed product version. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 0ba1c0df-faf0-4a0e-b39d-c3eb0e363fce
Builds on the crate-based version by adding back the part of the tag-derived scheme that is actually worth having: the commit a build came from. `openvmm_build_info` resolves the version at build time. The version itself is still a committed fact inherited from `[workspace.package]`, so it travels inside the source archive and a packager building an extracted tree with no Git history reports the right thing. Git is consulted only to append `+g<revision>` to a build made from a checkout, as semver build metadata so it orders identically to the plain version. `OPENVMM_PKGVERSION` still replaces the lot. Deliberately omitted from the tag-derived design: - No `.openvmm-release.json` and no tag parsing. Nothing has to stamp metadata into the archive, so there is no release step that can silently fail and leave a shipped tarball reporting `0.0.0-dev`, and no tag/manifest agreement to validate in CI. - No dirty flag. Detecting a modified working tree means emitting a `rerun-if-changed` for every tracked file, which stats the entire repository on every build. The revision alone needs two files. The Git lookup rejects a repository that does not start exactly where OpenVMM does. Git searches parent directories, so an archive extracted inside an unrelated checkout would otherwise report that checkout's HEAD, which is the one failure mode here that is silent and wrong rather than merely absent. `product_version` is exposed separately from `version` and is what the snapshot manifest records, since a persisted field wants the upstream version rather than a distribution's build string. Verified from a checkout, from an archive extracted outside any repository, and from one extracted inside an unrelated repository.
Keep enriching ordinary checkouts with +g<sha>, but report the plain product version when HEAD carries openvmm-v<VERSION>. A checkout without tags fails safely toward development identity, while an extracted source archive remains plain because it has no repository. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 0ba1c0df-faf0-4a0e-b39d-c3eb0e363fce
The hybrid versioning scheme already orders correctly -- `0.1.0-dev` is a
semver prerelease, so it sorts below `0.1.0` -- but nothing said "this is
not an official build" in words, and nothing distinguished the two at all
on Windows.
Four additions, none of which invent a new source of truth:
- `BuildKind` (`Release | Development | Custom`), resolved at build time
from facts already in hand: `Custom` when `OPENVMM_PKGVERSION` is set,
`Development` when the version carries a prerelease component, else
`Release`. It lands in the `OPENVMM_BUILD_INFO` link section, so it is
extractable from a binary without running it.
Deliberately not a boolean "official". OpenVMM ships as source that
someone else builds, so a packager's binary is legitimately not ours and
yet is a legitimate build of an official version. A boolean would be
unverifiable and would invite lying; the real proof of officialness is
the attestation on the tarball.
- A rustc-style long version. clap uses `version` for `-V` and
`long_version` for `--version`, so this costs no new flag:
openvmm 0.1.0-dev+g2d79d0685
build: development (not an official release)
version: 0.1.0-dev
commit: 2d79d06
host: x86_64-pc-windows-msvc
Composed in the build script, because the parts are optional, and passed
through a file in `OUT_DIR` rather than `cargo::rustc-env`: cargo parses
build script output a line at a time and silently keeps only the first
line of a multi-line value.
- One startup log line carrying the same identity, so every log bundle and
bug report has it. `info`, not `warn`: development builds are the normal
case for anyone working on OpenVMM, and a warning that always fires is
one that gets filtered out and then ignored when it finally matters.
Emitted after option parsing so `--version` and `--help` stay clean, and
after the mesh host check so worker processes do not each repeat it.
- `VS_FF_PRERELEASE` in the Windows version resource, which is the
idiomatic Win32 mechanism for exactly this and shows up in the file
properties dialog. Set from `CARGO_PKG_VERSION_PRE`, so it tracks the
same fact the rest of this does.
`VS_FF_SPECIALBUILD` was considered for the `OPENVMM_PKGVERSION` case and
skipped: it requires a matching `SpecialBuild` string, which needs
RC-preprocessor conditionals to supply, and packager overrides on Windows
are rare enough not to justify that.
Verified: `-V` and `--version` produce the short and long forms; the log
line appears once on a real run and not on `--version`; and the built
binary reports `IsPreRelease: True` with `FileVersion 0.1.0.0`.
Classify only an extracted released source tree or an exact release-tag checkout as a release. Ordinary checkouts remain development builds even though the committed product version is the most recently released version. Keep the long CLI output, startup telemetry, and Windows VS_FF_PRERELEASE flag consistent with that classification. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 0ba1c0df-faf0-4a0e-b39d-c3eb0e363fce
|
This PR modifies files containing For more on why we check whole files, instead of just diffs, check out the Rustonomicon |
Contributor
There was a problem hiding this comment.
Pull request overview
This pull request introduces a centralized “build identity” source (openvmm_build_info) and wires it into user-visible version reporting and telemetry, while also ensuring Windows VERSIONINFO reflects whether the build is a release vs development checkout.
Changes:
- Add
openvmm_build_infocrate to provide a consistent version/kind/revision/target identity (including a multi-line--versionform). - Update
openvmmCLI version output, snapshot manifest stamping, and startup telemetry to use the resolved build identity. - Ensure versioned crates that must carry a version explicitly set
publish = false, and extend the workspace to carry a canonical version.
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
xtask/src/tasks/fmt/lints/package_info.rs |
Expands version exception policy and documents why certain crates may carry a version. |
vm/vmgs/vmgstool/Cargo.toml |
Adds publish = false to comply with the “versioned crate” exception policy. |
openvmm/openvmm/resources.rc |
Adds Windows VERSIONINFO file flags plumbing for prerelease marking. |
openvmm/openvmm/Cargo.toml |
Makes openvmm inherit the workspace version and prevents publishing. |
openvmm/openvmm/build.rs |
Stamps Windows resource version from the crate version by default and sets prerelease flags based on Git tag identity. |
openvmm/openvmm_entry/src/vm_controller.rs |
Persists the canonical product version into snapshot manifests. |
openvmm/openvmm_entry/src/lib.rs |
Emits once-per-process build identity telemetry in logs. |
openvmm/openvmm_entry/src/cli_args.rs |
Sets CLI name/version/long-version from openvmm_build_info and adds tests for -V/--version output. |
openvmm/openvmm_entry/Cargo.toml |
Adds dependency on openvmm_build_info. |
openvmm/openvmm_build_info/src/lib.rs |
Defines BuildInfo/BuildKind API and embeds build metadata in a discoverable linker section. |
openvmm/openvmm_build_info/Cargo.toml |
Introduces the new crate with workspace version and publish = false. |
openvmm/openvmm_build_info/build.rs |
Generates version/kind/revision/target env vars and long_version.txt at build time. |
Cargo.toml |
Sets [workspace.package] version and adds openvmm_build_info to workspace dependencies. |
Cargo.lock |
Updates resolved package versions and includes the new crate. |
Comment on lines
+150
to
+158
| let target = std::env::var("TARGET").unwrap_or_else(|_| "unknown".into()); | ||
| let long_version = format!( | ||
| "{version}\n\ | ||
| build: {kind_description}\n\ | ||
| version: {product_version}\n\ | ||
| commit: {}\n\ | ||
| host: {target}", | ||
| revision.as_deref().unwrap_or("(not built from a checkout)"), | ||
| ); |
Member
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Depends on #4135. Once the preceding version PRs merge, this diff reduces to the user-visible build classification.
This change makes the source shape explicit wherever build identity is inspected:
openvmm -Vremains compact;openvmm --versionreports version, build kind, product version, revision, and target;VS_FF_PRERELEASEfor ordinary checkouts;openvmm-v<VERSION>checkout and an extracted source archive reportrelease;OPENVMM_PKGVERSIONreportscustom, rather than allowing a builder to claim official release status.The compiled behavior is unchanged; these are identity and diagnostics only.