diff --git a/Guide/src/SUMMARY.md b/Guide/src/SUMMARY.md index 1e66a0c7ca..74e60f407f 100644 --- a/Guide/src/SUMMARY.md +++ b/Guide/src/SUMMARY.md @@ -61,7 +61,9 @@ - [Coding Conventions](./dev_guide/contrib/code.md) - [Save State](./dev_guide/contrib/save-state.md) - [Snapshot Format](./dev_guide/snapshot_format.md) - - [Releases & Code Flow](./dev_guide/contrib/release.md) + - [OpenVMM Release Model and Support](./dev_guide/contrib/openvmm_release.md) + - [Packaging OpenVMM for a Linux Distribution](./dev_guide/contrib/openvmm_packaging.md) + - [OpenHCL Release Management](./dev_guide/contrib/openhcl_release.md) - [Submitting Changes](./dev_guide/contrib/pr.md) - [Code Review Process](./dev_guide/contrib/code_review.md) - [Guide Updates](./dev_guide/contrib/guide.md) diff --git a/Guide/src/dev_guide/contrib/release.md b/Guide/src/dev_guide/contrib/openhcl_release.md similarity index 66% rename from Guide/src/dev_guide/contrib/release.md rename to Guide/src/dev_guide/contrib/openhcl_release.md index aa1b269d5a..4ea1c1f14f 100644 --- a/Guide/src/dev_guide/contrib/release.md +++ b/Guide/src/dev_guide/contrib/openhcl_release.md @@ -1,16 +1,35 @@ -# Release Management +# OpenHCL Release Management -Occasionally, the OpenVMM project will declare upcoming release milestones. We -stabilize the code base in a `release/..` branch, typically -named for the YYMM when the branch was forked. Future references to the release -number will be shortened to `` in this doc. We expect a high quality -bar for all code that goes into the OpenVMM main branch, and we ask developers -to hold these release branches to the highest quality standards. The OpenVMM -maintainers will gradually slow the rate of churn into these branches as we get -closer to a close date. +This page describes the OpenHCL release branch, stabilization, and servicing +process. -> **Note:** Some older release branches use the format `release/` without -> the major and minor version numbers (e.g., `release/2411`, `release/2505`). +```admonish note title="See also" +[OpenVMM Release Model and Support](./openvmm_release.md) describes standalone +OpenVMM releases. OpenVMM tags and versions are independent from the OpenHCL +release branches described below. +``` + +```admonish warning +The `release/*` branches on this page service OpenHCL. They are not standalone +OpenVMM release branches. OpenVMM releases directly from `main`. Post-`1.0` it +may also create an on-demand patch branch when its currently supported release +requires a security or release-blocking fix; see +[OpenVMM Release Model and Support](./openvmm_release.md). +``` + +Occasionally, the OpenHCL project will declare upcoming release milestones. +We stabilize the code base in a `release/..` branch, +typically named for the YYMM when the branch was forked. Future references to +the release number will be shortened to `` in this doc. We expect a +high quality bar for all code that goes into the repository's main branch, and +we ask developers to hold these release branches to the highest quality +standards. The OpenHCL maintainers will gradually slow the rate of churn into +these branches as we get closer to a close date. + +```admonish note +Some older release branches use the format `release/` without the major +and minor version numbers, such as `release/2411` and `release/2505`. +``` This process should not impact your typical workflow; all new work should go into the `main` branch. But, to ease the cherry-picks, we may ask that you hold @@ -19,10 +38,8 @@ process. ## Marking, Approval Process, Code Flow -The OpenVMM maintainers will publish various dates for the upcoming releases. -Currently, these dates are driven by a Microsoft-internal process and can, and -do, often change. Microsoft does not mean to convey any new product launches by -choices of these dates. +The OpenHCL maintainers will publish various dates for upcoming releases. These +dates may change as release needs evolve and do not convey new product launches. Releases naturally fall into several phases: @@ -42,7 +59,9 @@ We track the state of candidates for a given release by tagging the PRs with the * N.B.: A maintainer will _remove_ this tag if the fix is not accepted into the release. * `backported_`: This PR (to `main`) has been cherry-picked to the release branch. -The [`repo_support/relabel_backported.py`](https://github.com/microsoft/openvmm/blob/main/repo_support/relabel_backported.py) script can be used to automatically transition PRs from `backport_` to `backported_` once they have been cherry-picked to the release branch. +The [`repo_support/relabel_backported.py`][relabel-backported] script can +automatically transition PRs from `backport_` to +`backported_` once they have been cherry-picked to the release branch. #### Seeking Approval for Backport @@ -66,7 +85,7 @@ When creating a backport PR to a release branch: resolution or additional modifications), clearly indicate this in the PR description. This signals to the reviewer that extra care is needed during the review process. - + ## Existing Release Branches | Release | Phase | Notes | @@ -81,3 +100,5 @@ When creating a backport PR to a release branch: We welcome feedback, especially if you would like to depend on a reliable release process. Please reach out! + +[relabel-backported]: https://github.com/microsoft/openvmm/blob/main/repo_support/relabel_backported.py diff --git a/Guide/src/dev_guide/contrib/openvmm_packaging.md b/Guide/src/dev_guide/contrib/openvmm_packaging.md new file mode 100644 index 0000000000..ff2a15d676 --- /dev/null +++ b/Guide/src/dev_guide/contrib/openvmm_packaging.md @@ -0,0 +1,228 @@ +# Packaging OpenVMM for a Linux Distribution + +This page describes building the `openvmm` binary as a Linux distribution +package, from public source only. It is aimed at downstream packagers (for +example, an RPM or `.deb` maintainer) who build from the official OpenVMM source +release rather than from the in-repo `cargo xflowey` provisioning flow. + +The examples target [Azure Linux](https://github.com/microsoft/azurelinux), but +the requirements generalize to any glibc distribution. + +```admonish note title="See also" +[OpenVMM Release Model and Support](./openvmm_release.md) describes the source +release archive and version identity that a distribution package builds from. +[Crypto Backends](./crypto_backends.md) explains the backend selection that +determines the native dependencies below. +``` + +## What a distribution package builds + +A distribution package builds the host `x86_64-unknown-linux-gnu` target: +dynamically linked against the system glibc and OpenSSL. Building from the +official source release is the supported way to consume OpenVMM today, and this +is the configuration to use. It differs from the statically linked `musl` +binaries that the repository's own provisioning tooling produces, which is what +the project will ship if and when it publishes prebuilt Linux archives. + +The gnu build deliberately avoids the repository's `.packages/` provisioning +(`cargo xflowey restore-packages`), which fetches prebuilt native libraries a +distribution build cannot consume. A packager instead supplies every native +dependency from distribution packages and overrides the few build settings that +otherwise point into `.packages/`. + +```admonish tip title="Only two overrides are required" +Building the `openvmm` binary for the gnu target needs no source patches. It +needs the distribution build packages below, plus two environment overrides +(`PROTOC` and `OPENSSL_NO_VENDOR`). +``` + +OpenVMM's CI builds this configuration on every change and checks that the +resulting binary links the distribution's OpenSSL, so a change that only works +against `.packages/` is caught upstream rather than by a packager. The CI job is +the executable form of this page: if the two descriptions ever disagree, the job +is the one that is right. + +## Obtaining and verifying the source release + +Each OpenVMM release publishes `openvmm--source.tar.gz` together with a +`SHA256SUMS` file covering it. Download both, and verify the archive before +building from it: + +```bash +sha256sum -c SHA256SUMS +``` + +Every published asset also carries a GitHub build provenance attestation, which +binds the artifact to the repository, workflow, and commit that produced it. +Unlike the checksum file, it cannot be regenerated by whoever replaced the +archive, so verify it as well: + +```bash +gh attestation verify openvmm--source.tar.gz --repo microsoft/openvmm +``` + +The archive is assembled reproducibly: the same release tag always produces +byte-identical bytes, so an independently assembled archive can be compared +against the published checksum. + +```admonish warning title="Use the published archive, not GitHub's" +GitHub generates its own "Source code (tar.gz)" link on every release page. +That archive is **not** the OpenVMM source release: it omits +`.openvmm-release.json`, so a build from it cannot recover its release identity, +and it is not covered by `SHA256SUMS` or the attestation. +``` + +## Toolchain + +The workspace declares a minimum supported Rust version (MSRV) in the root +`Cargo.toml` (`rust-version`). Building requires a Rust toolchain at least that +new. The MSRV advances over time, so confirm the current value in the source +you are packaging and require at least that Rust version in the package. + +```admonish warning title="Distribution Rust may lag the MSRV" +If the distribution's packaged `rust` is older than the workspace MSRV, `cargo` +fails during resolution — for example: + + error: package `x86emu@0.0.0` cannot be built because it requires + rustc 1.95 or newer, while the currently active rustc version is 1.90.0 + +Target a distribution whose packaged Rust meets the MSRV, or arrange a newer +toolchain in the package build environment. +``` + +## Native build dependencies + +The `openvmm` gnu binary compiles a small amount of C through build scripts and +shells out to `protoc`. The native build dependencies are: + +- a C toolchain (`gcc`, the glibc development headers, and `binutils`); +- the Linux UAPI headers (`kernel-headers`), for the bundled SQLite compiled by + `libsqlite3-sys`; +- the OpenSSL development headers, for `openssl-sys`; +- a Protocol Buffers compiler providing `protoc`, for `prost` / `pbjson`. + +```admonish note title="SymCrypt is not needed for the gnu build" +The `crypto` crate selects the OpenSSL backend on `target_os = "linux"` for +non-`musl` targets, and SymCrypt only on `musl`. The `openvmm` gnu binary +therefore does not depend on SymCrypt, `ms-tpm-20-ref`, or `mimalloc` — none of +them appear in `cargo tree -p openvmm` for the host target. Only `musl` +(OpenHCL) builds link SymCrypt. See [Crypto Backends](./crypto_backends.md). +``` + +### Azure Linux package names + +Package names differ between Azure Linux versions: + +| Need | Azure Linux 3.0 | Azure Linux 4.0 | +| --- | --- | --- | +| C toolchain | `gcc`, `glibc-devel`, `binutils` | same | +| Linux UAPI headers | `kernel-headers` | `kernel-headers` | +| OpenSSL headers | `openssl-devel` | `openssl-devel` | +| `protoc` | `protobuf` | `protobuf-compiler`, `protobuf-devel` | + +Azure Linux 3.0 ships a newer `protoc` that embeds the well-known types, so its +`protobuf` package is sufficient. Azure Linux 4.0 ships an older `protoc`, so +`protobuf-devel` is also required to supply `google/protobuf/*.proto` on disk. + +## Environment overrides + +The in-repo `.cargo/config.toml` sets `PROTOC` to a path under `.packages/` +unconditionally. A distribution build must point it at the system `protoc`. +Setting `OPENSSL_NO_VENDOR` makes `openssl-sys` link the system OpenSSL rather +than building a vendored copy: + +```bash +export PROTOC="$(command -v protoc)" +export OPENSSL_NO_VENDOR=1 +``` + +## Offline vendored build + +A package build should be reproducible and offline. The OpenVMM source release +is a source archive only: it does not carry the crate dependency tree, so the +packager produces the vendored tarball and covers it with the distribution's +own integrity metadata alongside the source archive. + +Vendor all dependencies — including the Git dependencies and the +`[patch.crates-io]` pins — into a tarball alongside the source archive: + +```bash +cargo vendor vendor/ > vendor-config.toml +``` + +`cargo vendor` captures the Git dependencies and their Git submodule C sources +(for example the `ms-tpm-20-ref` and SymCrypt submodules), so the vendored tree +is self-contained. Append the generated `[source]` redirection to +`.cargo/config.toml`, then build without network access: + +```bash +cargo build --release -p openvmm --offline +``` + +```admonish note title="Vendoring covers the whole workspace" +`cargo vendor` has no per-package scoping: it vendors every dependency in the +workspace, not just the ones the `openvmm` binary needs. A measured run +vendored 498 crates where the binary requires 254, and a large share of the +resulting tree is Windows-only crates that a Linux package never compiles. +Expect the vendored tree to be substantially larger than the build requires. +``` + +## Runtime dependencies + +The resulting binary links a small, stable set of shared libraries. Confirm the +exact set for your build with `ldd`: + +- glibc (`libc`, `libm`); +- OpenSSL (`libssl`, `libcrypto`); +- `libgcc_s`. + +Depending on the OpenSSL build, `libz` may also appear transitively; a measured +Ubuntu build did not link it. The bundled SQLite is linked statically and adds +no runtime dependency. RPM automatic dependency generation derives these from +the ELF `NEEDED` entries, so confirm the set for your own build rather than +copying a fixed list. + +## Worked example: Azure Linux RPM + +This uses a common Rust-packaging pattern: a source tarball, a `cargo vendor` +tarball, and an offline build. The distribution package version is independent +from the OpenVMM product version (see +[Independent version spaces](./openvmm_release.md#independent-version-spaces)). + +Use `openvmm--source.tar.gz` from the release as `Source0` so the build +retains its release identity through `.openvmm-release.json` — see +[Obtaining and verifying the source release](#obtaining-and-verifying-the-source-release). + +Declare the build and runtime dependencies. Require a Rust toolchain at least as +new as the workspace MSRV — read the current value from `rust-version` in the +source you are packaging rather than copying the one below: + +```spec +BuildRequires: rust >= +BuildRequires: cargo >= +BuildRequires: gcc glibc-devel binutils kernel-headers +BuildRequires: openssl-devel +BuildRequires: protobuf-compiler protobuf-devel + +Requires: glibc +Requires: openssl-libs +``` + +Build offline and install the single binary: + +```spec +%build +export PROTOC="$(command -v protoc)" +export OPENSSL_NO_VENDOR=1 +cargo build --release --offline -p openvmm \ + --target x86_64-unknown-linux-gnu + +%install +install -D -m0755 \ + target/x86_64-unknown-linux-gnu/release/openvmm \ + %{buildroot}%{_bindir}/openvmm +``` + +On Azure Linux 3.0, replace `protobuf-compiler protobuf-devel` with `protobuf`, +and confirm the packaged `rust` meets the workspace MSRV before adopting a base +version. diff --git a/Guide/src/dev_guide/contrib/openvmm_release.md b/Guide/src/dev_guide/contrib/openvmm_release.md new file mode 100644 index 0000000000..3bef1ef497 --- /dev/null +++ b/Guide/src/dev_guide/contrib/openvmm_release.md @@ -0,0 +1,461 @@ +# OpenVMM Release Model and Support + +This page describes standalone OpenVMM releases, support policy, source-build +identity, and the maintainer release runbook. OpenVMM versions are independent +from OpenHCL servicing versions. + +```admonish warning title="This model is still being implemented" +The policy on this page is settled, but the tooling behind it is not. Today +`openvmm --version` reports the Cargo package version rather than a +tag-derived identity, and the tag-triggered release automation does not exist, +so no public OpenVMM release tag should be created yet. Read +[Build identity](#build-identity), [Release assets](#release-assets), +[Building a release from source](#building-a-release-from-source), and the +[Normal release runbook](#normal-release-runbook) as the intended behavior +until the implementation lands. +``` + +Releases are phased. The initial releases publish source only, so that +downstream distributions can build and package OpenVMM from public source. +Prebuilt binary archives follow in a later phase. Sections describing the +binary phase say so explicitly. + +## One repository, two products + +OpenVMM and OpenHCL share a repository and substantial code, but they are +separate products with different release and support policies. + +| Product | Release and support model | +| --- | --- | +| OpenVMM | Cross-platform Virtual Machine Monitor. Continuous development on `main`, with standalone releases identified by OpenVMM-specific tags. | +| OpenHCL | Paravisor built on OpenVMM. Releases and in-market servicing use selected long-lived release branches. | + +```admonish note title="See also" +[OpenHCL Release Management](./openhcl_release.md) describes the OpenHCL release +branch and backport process. +``` + +## Version scheme + +OpenVMM product versions are `MAJOR.MINOR.PATCH`. Calendar months are not +encoded into the product version. + +Normal releases advance the minor version: + +```text +0.1.0 +0.2.0 +0.3.0 +``` + +Patch releases advance the patch version: + +```text +0.2.1 +0.2.2 +``` + +Before `1.0`, normal minor releases may make breaking changes to APIs, +command-line behavior, device models, snapshot formats, and other interfaces. +Breaking changes should be intentional and documented in the release notes, +with migration guidance when practical. + +The workspace minimum supported Rust version (MSRV), declared as `rust-version` +in the root `Cargo.toml`, advances over time. An MSRV increase can break +downstream builds on distributions whose packaged Rust toolchain is older, so +treat it as a breaking change: raise it in a normal minor release and call it +out in the release notes. + +A patch release corrects the currently supported minor line in isolation and +avoids breaking changes unless a fix genuinely requires one, such as an urgent +security fix that cannot be made compatibly. Servicing a line in isolation +requires stable release branches, which arrive post-`1.0`. Pre-`1.0`, OpenVMM +rolls forward from `main` instead, so patch versions — `X.Y.Z` with `Z` greater +than `0` — are not produced yet. + +## Pre-1.0 cadence and support + +Before `1.0`, maintainers target approximately one OpenVMM release per month +from a healthy `main` commit. A release may be delayed or skipped when the +candidate does not meet the quality bar. + +Only the newest OpenVMM release is supported. Fixes always land on `main` +first. Before `1.0`, every fix — including security fixes and release-blocking +regressions — reaches users by rolling forward: the fix lands on `main` and +rides the next release, cut early when it is urgent. Once a newer release +ships, the previous line leaves support. + +This support policy covers OpenVMM releases published by this project. A +distribution that packages OpenVMM sets its own support policy and commonly +holds a release for far longer, carrying fixes as distribution package +revisions against a pinned OpenVMM version. Such a package may therefore +receive a fix for a release this project no longer supports. That is a normal +downstream arrangement and does not extend upstream support for that release. + +## Release tags + +Git tags are the only source of public OpenVMM semantic versions. There is no +checked-in OpenVMM product-version file. + +Release tags use: + +```text +openvmm-vMAJOR.MINOR.PATCH +``` + +Examples: + +```text +openvmm-v0.1.0 +openvmm-v0.1.1 +openvmm-v0.2.0 +``` + +Tags must contain exactly three canonical unsigned numeric components. +Prerelease suffixes, build metadata, leading zeroes, and additional components +are rejected. + +Normal `MAJOR.MINOR.0` tags must point to commits reachable from `main`. A +patch tag must descend from its immediate predecessor. For example, +`openvmm-v0.2.2` must descend from `openvmm-v0.2.1`. + +More than one `openvmm-v*` tag on the same commit is an error. After Git checks +out a tagged commit, the source identity cannot determine which of several tags +the caller intended. Selecting the highest version could therefore make a +checkout of an older tag report a newer version. Each release commit must have +exactly one OpenVMM release tag. Pushed release tags are immutable. + +The release workflow enforces the tag format, because the version it parses +becomes the archive name and the version recorded in `.openvmm-release.json`. +It does not check commit topology or count the tags on a commit. Those rules +are the releasing maintainer's responsibility, checked while selecting the +release rather than by automation. Releases are published as drafts precisely +so a mistake of this kind is caught before anything becomes public. + +## Build identity + +OpenVMM resolves its displayed version from source identity: + +| Source state | Displayed version | +| --- | --- | +| Clean exact `openvmm-v0.2.0` tag | `0.2.0` | +| Dirty exact tag | `0.2.0+dirty` | +| Clean untagged Git checkout | `0.0.0-dev+g012345678` | +| Dirty untagged Git checkout | `0.0.0-dev+g012345678.dirty` | +| No usable Git or generated release metadata | `0.0.0-dev` | + +Git identity wins when both are present. A source tree that is inside a Git +repository is described by that repository, and generated release metadata is +consulted only when there is no usable Git identity. Initializing a Git +repository inside an extracted source archive therefore shadows the archive's +release metadata, and the build reports a development version instead of the +release it was cut from. Build the archive as extracted. + +The `g` prefix follows the `git describe` convention and identifies the +following nine characters as an abbreviated Git commit ID. It is not part of +the commit ID. + +More than one OpenVMM release tag on `HEAD` fails the build rather than +selecting an arbitrary version. + +The `openvmm-v*` namespace is reserved for canonical release tags. A tag in that +namespace that is not a canonical three-component version also fails the build +rather than being ignored, so the reserved prefix cannot be repurposed for +non-release markers such as a moving `openvmm-vnext`. + +`openvmm --version` prints the concise displayed version. The full source +revision remains available as separate embedded build information. + +A copied or exported source tree may contain neither Git metadata nor generated +release metadata. Examples include GitHub's automatic source archives and +metadata-free vendored source trees. Such a build warns that `0.0.0-dev` is not +an official release identity. The official OpenVMM source archive described +below instead includes generated release metadata and retains the exact release +identity without Git. + +Windows numeric version resources use `MAJOR.MINOR.PATCH.` for an +official release and `0.0.0.0` for a development build. The public release +binary leaves the fourth field `0`. That field is reserved for distributors who +ship more than one build of a single OpenVMM release and need each build to be +uniquely numbered. It never changes which OpenVMM release the +`MAJOR.MINOR.PATCH` prefix names. + +### Independent version spaces + +The OpenVMM product version is independent from: + +- internal Cargo crate versions; +- OpenHCL release and servicing versions; +- distribution package versions; +- CI build counters; +- source revision identifiers. + +Build and distribution systems may record package versions, build IDs, and +source revisions as additional metadata. They must not present those values as +the OpenVMM product version. + +## Release assets + +### Source release + +Every release publishes: + +- `openvmm--source.tar.gz`; +- `SHA256SUMS`. + +The source archive contains `.openvmm-release.json` at its root, recording the +metadata schema, release version, release tag, and full source revision. A +build from this archive retains the exact release identity without a `.git` +directory, which is what makes it the supported input for downstream +packagers. See +[Packaging OpenVMM for a Linux Distribution](./openvmm_packaging.md). + +`SHA256SUMS` covers every archive in the release. Every archive and `SHA256SUMS` +receives a public GitHub build provenance attestation before the release is +published. + +The archive is a source release, not a vendored build environment. It does not +carry the crate dependency tree. A packager producing an offline build vendors +dependencies themselves and covers that vendored tarball with their own +distribution integrity metadata. + +### Binary archives + +```admonish note title="A later phase" +The initial releases do not publish prebuilt binaries. This section describes +the intended binary release once that phase begins. +``` + +The binary phase adds four targets, each with a separate runtime and symbol +archive: + +- `openvmm--windows-x64.zip`; +- `openvmm--windows-x64-symbols.zip`; +- `openvmm--windows-arm64.zip`; +- `openvmm--windows-arm64-symbols.zip`; +- `openvmm--linux-x64-musl.tar.gz`; +- `openvmm--linux-x64-musl-symbols.tar.gz`; +- `openvmm--linux-arm64-musl.tar.gz`; +- `openvmm--linux-arm64-musl-symbols.tar.gz`. + +Runtime archives contain the runnable binary and `LICENSE`. Symbol archives +contain the matching debug symbols and `LICENSE`. Linux runtime binaries retain +executable permissions. The prebuilt Linux binaries are statically linked +`musl` builds, which differ from the dynamically linked glibc build a Linux +distribution package produces. + +```admonish warning title="Windows signing is a prerequisite for this phase" +The release workflow cannot Authenticode-sign Windows artifacts today. +Publishing unsigned Windows executables is not acceptable, so Authenticode +signing must land before the binary phase begins. Deferring binaries keeps this +off the critical path for the source release, whose integrity comes from +`SHA256SUMS` and the build provenance attestations. +``` + +## Building a release from source + +Building from source is the primary supported way to consume an OpenVMM +release today. Distributors packaging OpenVMM for an operating system should +read [Packaging OpenVMM for a Linux Distribution](./openvmm_packaging.md), +which covers the distribution build configuration, native dependencies, and +offline vendoring. + +A real Git checkout with the exact release tag available derives its version +directly from Git: + +```bash +git clone https://github.com/microsoft/openvmm.git +cd openvmm +git checkout openvmm-v0.2.0 +``` + +Build OpenVMM from the checkout with Cargo: + +```bash +cargo build +``` + +See [Building OpenVMM](../getting_started/build_openvmm.md) for prerequisites +and additional build options. + +A build from `openvmm--source.tar.gz` needs no Git checkout: the +`.openvmm-release.json` the archive carries supplies the same release identity. + +```admonish warning title="Use the official source archive" +GitHub's automatic "Source code (zip)" and "Source code (tar.gz)" links omit Git +metadata and do not preserve the OpenVMM release identity. A build from one of +them reports a development version rather than the release it was cut from. +They are convenience snapshots, not supported version-preserving build inputs. +Use a real checkout of the release tag or `openvmm--source.tar.gz`. +``` + +## Normal release runbook + +Tag creation starts the release, but it does not complete it. The workflow +publishes a **draft** GitHub Release, which a maintainer reviews and publishes +by hand. Releasing is new enough that a human should look at the assembled +release before it becomes public. + +### 1. Select the release + +Choose a healthy commit already on `main`. Confirm that: + +- required changes are merged; +- required CI checks pass; +- the next normal version follows the release sequence; +- the version has not already been released; +- the commit is suitable for public release. + +Do not create the tag while required changes or checks are outstanding. + +### 2. Create and push the tag + +Update local `main`, confirm the working tree is clean, and create an annotated +tag. For example: + +```bash +git switch main +git pull --ff-only +git status --short +version="0.2.0" +tag="openvmm-v${version}" +git tag -a "${tag}" -m "OpenVMM ${version}" +git push origin "${tag}" +``` + +Do not move, delete, or recreate a pushed release tag. + +### 3. Monitor the workflow + +The tag starts the OpenVMM release workflow. The workflow: + +1. builds `openvmm` from the assembled source release in the configuration a + distribution packages it in, before publishing rather than after; +2. assembles the official source archive, including `.openvmm-release.json`; +3. creates `SHA256SUMS`; +4. attests the archive and the checksum file; +5. publishes a **draft** GitHub Release with generated notes. + +Both jobs resolve the release identity from the same tag through the same code, +and assembly is reproducible, so the archive the first job proved buildable and +the archive the second job publishes are byte-for-byte identical. + +Once the binary phase begins, the workflow also builds Windows x64, Windows +ARM64, Linux musl x64, and Linux musl ARM64, and creates a separate runtime and +symbol archive for each before checksumming and attesting. + +If a build, packaging, checksum, or attestation step fails, no release is +created, and the same immutable tag may be rerun. + +If a release already exists for the tag, the workflow fails rather than +reporting success without doing anything. To regenerate a draft, delete it and +rerun the workflow. A published release is never modified: correct a bad +published release with a new version rather than mutating it. + +### 4. Confirm the draft + +Before publishing, confirm that: + +- the release page points to the intended tag and revision; +- the official source archive is present; +- the source archive contains `.openvmm-release.json` naming the intended + release version, tag, and revision; +- a build from the extracted source archive reports the release version; +- `SHA256SUMS` covers every published archive; +- every archive and `SHA256SUMS` has a provenance attestation; +- generated notes cover the intended pull requests, including any change to the + minimum supported Rust version; +- the release is presented as the newest supported OpenVMM release. + +Once the binary phase begins, also confirm that all four targets have separate +runtime and symbol archives and that every runtime and symbol archive contains +`LICENSE`. + +After downloading all assets into one directory, verify the checksums: + +```bash +sha256sum -c SHA256SUMS +``` + +Verify an asset's provenance with the GitHub CLI: + +```bash +gh attestation verify path/to/ --repo microsoft/openvmm +``` + +Once the binary phase begins, smoke-test runnable archives on compatible hosts +where practical. At minimum, confirm that the executable starts and reports the +expected version. + +### 5. Publish the release + +Publish the draft from the release page, or with the GitHub CLI: + +```bash +gh release edit "openvmm-v${version}" --repo microsoft/openvmm --draft=false +``` + +Publishing is the point of no return. The workflow will refuse to replace the +assets of a published release, so a mistake found after this point is corrected +with a new version rather than by mutating what was published. + +## Patch release runbook + +```admonish note title="Post-1.0: requires stable release branches" +This runbook applies once OpenVMM adopts post-`1.0` stable release branches for +servicing an older in-support line. Pre-`1.0`, fixes instead roll forward in the +next release from `main` and no patch branches are created — see +[Pre-1.0 cadence and support](#pre-10-cadence-and-support). This process mirrors +the OpenHCL [release branch model](./openhcl_release.md). +``` + +OpenVMM does not create a release branch for every normal release. Create a +patch branch only when the currently supported release requires a security or +release-blocking fix. + +1. Implement and merge the fix into `main`. +2. Create a temporary patch branch from the currently supported release tag. +3. Cherry-pick the fix onto that branch. +4. Validate the branch and the affected release artifacts. +5. Tag the corrected commit with the next patch version. +6. Push the tag and monitor the normal automatic release workflow. + +For example: + +```bash +git switch main +git pull --ff-only +git switch -c patch/openvmm-0.2.x openvmm-v0.2.0 +git cherry-pick +git tag -a openvmm-v0.2.1 -m "OpenVMM 0.2.1" +git push origin openvmm-v0.2.1 +``` + +Further patches must branch from or include their immediate predecessor. For +example, `openvmm-v0.2.2` must descend from `openvmm-v0.2.1`. + +The patch branch is not a new general development branch. New work continues +on `main`, and the older line leaves support when the next normal release +ships. + +## Reporting security issues + +Do not report security vulnerabilities through public GitHub issues, pull +requests, or discussions. Report them privately through the Microsoft Security +Response Center (MSRC) as described in the repository +[`SECURITY.md`](https://github.com/microsoft/openvmm/blob/main/SECURITY.md). + +Before `1.0`, a confirmed security issue in the currently supported OpenVMM +release ships in the next release rolled forward from `main`, cut early when the +fix is urgent. Post-`1.0`, once stable release branches exist, it instead ships +as a patch following the [patch release runbook](#patch-release-runbook). + +## Future policy + +The project may later designate selected releases for longer support, but no +LTS policy exists yet. Before supporting multiple OpenVMM lines or publishing +`1.0.0`, maintainers must document the compatibility, deprecation, +support-window, and servicing commitments. + +Public nightly releases are deferred until a concrete consumer requires them. +Ordinary CI artifacts remain available for engineering use. diff --git a/Guide/src/dev_guide/contrib/save-state.md b/Guide/src/dev_guide/contrib/save-state.md index d373b38361..f3c823d7b6 100644 --- a/Guide/src/dev_guide/contrib/save-state.md +++ b/Guide/src/dev_guide/contrib/save-state.md @@ -89,4 +89,4 @@ pub mod save_restore { ``` [^1]: Saved state is in use when it reaches a release branch that is in tell - mode. See [release management](./release.md) for details. + mode. See [release management](./openhcl_release.md) for details.