Repository navigation
ci: check OpenVMM's own CI instead of running OpenVMM's tests - #1074
Merged
Pedro Henrique Penna (ppenna) merged 3 commits intoOct 31, 2026
Merged
Conversation
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The polling loop delays reporting failed or missing required jobs while other jobs remain pending, potentially for 300 minutes, contrary to documented fail-fast behavior; it needs an immediate return and mixed-result regression coverage.
1 open issue
What changed in this PR
This PR replaces NVX’s duplicate OpenVMM test jobs with a check of upstream CI results for the pinned revision, reducing runner usage while retaining local test commands.
Changes:
- Adds
check-openvmm-cito verify six required upstream jobs, with polling and evidence summaries. - Updates CI selection, required results, release gates, and cache saves.
- Removes CI-only test packaging and sharding tools, and documents the new workflow.
| File | Description |
|---|---|
scripts/nvx.py |
Registers the upstream check and removes obsolete CLI options. |
scripts/nvx_tools/shard_plans.py |
Updates the docstring to reflect its remaining microVM use. |
scripts/nvx_tools/openvmm_test_shards.py |
Removes the OpenVMM test shard planner. |
scripts/nvx_tools/openvmm_test_shards.json |
Removes the OpenVMM shard configuration. |
scripts/nvx_tools/openvmm_ci.py |
Adds upstream job verification, polling, and reporting. |
scripts/nvx_tools/ci.py |
Updates change selection and required results; removes test handoff code. |
nvx-rs/README.md |
Updates guest-image and test-selection documentation. |
doc/usage.md |
Documents the new command and removes retired command details. |
doc/project-structure.md |
Adds the upstream checker to the module listing. |
doc/contribute.md |
Clarifies upstream test ownership and local commands. |
doc/ci.md |
Documents upstream verification and the revised CI structure. |
.github/workflows/ci.yml |
Replaces five test jobs with the upstream CI check. |
.github/skills/nvx-openvmm-promote/SKILL.md |
Adds upstream CI evidence to pin-promotion guidance. |
.github/copilot-instructions.md |
Directs OpenVMM test validation to upstream CI. |
.github/actions/build-openvmm/action.yml |
Saves input and Cargo caches after uncached builds on dev pushes. |
Review effort: Balanced
NVX pins a revision of feature/microvm/dev in microsoft/openvmm, whose checkin gates test it: since OpenVMM's c2722fbcd of 2026-10-21, the OpenVMM PR workflow runs them on each pull request into the branch that is ready for review, and the OpenVMM CI workflow on each push to it. Nothing on OpenVMM's side requires them to pass, though: the branch has no required status check, a pull request lands by a push of its head, and every OpenVMM CI run of the branch from 2026-10-25 to 2026-10-30 failed in the VMM tests of OpenHCL and confidential VMs on its TDX and SEV-SNP hosts, which NVX does not use. A run's conclusion therefore says little about the jobs that matter to NVX. nvx.py check-openvmm-ci reads the runs of those two workflows whose head is, in microsoft/openvmm, the revision that the checkout's index pins or the one that --revision names, with the latest attempt of each of their jobs. It requires the jobs that cover NVX's use of OpenVMM to have passed in at least one of those runs: unit tests [x64-linux] and [x64-windows], and run vmm-tests [x64-linux-amd-kvm], [x64-linux-intel-mshv], [x64-windows-intel], and [x64-windows-amd]. It ignores the runs of pull requests from forks, which run the fork's copy of the workflows. A job is pending while a run that has not finished may still pass it, since a run creates a job only once the jobs that it needs finish; failed when every run that ran it finished it without passing; and missing when no run will run it. With --wait-minutes, the command looks again every five minutes while a job is pending, and after a look that failed, at most twice in a row, for at most that long. It prints each verdict with the job that decided it, appends the verdicts as a table to the --summary file, such as the step summary, and fails with a GitHub error for each job that did not pass. It reads the public repository through the nightly report's GitHub client, with GH_TOKEN or GITHUB_TOKEN when one is set. For the current pin, 3d7512af6, the pull request's and the branch's runs both passed all six jobs; for a pull request whose Windows VMM tests still ran, the check reported those two as pending, and for a commit that no run tested, all six as missing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Five jobs built and ran OpenVMM's unit tests and a selection of its VMM tests on the NVX runners: build-openvmm-vmm-tests-linux and -windows, openvmm-vmm-tests-linux and -windows, the latter in two shards, and openvmm-unit-tests. From 2026-10-21 to 2026-10-31 they ran in 673 runs and took about 620 runner-hours, 517 of them on the KVM, MSHV, and WHP runners. They failed 9 times, never for a defect in OpenVMM: 4 times for an NVX script error on a dispatched branch, once for a WHP runner that lost its connection, and 4 times for flaky tests that passed on the same OpenVMM revision in other runs. OpenVMM's own checkin gates run every test that those jobs ran, on OpenVMM's runners, on each pull request into feature/microvm/dev that is ready for review and on each push to it, but for two differences. OpenVMM's KVM job, on AMD hosts, skips the 4 emulated Intel VT-d tests that NVX's KVM job ran, which OpenVMM's MSHV and Windows Intel jobs run. And the gates' TTRPC microVM test boots OpenVMM's own kernel at one processor, where NVX's jobs booted NVX's kernel at one, two, four, and eight; NVX uses no TTRPC, and the NVX microVM tests boot and restore NVX's kernel at those processor counts on every backend. CI therefore runs none of OpenVMM's tests. The GitHub-hosted openvmm-ci job runs check-openvmm-ci on the pinned revision instead. It reads only the public repository's runs, so it needs neither an OpenVMM checkout nor the deploy key, and pull requests from forks run it too. A pull request, whose pin promotion usually starts before OpenVMM's gates finish with the pin, which takes them one and a half to two hours, and a manual run wait up to 300 minutes for the gates. A merge group, a dev push, and a scheduled run check a pin whose pull request passed the check, so they fail at once rather than hold up the merge groups and dev pushes that queue behind them. The change detector replaces run-openvmm-unit-tests and run-openvmm-vmm-tests with run-openvmm-ci-check, which a change to the OpenVMM pin, ci.yml, nvx.py, or the check's modules sets. Required status check expects openvmm-ci to succeed whenever the output is set and to be skipped otherwise, and the development release and the recording of the performance results require it to succeed, or to be skipped because the change selected no check. The guest artifacts are built only for the jobs that boot them. The VMM tests' build-only content, its cache, its sharding, and its test duration reports served only those jobs, so build-openvmm-tests, openvmm-test-cache-key, check-openvmm-tests, reuse-openvmm-tests, plan-openvmm-test-shards, test-openvmm's --content and --shard, and the partition of the WHP tests' shards go too. test-openvmm and test-openvmm-unit still build and run OpenVMM's tests on a developer's host. The removed jobs were the only ones that saved the OpenVMM input and Cargo caches that the OpenVMM binary builds restore, so build-openvmm now saves them when a dev push's build misses its binary cache. doc/ci.md replaces the sections on the VMM tests, their cache, and their shards with one on OpenVMM CI, and doc/usage.md, doc/contribute.md, doc/project-structure.md, the Copilot instructions, and the nvx-rs README follow. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
NVX CI no longer runs OpenVMM's tests: its openvmm-ci job requires OpenVMM's checkin gates to have passed the x86-64 Linux and Windows unit tests and the KVM, MSHV, and Windows VMM tests for the pinned revision, in an OpenVMM PR or OpenVMM CI run whose head is that revision in microsoft/openvmm. An OpenVMM pull request gets those runs only once it is ready for review and its branch is in microsoft/openvmm. The promotion skill now says so, and records that evidence with check-openvmm-ci before relying on NVX CI: a pending job means that OpenVMM's CI still runs, and a failed one needs a rerun or a fix in OpenVMM. It also says that the pull request's openvmm-ci job waits up to 300 minutes for OpenVMM's CI of the pin, and that after a failed OpenVMM job, that job and then openvmm-ci need a rerun. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pedro Henrique Penna (ppenna)
force-pushed
the
agents/pin-microvm-dev-branch-openvmm-ci
branch
from
October 31, 2026 04:59
3757abb to
6c8815c
Compare
Contributor
There was a problem hiding this comment.
🔵 Needs a closer look
The sole replacement gate still needs an exact-head NVX CI run to verify cross-repository OpenVMM Actions access using the restricted GITHUB_TOKEN, including on fork PRs.
No open issues 🎉
1 resolved since last review
Review effort: Balanced
Pedro Henrique Penna (ppenna)
marked this pull request as ready for review
October 31, 2026 05:04
Pedro Henrique Penna (ppenna)
deleted the
agents/pin-microvm-dev-branch-openvmm-ci
branch
October 31, 2026 05:51
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.

