文档目录开发 · 18 篇

文档/开发

06

贡献指南

向 NVX 提交代码、编写提交信息与发起 PR 的规范。

译自microsoft/nvx · doc/contribute.md。技术细节以英文原文为准。

NVX 通过向 microsoft/nvx 的 dev 分支发起 PR 来接受贡献。本指南涵盖工作流、审查者期望的约定、质量门禁、测试归属,以及 OpenVMM 更改如何进入 NVX。按 SECURITY.md 所述报告安全漏洞,绝不要在公共 issue 中报告。

工作流

  1. 克隆仓库及其 OpenVMM 子模块,并运行 scripts/nvx.py verify,如环境准备所述。
  2. 从 dev 创建主题分支。
  3. 进行更改,同时包含其测试和文档,然后运行覆盖它的质量门禁和测试。
  4. 以草稿或就绪审查状态向 dev 发起 PR。
  5. 处理审查,直到 PR 满足下面的合并规则。

dev 上的分支规则要求一次批准审查、每个审查线程都已解决,以及通过的 Required status check——该 CI 作业确认更改调度的每个作业都成功。Copilot 会审查每次推送,包括草稿。PR 以合并提交合并,因此分支上的每个提交都会进入 dev;给每个提交一个遵循约定的主题。

CI 只对推送和同仓库 PR 运行需要 OpenVMM 部署密钥或 hypervisor runner 的作业,包括 NVX CLI 测试。来自 fork 的 PR 运行其余 GitHub 托管的检查,维护者会将其暂存到 microsoft/nvx 分支以运行剩余部分;见作业图与 runner 容量。

提交与 PR

项目 约定
提交主题 area: summary,其中 area 是发生更改的组件、命令或目录,例如 doc、ci、guest、sandbox 或 openvmm。摘要以小写祈使动词开头,并省略末尾句号:ci: run each OpenVMM suite only when its inputs change。
提交正文 当主题不足以说明时,说明更改了什么以及为什么。
PR 标题 单提交 PR 的提交主题;否则使用相同形式的摘要。
PR 正文 更改了什么以及为什么,然后是一个 Validation 部分,列出你运行的检查和留给 CI 的门禁,例如你无法测试的后端。
Issue 引用 当 PR 完成该 issue 时,将 Closes #N 或 Fixes #N 放在最前;否则使用 Part of #N 或 Refs #N。
审查线程 用处理该评论的提交回复,或用无需更改的证据回复,然后解决该线程。