NVX CI stops building and running OpenVMM's unit and VMM tests. A new GitHub-hosted job,
openvmm-ci, checks instead that OpenVMM's own CI passed the OpenVMM revision that NVX pins. Developers can still run OpenVMM's tests locally withtest-openvmmandtest-openvmm-unit.Based on
devat23ad26729.Why
NVX pins
feature/microvm/dev, and OpenVMM's own CI already tests that branch:.gitmodulestracksfeature/microvm/dev, and theopenvmmgitlink,3d7512af6, is the branch's tip (the head of [DO NOT REVIEW] vmm_tests: run the KVP IC test on Windows Server 2025 (port of #4803) openvmm#4816).c2722fbcd(2026-10-21), OpenVMM's checkin gates trigger onfeature/microvm/**:openvmm-pr.yamlruns on each pull request into the branch that isn't a draft.openvmm-ci.yamlruns on each push to the branch.The OpenVMM jobs in NVX CI ran tests that OpenVMM's gates also run, and they cost a lot. From 2026-10-21 to 2026-10-31 (1,034 NVX CI runs):
build-openvmm-vmm-tests-linuxandbuild-openvmm-vmm-tests-windowsopenvmm-vmm-tests-linuxandopenvmm-vmm-tests-windows(WHP in two shards)openvmm-unit-testsSyntaxErroron a dispatched branch;Coverage
On the same pin, OpenVMM's gates run every test that NVX's jobs ran, with two differences:
What changed
scripts: add check-openvmm-ci to check OpenVMM's CI of a revisionscripts/nvx_tools/openvmm_ci.pyandnvx.py check-openvmm-ci, with tests and documentation indoc/usage.mdanddoc/project-structure.md.ci: check OpenVMM's own CI instead of running OpenVMM's testsopenvmm-ci. The change detector'srun-openvmm-unit-testsandrun-openvmm-vmm-testsoutputs becomerun-openvmm-ci-check, and the required-results policy changes to match. Removes the CI-only plumbing (details below), adds cache saves tobuild-openvmm, and updatesdoc/ci.md,doc/usage.md,doc/contribute.md, the Copilot instructions, and the nvx-rs README.doc: check OpenVMM's CI of the pin when promoting itnvx-openvmm-promoteskill gather the check's evidence before merging a pin promotion.The CI-only plumbing that the second commit removes:
build-openvmm-tests,openvmm-test-cache-key,check-openvmm-tests,reuse-openvmm-tests, andplan-openvmm-test-shards;test-openvmm's--contentand--shardoptions;openvmm_test_shards.pyandopenvmm_test_shards.json.How the check works
The check reads
GET /repos/microsoft/openvmm/actions/runs?head_sha=…for the pinned SHA. It keeps only runs of the two gate workflows whose head repository is microsoft/openvmm, then reads each run's latest job attempts.Required jobs: six jobs cover NVX's use of OpenVMM:
unit tests [x64-linux]andunit tests [x64-windows];run vmm-tests [x64-linux-amd-kvm],[x64-linux-intel-mshv],[x64-windows-intel], and[x64-windows-amd].Each must have passed in a run of either workflow. A required name matches one whole comma-separated part of a job name, because the two workflows name their unit-test jobs differently.
Excluded jobs: the gates' TDX, SEV-SNP, and other OpenHCL or confidential-VM jobs aren't required, because NVX uses none of those features. OpenVMM's push CI on the branch has failed in those jobs since 10-25.
Verdicts:
passed,pending(a job hasn't finished, or a run hasn't listed it yet),failed, ormissing.Waiting:
pull_requestandworkflow_dispatch, the job waits up to 300 minutes, checking every 5 minutes, because a pin promotion usually opens before OpenVMM's gates finish (about 1.5 to 2 hours).openvmm-ci.devpushes, and scheduled runs check a pin that already passed in its pull request, so they fail at once instead of delaying the queue.Access: the job uses no secrets and no OpenVMM checkout, so pull requests from forks run it too.
Triggers: it runs when the pin,
ci.yml,nvx.py, or the check's modules change (openvmm_ci.py,nightly_ci.py,common.py,build_constants.py,__init__.py).Results policy:
Required status checkexpects the job to succeed when its output is set, and to be skipped otherwise.performance-record) need it to succeed, or to be skipped because the change selected no check.Reviewers should know
${{ github.token }}to read microsoft/openvmm's public Actions runs. This PR's CI confirmed that the default token can read them: itsopenvmm-cijob passed in 11 seconds. A fork's pull request gets a read-only token, which reads public data the same way. Without a token, the check works anonymously (I verified this locally) but under a lower rate limit.build-openvmmnow saves them on adevpush whose build misses the binary cache.doc/ci.mdupdates the runner-capacity and job-graph sections to match.Validation
ruff checkandruff format --check,pyrightfor Linux and for Windows, andcheck_markdown_links.pypass on every commit.validate-nvxruns pass locally on Windows: 1,638 tests, 73 skipped.test_adversarial.py(84 tests) and the host-connect tests (4) pass too.test_nvx_tools.py,test_nightly_ci.py, and the docs tests, 813 tests in all.3d7512af6. All six jobs passed in OpenVMM run 41143115866.pendingfor an OpenVMM pull request whose gates were still running, andmissingfor a commit that no gate had tested.6c8815c23passed: 34 jobs succeeded, and the 8 skipped jobs run only ondevpushes, merge groups, or full runs. Itsopenvmm-cijob found all six required jobs passed for3d7512af6.