将 data/*.csv 中的性能历史留给 CI:成功的 dev 推送会追加到其中。

草稿或就绪

当发往 dev 的 PR 被打开、重新打开、推送或标记为就绪审查时,CI 会运行;当 PR 是草稿时,会跳过其 lint、构建和测试作业。新的推送会取消 PR 正在进行的运行;将其重新转换为草稿则不会。更改不止文档的就绪 PR 会占用共享的自托管 KVM、MSHV 和 WHP runner 池,因此:

  • 当更改涉及的不仅仅是文档,且尚未通过覆盖它的质量门禁和测试时,打开草稿。通过后将其标记为就绪。
  • 否则以就绪打开。仅文档更改(每个路径都在 doc/ 下或以 .md 结尾)会跳过客户机产物、OpenVMM 构建和每个 hypervisor 作业;见变更分类。

质量门禁

CI 在 GitHub 托管的 runner 上运行这些检查。推送前运行覆盖你更改的检查;环境准备列出了 Python、shell 和链接检查的命令。

代码 检查 定义
scripts/ 和 .github/specula/ 中的 Python 使用 88 列行的 Ruff lint 和格式检查;在 scripts/ 上针对 Linux 和 Windows API 运行严格模式 Pyright;以及 Specula 接线测试。代码目标为 Python 3.10。 check-quality、pyproject.toml
客户机和安装 shell 脚本 ShellCheck,以及使用四空格缩进和缩进 case 分支的 shfmt。除非 check-quality 将其作为 Bash 检查,脚本为 POSIX sh。 check-quality
scripts/setup/setup-windows-whp.ps1 PowerShell 语法 check-quality
Markdown 文件和 doc/ 路径 受跟踪 Markdown 文件中的每个相对链接和图像都解析到受跟踪文件,每个锚点都解析到 GitHub 生成的标题 slug(忽略代码)。受跟踪文件提到的每个 doc/ 路径也会解析,但 DOC_PATH_FIXTURES 列出的测试夹具除外。 check-quality、check_markdown_links.py
aci_edge_sandboxes/ rustfmt、以警告即错误运行的 Clippy 和 rustdoc、测试,以及最低支持的 Rust 版本;见 Rust crate check-aci-edge-sandboxes
nvx-rs/ rustfmt、以警告即错误运行的 Clippy 和 rustdoc、包括捆绑发布版夹具的测试、最低支持的 Rust 版本、macOS 检查,以及通过 nvx.py 对客户机二进制进行的 musl lint、测试、构建、摘要清单和静态 ELF 检查;见 Rust crate check-nvx-rs
NVX CLI 在 Linux 和 Windows 上编译 scripts/、运行每个 scripts/test_*.py 模块,并检查命令帮助 validate-nvx

check-quality 会列出它检查的每个 shell 脚本,并且除非 validate-nvx 在两个操作系统上运行每个 scripts/test_*.py 模块,否则 CLI 测试会失败,因此请将新的脚本或测试模块添加到这些列表中。

测试归属

OpenVMM 拥有控制平面覆盖。用 scripts/nvx.py test-openvmm-unit 运行其单元和文档测试,用 scripts/nvx.py test-openvmm --backend BACKEND 运行其 VMM 测试。VMM 测试启动 OpenVMM 自己的测试客户机,但管理 RPC(TTRPC)生命周期、SMP 和快照测试除外——当 test-openvmm 运行它时,它会启动 NVX 的内核和 Alpine initramfs。

NVX 拥有依赖于其打过补丁的 Linux 内核、其 Alpine、Ubuntu 和 Azure Linux 用户态、客户机二进制和脚本、SMP 行为或 virtio 设备的行为。将这些场景添加到 scripts/nvx_tools/microvm_tests.py,并用 scripts/nvx.py test-microvm --backend BACKEND 运行它们。将客户机工作负载保留在 scripts/nvx_tools/microvm_test_scripts 中,并保留完整的失败日志。驱动公共 nvx.py sandbox 命令的场景位于 scripts/nvx_tools/managed_exec_tests.py 和 scripts/nvx_tools/sandbox_lifecycle_tests.py,microvm_tests.py 注册它们。nvx.py sandbox 和控制协议属于 nvx-rs(microsoft/nvx#359),因此这些场景将它们作为命令驱动,用 nvx-rs egress compile 编译出站策略,并将控制会话留给 nvx-rs:managed-lifecycle 场景构建 OpenVMM 的命令行并运行被忽略的 nvx-rs 测试 tests/managed_lifecycle.rs,后者驱动客户机。不要添加控制协议、生命周期或出站逻辑的 Python 客户端。

宿主工具的单元测试位于 scripts/test_*.py。aci_edge_sandboxes 和 nvx-rs crate 在其 Rust 源码旁保留单元测试,并在其 tests 目录中保留集成测试。后者还针对精确的客户机 profile 二进制运行 tests/guest_tools.rs。NVX 机制的测试(例如控制协议的黄金测试夹具)属于 nvx-rs,ACI Edge Sandboxes 约定的测试属于 aci_edge_sandboxes。scripts/nvx.py test-aci-edge-sandboxes --backend BACKEND 命令在真实 hypervisor 上运行所有被忽略的 openvmm_e2e 测试,这会检验两个 crate;scripts/nvx.py test-agent-bundling 在没有 hypervisor 的情况下检查该 crate 的代理捆绑暂存。持续集成描述了 OpenVMM VMM 测试和 NVX 微虚拟机套件覆盖的内容。

OpenVMM

访问

openvmm/ 是公共 microsoft/openvmm 仓库的 Git 子模块。.gitmodules 记录其 URL 和跟踪的 feature/microvm/dev 分支,每个 NVX 提交固定一个精确修订版。使用 --recurse-submodules 克隆,或在现有检出中运行 scripts/nvx.py init,如环境准备所述。在子模块以固定修订版检出之前,scripts/nvx.py verify 会失败。早于从 nanvix/openvmm 迁移的检出会继续从那里获取,直到 git submodule sync -- openvmm 采用记录的 URL。

源码更改

通过向 microsoft/openvmm 的 feature/microvm/dev 分支发起 PR 来更改 OpenVMM,该 PR 遵循其贡献者说明,包括其 Clippy、rustdoc、测试和格式检查,然后将审查过的修订版提升到 NVX。

feature/microvm/dev 在 microsoft/openvmm 的 main 分支之上承载微虚拟机提交。OpenVMM 上游路线图将这些提交分组为计划发往 main 的 PR,并标记那些保留为仅 fork 的提交。

固定版本提升

固定版本提升将 openvmm gitlink 移动到一个经过审查的 OpenVMM 修订版:

  • 使提升成为直接基于当前 dev 的单提交主题分支;除非该修订版需要协调的 NVX 更改,该提交应只更改 gitlink,主题如 openvmm: pin auto's fallback to host CPU profiles。绝不将 OpenVMM 历史合并到 NVX。
  • 提交后,运行 scripts/nvx.py verify,它检查子模块检出是否与记录的固定版本匹配。
  • 在 PR 中,指明 OpenVMM PR 和精确固定的 SHA、范围与任何前置修订版,以及你运行的验证。
  • gitlink 更改是每个 CI 套件的输入,因此其 PR 会运行完整矩阵,包括两个 OpenVMM 套件。
  • 当 rebase 在 gitlink 上冲突时,不要选择任何一方:合并两个更改通常需要一个新的 OpenVMM 修订版。

nvx-openvmm-promote 技能给出了完整过程,包括如何证明替换修订版与已审查版本匹配。