1use flowey::node::prelude::AdoResourcesRepositoryId;
7use flowey::node::prelude::FlowPlatformLinuxDistro;
8use flowey::node::prelude::GhPermission;
9use flowey::node::prelude::GhPermissionValue;
10use flowey::node::prelude::ReadVar;
11use flowey::pipeline::prelude::*;
12use flowey_lib_common::git_checkout::RepoSource;
13use flowey_lib_hvlite::_jobs::build_and_publish_openhcl_igvm_from_recipe::OpenhclIgvmBuildParams;
14use flowey_lib_hvlite::build_openhcl_igvm_from_recipe::OpenhclIgvmRecipe;
15use flowey_lib_hvlite::build_openvmm_hcl::OpenvmmHclBuildProfile;
16use flowey_lib_hvlite::run_cargo_build::common::CommonArch;
17use flowey_lib_hvlite::run_cargo_build::common::CommonPlatform;
18use flowey_lib_hvlite::run_cargo_build::common::CommonProfile;
19use flowey_lib_hvlite::run_cargo_build::common::CommonTriple;
20use std::collections::BTreeMap;
21use std::path::PathBuf;
22use target_lexicon::Triple;
23use vmm_test_images::KnownTestArtifacts;
24
25#[derive(Copy, Clone, clap::ValueEnum)]
26enum PipelineConfig {
27 Pr,
29 Ci,
34 PrRelease,
36}
37
38#[derive(clap::Args)]
41pub struct CheckinGatesCli {
42 #[clap(long)]
44 config: PipelineConfig,
45
46 #[clap(flatten)]
47 local_run_args: Option<crate::pipelines_shared::cfg_common_params::LocalRunArgs>,
48
49 #[clap(long)]
51 vmm_tests_disk_cache_dir: Option<PathBuf>,
52}
53
54impl IntoPipeline for CheckinGatesCli {
55 fn into_pipeline(self, backend_hint: PipelineBackendHint) -> anyhow::Result<Pipeline> {
56 let Self {
57 config,
58 local_run_args,
59 vmm_tests_disk_cache_dir,
60 } = self;
61
62 let release = match config {
63 PipelineConfig::Ci | PipelineConfig::PrRelease => true,
64 PipelineConfig::Pr => false,
65 };
66
67 let mut pipeline = Pipeline::new();
68
69 let mut vmgstools = BTreeMap::new();
70
71 {
73 let branches = vec!["main".into(), "release/*".into()];
74 match config {
75 PipelineConfig::Ci => {
76 pipeline
77 .gh_set_ci_triggers(GhCiTriggers {
78 branches,
79 ..Default::default()
80 })
81 .gh_set_name("OpenVMM CI");
82 }
83 PipelineConfig::Pr => {
84 pipeline
85 .gh_set_pr_triggers(GhPrTriggers {
86 branches,
87 ..GhPrTriggers::new_draftable()
88 })
89 .gh_set_name("OpenVMM PR")
90 .ado_set_pr_triggers(AdoPrTriggers {
91 branches: vec!["main".into(), "release/*".into(), "embargo/*".into()],
92 ..Default::default()
93 });
94 }
95 PipelineConfig::PrRelease => {
96 let mut triggers = GhPrTriggers::new_draftable();
98 triggers.branches = branches;
99 triggers.types.push("labeled".into());
100 pipeline
101 .gh_set_pr_triggers(triggers)
102 .gh_set_name("[Optional] OpenVMM Release PR");
103 }
104 }
105 }
106
107 let openvmm_repo_source = match backend_hint {
108 PipelineBackendHint::Local => {
109 RepoSource::ExistingClone(ReadVar::from_static(crate::repo_root()))
110 }
111 PipelineBackendHint::Github => RepoSource::GithubSelf,
112 PipelineBackendHint::Ado => {
113 RepoSource::AdoResource(AdoResourcesRepositoryId::new_self())
114 }
115 };
116
117 if let RepoSource::GithubSelf = &openvmm_repo_source {
118 pipeline.gh_set_flowey_bootstrap_template(
119 crate::pipelines_shared::gh_flowey_bootstrap_template::get_template(),
120 );
121 }
122
123 if let RepoSource::AdoResource(source) = &openvmm_repo_source {
124 pipeline.ado_set_flowey_bootstrap_template(
125 crate::pipelines_shared::ado_flowey_bootstrap_template::get_template_ado(source),
126 );
127 }
128
129 let cfg_common_params = crate::pipelines_shared::cfg_common_params::get_cfg_common_params(
130 &mut pipeline,
131 backend_hint,
132 local_run_args,
133 )?;
134
135 pipeline.inject_all_jobs_with(move |job| {
136 let mut job = job
137 .dep_on(&cfg_common_params)
138 .dep_on(|_| flowey_lib_hvlite::_jobs::cfg_versions::Request::Init)
139 .dep_on(
140 |_| flowey_lib_hvlite::_jobs::cfg_hvlite_reposource::Params {
141 hvlite_repo_source: openvmm_repo_source.clone(),
142 },
143 )
144 .gh_grant_permissions::<flowey_lib_common::git_checkout::Node>([(
145 GhPermission::Contents,
146 GhPermissionValue::Read,
147 )])
148 .gh_grant_permissions::<flowey_lib_common::gh_task_azure_login::Node>([(
149 GhPermission::IdToken,
150 GhPermissionValue::Write,
151 )]);
152
153 if matches!(config, PipelineConfig::PrRelease) {
155 job = job.gh_dangerous_override_if(
156 "contains(github.event.pull_request.labels.*.name, 'release-ci-required') && github.event.pull_request.draft == false",
157 );
158 }
159
160 job
161 });
162
163 let openhcl_musl_target = |arch: CommonArch| -> Triple {
164 CommonTriple::Common {
165 arch,
166 platform: CommonPlatform::LinuxMusl,
167 }
168 .as_triple()
169 };
170
171 let (pub_vmm_tests_archive_linux_x86, use_vmm_tests_archive_linux_x86) =
173 pipeline.new_typed_artifact("x64-linux-vmm-tests-archive");
174 let (pub_vmm_tests_archive_windows_x86, use_vmm_tests_archive_windows_x86) =
175 pipeline.new_typed_artifact("x64-windows-vmm-tests-archive");
176 let (pub_vmm_tests_archive_windows_aarch64, use_vmm_tests_archive_windows_aarch64) =
177 pipeline.new_typed_artifact("aarch64-windows-vmm-tests-archive");
178
179 let mut pub_vmm_tests_archive_linux_x86 = Some(pub_vmm_tests_archive_linux_x86);
182 let mut pub_vmm_tests_archive_windows_x86 = Some(pub_vmm_tests_archive_windows_x86);
183 let mut pub_vmm_tests_archive_windows_aarch64 = Some(pub_vmm_tests_archive_windows_aarch64);
184
185 let mut vmm_tests_artifacts_linux_x86 =
189 vmm_tests_artifact_builders::VmmTestsArtifactsBuilderLinuxX86::default();
190 let mut vmm_tests_artifacts_windows_x86 =
191 vmm_tests_artifact_builders::VmmTestsArtifactsBuilderWindowsX86::default();
192 let mut vmm_tests_artifacts_windows_aarch64 =
193 vmm_tests_artifact_builders::VmmTestsArtifactsBuilderWindowsAarch64::default();
194
195 let mut all_jobs = Vec::new();
201
202 {
204 let windows_fmt_job = pipeline
205 .new_job(
206 FlowPlatform::Windows,
207 FlowArch::X86_64,
208 "xtask fmt (windows)",
209 )
210 .gh_set_pool(crate::pipelines_shared::gh_pools::gh_hosted_x64_windows())
211 .ado_set_pool(crate::pipelines_shared::ado_pools::default_x86_pool(
212 FlowPlatform::Windows,
213 ))
214 .dep_on(|ctx| flowey_lib_hvlite::_jobs::check_xtask_fmt::Request {
215 target: CommonTriple::X86_64_WINDOWS_MSVC,
216 done: ctx.new_done_handle(),
217 })
218 .finish();
219
220 let linux_fmt_job = pipeline
221 .new_job(
222 FlowPlatform::Linux(FlowPlatformLinuxDistro::Ubuntu),
223 FlowArch::X86_64,
224 "xtask fmt (linux)",
225 )
226 .gh_set_pool(crate::pipelines_shared::gh_pools::gh_hosted_x64_linux())
227 .ado_set_pool(crate::pipelines_shared::ado_pools::default_x86_pool(
228 FlowPlatform::Linux(FlowPlatformLinuxDistro::Ubuntu),
229 ))
230 .dep_on(|ctx| flowey_lib_hvlite::_jobs::check_xtask_fmt::Request {
231 target: CommonTriple::X86_64_LINUX_GNU,
232 done: ctx.new_done_handle(),
233 })
234 .finish();
235
236 pipeline.non_artifact_dep(&windows_fmt_job, &linux_fmt_job);
240
241 all_jobs.push(linux_fmt_job);
242 all_jobs.push(windows_fmt_job);
243 }
244
245 for arch in [CommonArch::Aarch64, CommonArch::X86_64] {
252 let arch_tag = match arch {
253 CommonArch::X86_64 => "x64",
254 CommonArch::Aarch64 => "aarch64",
255 };
256
257 let (pub_openvmm, use_openvmm) =
259 pipeline.new_typed_artifact(format!("{arch_tag}-windows-openvmm"));
260
261 let (pub_pipette_windows, use_pipette_windows) =
262 pipeline.new_typed_artifact(format!("{arch_tag}-windows-pipette"));
263
264 let (pub_tmk_vmm, use_tmk_vmm) =
265 pipeline.new_typed_artifact(format!("{arch_tag}-windows-tmk_vmm"));
266
267 let (pub_prep_steps, use_prep_steps) =
268 pipeline.new_typed_artifact(format!("{arch_tag}-windows-prep_steps"));
269
270 let (pub_vmgstool, use_vmgstool) =
271 pipeline.new_typed_artifact(format!("{arch_tag}-windows-vmgstool"));
272
273 let (pub_tpm_guest_tests, use_tpm_guest_tests_windows) =
274 pipeline.new_typed_artifact(format!("{arch_tag}-windows-tpm_guest_tests"));
275
276 let (pub_test_igvm_agent_rpc_server, use_test_igvm_agent_rpc_server) = pipeline
277 .new_typed_artifact(format!("{arch_tag}-windows-test_igvm_agent_rpc_server"));
278
279 match arch {
281 CommonArch::X86_64 => {
282 vmm_tests_artifacts_linux_x86.use_pipette_windows =
283 Some(use_pipette_windows.clone());
284 vmm_tests_artifacts_windows_x86.use_openvmm = Some(use_openvmm.clone());
285 vmm_tests_artifacts_windows_x86.use_pipette_windows =
286 Some(use_pipette_windows.clone());
287 vmm_tests_artifacts_windows_x86.use_tmk_vmm = Some(use_tmk_vmm.clone());
288 vmm_tests_artifacts_windows_x86.use_prep_steps = Some(use_prep_steps.clone());
289 vmm_tests_artifacts_windows_x86.use_vmgstool = Some(use_vmgstool.clone());
290 vmm_tests_artifacts_windows_x86.use_tpm_guest_tests_windows =
291 Some(use_tpm_guest_tests_windows.clone());
292 vmm_tests_artifacts_windows_x86.use_test_igvm_agent_rpc_server =
293 Some(use_test_igvm_agent_rpc_server.clone());
294 }
295 CommonArch::Aarch64 => {
296 vmm_tests_artifacts_windows_aarch64.use_openvmm = Some(use_openvmm.clone());
297 vmm_tests_artifacts_windows_aarch64.use_pipette_windows =
298 Some(use_pipette_windows.clone());
299 vmm_tests_artifacts_windows_aarch64.use_tmk_vmm = Some(use_tmk_vmm.clone());
300 vmm_tests_artifacts_windows_aarch64.use_vmgstool = Some(use_vmgstool.clone());
301 }
302 }
303 let (pub_igvmfilegen, _use_igvmfilegen) =
307 pipeline.new_typed_artifact(format!("{arch_tag}-windows-igvmfilegen"));
308 let (pub_vmgs_lib, _use_vmgs_lib) =
309 pipeline.new_typed_artifact(format!("{arch_tag}-windows-vmgs_lib"));
310 let (pub_hypestv, _use_hypestv) =
311 pipeline.new_typed_artifact(format!("{arch_tag}-windows-hypestv"));
312 let (pub_ohcldiag_dev, _use_ohcldiag_dev) =
313 pipeline.new_typed_artifact(format!("{arch_tag}-windows-ohcldiag-dev"));
314
315 let job = pipeline
316 .new_job(
317 FlowPlatform::Windows,
318 FlowArch::X86_64,
319 format!("build artifacts (not for VMM tests) [{arch_tag}-windows]"),
320 )
321 .gh_set_pool(crate::pipelines_shared::gh_pools::windows_amd_self_hosted_largedisk())
322 .ado_set_pool(crate::pipelines_shared::ado_pools::default_x86_pool(
323 FlowPlatform::Windows,
324 ))
325 .dep_on(|ctx| flowey_lib_hvlite::build_hypestv::Request {
326 target: CommonTriple::Common {
327 arch,
328 platform: CommonPlatform::WindowsMsvc,
329 },
330 profile: CommonProfile::from_release(release),
331 hypestv: ctx.publish_typed_artifact(pub_hypestv),
332 })
333 .dep_on(|ctx| flowey_lib_hvlite::build_and_test_vmgs_lib::Request {
334 target: CommonTriple::Common {
335 arch,
336 platform: CommonPlatform::WindowsMsvc,
337 },
338 profile: CommonProfile::from_release(release),
339 vmgs_lib: ctx.publish_typed_artifact(pub_vmgs_lib),
340 })
341 .dep_on(|ctx| flowey_lib_hvlite::build_igvmfilegen::Request {
342 build_params: flowey_lib_hvlite::build_igvmfilegen::IgvmfilegenBuildParams {
343 target: CommonTriple::Common {
344 arch,
345 platform: CommonPlatform::WindowsMsvc,
346 },
347 profile: CommonProfile::from_release(release).into(),
348 },
349 igvmfilegen: ctx.publish_typed_artifact(pub_igvmfilegen),
350 })
351 .dep_on(|ctx| flowey_lib_hvlite::build_ohcldiag_dev::Request {
352 target: CommonTriple::Common {
353 arch,
354 platform: CommonPlatform::WindowsMsvc,
355 },
356 profile: CommonProfile::from_release(release),
357 ohcldiag_dev: ctx.publish_typed_artifact(pub_ohcldiag_dev),
358 });
359
360 all_jobs.push(job.finish());
361
362 let vmgstool_target = CommonTriple::Common {
363 arch,
364 platform: CommonPlatform::WindowsMsvc,
365 };
366 if vmgstools
367 .insert(vmgstool_target.to_string(), use_vmgstool.clone())
368 .is_some()
369 {
370 anyhow::bail!("multiple vmgstools for the same target");
371 }
372
373 let mut job = pipeline
375 .new_job(
376 FlowPlatform::Windows,
377 FlowArch::X86_64,
378 format!("build artifacts (for VMM tests) [{arch_tag}-windows]"),
379 )
380 .gh_set_pool(crate::pipelines_shared::gh_pools::windows_amd_self_hosted_largedisk())
381 .ado_set_pool(crate::pipelines_shared::ado_pools::default_x86_pool(
382 FlowPlatform::Windows,
383 ))
384 .dep_on(|ctx| {
385 flowey_lib_hvlite::build_openvmm::Request {
386 params: flowey_lib_hvlite::build_openvmm::OpenvmmBuildParams {
387 target: CommonTriple::Common {
388 arch,
389 platform: CommonPlatform::WindowsMsvc,
390 },
391 profile: CommonProfile::from_release(release),
392 features: if matches!(arch, CommonArch::Aarch64) {
395 [flowey_lib_hvlite::build_openvmm::OpenvmmFeature::UnstableWhp]
396 .into()
397 } else {
398 [].into()
399 },
400 },
401 openvmm: ctx.publish_typed_artifact(pub_openvmm),
402 }
403 })
404 .dep_on(|ctx| flowey_lib_hvlite::build_pipette::Request {
405 target: CommonTriple::Common {
406 arch,
407 platform: CommonPlatform::WindowsMsvc,
408 },
409 profile: CommonProfile::from_release(release),
410 pipette: ctx.publish_typed_artifact(pub_pipette_windows),
411 })
412 .dep_on(|ctx| flowey_lib_hvlite::build_tmk_vmm::Request {
413 target: CommonTriple::Common {
414 arch,
415 platform: CommonPlatform::WindowsMsvc,
416 },
417 unstable_whp: true, profile: CommonProfile::from_release(release),
419 tmk_vmm: ctx.publish_typed_artifact(pub_tmk_vmm),
420 })
421 .dep_on(|ctx| flowey_lib_hvlite::build_prep_steps::Request {
422 target: CommonTriple::Common {
423 arch,
424 platform: CommonPlatform::WindowsMsvc,
425 },
426 profile: CommonProfile::from_release(release),
427 prep_steps: ctx.publish_typed_artifact(pub_prep_steps),
428 })
429 .dep_on(|ctx| flowey_lib_hvlite::build_vmgstool::Request {
430 target: vmgstool_target,
431 profile: CommonProfile::from_release(release),
432 with_crypto: true,
433 with_test_helpers: true,
434 vmgstool: ctx.publish_typed_artifact(pub_vmgstool),
435 })
436 .dep_on(|ctx| flowey_lib_hvlite::build_tpm_guest_tests::Request {
437 target: CommonTriple::Common {
438 arch,
439 platform: CommonPlatform::WindowsMsvc,
440 },
441 profile: CommonProfile::from_release(release),
442 tpm_guest_tests: ctx.publish_typed_artifact(pub_tpm_guest_tests),
443 })
444 .dep_on(
445 |ctx| flowey_lib_hvlite::build_test_igvm_agent_rpc_server::Request {
446 target: CommonTriple::Common {
447 arch,
448 platform: CommonPlatform::WindowsMsvc,
449 },
450 profile: CommonProfile::from_release(release),
451 test_igvm_agent_rpc_server: ctx
452 .publish_typed_artifact(pub_test_igvm_agent_rpc_server),
453 },
454 );
455
456 match arch {
458 CommonArch::X86_64 => {
459 let pub_vmm_tests_archive_windows_x86 =
460 pub_vmm_tests_archive_windows_x86.take().unwrap();
461 job = job.dep_on(|ctx|
462 flowey_lib_hvlite::build_nextest_vmm_tests::Request {
463 target: CommonTriple::X86_64_WINDOWS_MSVC.as_triple(),
464 profile: CommonProfile::from_release(release),
465 build_mode: flowey_lib_hvlite::build_nextest_vmm_tests::BuildNextestVmmTestsMode::Archive(
466 ctx.publish_typed_artifact(pub_vmm_tests_archive_windows_x86),
467 ),
468 });
469 }
470 CommonArch::Aarch64 => {
471 let pub_vmm_tests_archive_windows_aarch64 =
472 pub_vmm_tests_archive_windows_aarch64.take().unwrap();
473 job = job.dep_on(|ctx| flowey_lib_hvlite::build_nextest_vmm_tests::Request {
474 target: CommonTriple::AARCH64_WINDOWS_MSVC.as_triple(),
475 profile: CommonProfile::from_release(release),
476 build_mode: flowey_lib_hvlite::build_nextest_vmm_tests::BuildNextestVmmTestsMode::Archive(
477 ctx.publish_typed_artifact(pub_vmm_tests_archive_windows_aarch64),
478 ),
479 });
480 }
481 }
482
483 all_jobs.push(job.finish());
484 }
485
486 for arch in [CommonArch::Aarch64, CommonArch::X86_64] {
488 let arch_tag = match arch {
489 CommonArch::X86_64 => "x64",
490 CommonArch::Aarch64 => "aarch64",
491 };
492
493 let (pub_openvmm, use_openvmm) =
494 pipeline.new_typed_artifact(format!("{arch_tag}-linux-openvmm"));
495 let (pub_igvmfilegen, _) =
496 pipeline.new_typed_artifact(format!("{arch_tag}-linux-igvmfilegen"));
497 let (pub_vmgs_lib, _) =
498 pipeline.new_typed_artifact(format!("{arch_tag}-linux-vmgs_lib"));
499 let (pub_vmgstool, use_vmgstool) =
500 pipeline.new_typed_artifact(format!("{arch_tag}-linux-vmgstool"));
501 let (pub_ohcldiag_dev, _) =
502 pipeline.new_typed_artifact(format!("{arch_tag}-linux-ohcldiag-dev"));
503 let (pub_tmks, use_tmks) = pipeline.new_typed_artifact(format!("{arch_tag}-tmks"));
504 let (pub_tpm_guest_tests, use_tpm_guest_tests) =
505 pipeline.new_typed_artifact(format!("{arch_tag}-linux-tpm_guest_tests"));
506
507 let (pub_guest_test_uefi, use_guest_test_uefi) =
514 pipeline.new_typed_artifact(format!("{arch_tag}-guest_test_uefi"));
515
516 match arch {
518 CommonArch::X86_64 => {
519 vmm_tests_artifacts_linux_x86.use_openvmm = Some(use_openvmm.clone());
520 vmm_tests_artifacts_linux_x86.use_guest_test_uefi =
521 Some(use_guest_test_uefi.clone());
522 vmm_tests_artifacts_windows_x86.use_guest_test_uefi =
523 Some(use_guest_test_uefi.clone());
524 vmm_tests_artifacts_windows_x86.use_tmks = Some(use_tmks.clone());
525 vmm_tests_artifacts_linux_x86.use_tmks = Some(use_tmks.clone());
526 vmm_tests_artifacts_windows_x86.use_tpm_guest_tests_linux =
527 Some(use_tpm_guest_tests.clone());
528 }
529 CommonArch::Aarch64 => {
530 vmm_tests_artifacts_windows_aarch64.use_guest_test_uefi =
531 Some(use_guest_test_uefi.clone());
532 vmm_tests_artifacts_windows_aarch64.use_tmks = Some(use_tmks.clone());
533 }
534 }
535
536 let vmgstool_target = CommonTriple::Common {
537 arch,
538 platform: CommonPlatform::LinuxGnu,
539 };
540 if vmgstools
541 .insert(vmgstool_target.to_string(), use_vmgstool.clone())
542 .is_some()
543 {
544 anyhow::bail!("multiple vmgstools for the same target");
545 }
546
547 let mut job = pipeline
548 .new_job(
549 FlowPlatform::Linux(FlowPlatformLinuxDistro::Ubuntu),
550 FlowArch::X86_64,
551 format!("build artifacts [{arch_tag}-linux]"),
552 )
553 .gh_set_pool(crate::pipelines_shared::gh_pools::linux_self_hosted_largedisk())
554 .ado_set_pool(crate::pipelines_shared::ado_pools::default_x86_pool(
555 FlowPlatform::Linux(FlowPlatformLinuxDistro::Ubuntu),
556 ))
557 .dep_on(|ctx| {
558 flowey_lib_hvlite::build_openvmm::Request {
559 params: flowey_lib_hvlite::build_openvmm::OpenvmmBuildParams {
560 target: CommonTriple::Common {
561 arch,
562 platform: CommonPlatform::LinuxGnu,
563 },
564 profile: CommonProfile::from_release(release),
565 features: [flowey_lib_hvlite::build_openvmm::OpenvmmFeature::Tpm]
567 .into(),
568 },
569 openvmm: ctx.publish_typed_artifact(pub_openvmm),
570 }
571 })
572 .dep_on(|ctx| flowey_lib_hvlite::build_vmgstool::Request {
573 target: vmgstool_target,
574 profile: CommonProfile::from_release(release),
575 with_crypto: true,
576 with_test_helpers: true,
577 vmgstool: ctx.publish_typed_artifact(pub_vmgstool),
578 })
579 .dep_on(|ctx| flowey_lib_hvlite::build_and_test_vmgs_lib::Request {
580 target: CommonTriple::Common {
581 arch,
582 platform: CommonPlatform::LinuxGnu,
583 },
584 profile: CommonProfile::from_release(release),
585 vmgs_lib: ctx.publish_typed_artifact(pub_vmgs_lib),
586 })
587 .dep_on(|ctx| flowey_lib_hvlite::build_igvmfilegen::Request {
588 build_params: flowey_lib_hvlite::build_igvmfilegen::IgvmfilegenBuildParams {
589 target: CommonTriple::Common {
590 arch,
591 platform: CommonPlatform::LinuxGnu,
592 },
593 profile: CommonProfile::from_release(release).into(),
594 },
595 igvmfilegen: ctx.publish_typed_artifact(pub_igvmfilegen),
596 })
597 .dep_on(|ctx| flowey_lib_hvlite::build_ohcldiag_dev::Request {
598 target: CommonTriple::Common {
599 arch,
600 platform: CommonPlatform::LinuxGnu,
601 },
602 profile: CommonProfile::from_release(release),
603 ohcldiag_dev: ctx.publish_typed_artifact(pub_ohcldiag_dev),
604 })
605 .dep_on(|ctx| flowey_lib_hvlite::build_guest_test_uefi::Request {
606 arch,
607 profile: CommonProfile::from_release(release),
608 guest_test_uefi: ctx.publish_typed_artifact(pub_guest_test_uefi),
609 })
610 .dep_on(|ctx| flowey_lib_hvlite::build_tmks::Request {
611 arch,
612 profile: CommonProfile::from_release(release),
613 tmks: ctx.publish_typed_artifact(pub_tmks),
614 })
615 .dep_on(|ctx| flowey_lib_hvlite::build_tpm_guest_tests::Request {
616 target: CommonTriple::Common {
617 arch,
618 platform: CommonPlatform::LinuxGnu,
619 },
620 profile: CommonProfile::from_release(release),
621 tpm_guest_tests: ctx.publish_typed_artifact(pub_tpm_guest_tests),
622 });
623
624 if matches!(arch, CommonArch::X86_64) {
628 let pub_vmm_tests_archive_linux_x86 =
629 pub_vmm_tests_archive_linux_x86.take().unwrap();
630 job = job.dep_on(|ctx| flowey_lib_hvlite::build_nextest_vmm_tests::Request {
631 target: CommonTriple::X86_64_LINUX_GNU.as_triple(),
632 profile: CommonProfile::from_release(release),
633 build_mode: flowey_lib_hvlite::build_nextest_vmm_tests::BuildNextestVmmTestsMode::Archive(
634 ctx.publish_typed_artifact(pub_vmm_tests_archive_linux_x86),
635 ),
636 });
637 }
638
639 all_jobs.push(job.finish());
640 }
641
642 for arch in [CommonArch::Aarch64, CommonArch::X86_64] {
644 let arch_tag = match arch {
645 CommonArch::X86_64 => "x64",
646 CommonArch::Aarch64 => "aarch64",
647 };
648
649 let openvmm_hcl_profile = if release {
650 OpenvmmHclBuildProfile::OpenvmmHclShip
651 } else {
652 OpenvmmHclBuildProfile::Debug
653 };
654
655 let (pub_openhcl_igvm, use_openhcl_igvm) =
656 pipeline.new_artifact(format!("{arch_tag}-openhcl-igvm"));
657 let (pub_openhcl_igvm_extras, _use_openhcl_igvm_extras) =
658 pipeline.new_artifact(format!("{arch_tag}-openhcl-igvm-extras"));
659
660 let (pub_openhcl_baseline, _use_openhcl_baseline) =
661 if matches!(config, PipelineConfig::Ci) {
662 let (p, u) = pipeline.new_artifact(format!("{arch_tag}-openhcl-baseline"));
663 (Some(p), Some(u))
664 } else {
665 (None, None)
666 };
667
668 let (pub_pipette_linux_musl, use_pipette_linux_musl) =
673 pipeline.new_typed_artifact(format!("{arch_tag}-linux-musl-pipette"));
674
675 let (pub_tmk_vmm, use_tmk_vmm) =
676 pipeline.new_typed_artifact(format!("{arch_tag}-linux-musl-tmk_vmm"));
677
678 match arch {
680 CommonArch::X86_64 => {
681 vmm_tests_artifacts_windows_x86.use_openhcl_igvm_files =
682 Some(use_openhcl_igvm.clone());
683 vmm_tests_artifacts_windows_x86.use_pipette_linux_musl =
684 Some(use_pipette_linux_musl.clone());
685 vmm_tests_artifacts_linux_x86.use_pipette_linux_musl =
686 Some(use_pipette_linux_musl.clone());
687 vmm_tests_artifacts_linux_x86.use_tmk_vmm = Some(use_tmk_vmm.clone());
688 vmm_tests_artifacts_windows_x86.use_tmk_vmm_linux_musl =
689 Some(use_tmk_vmm.clone());
690 }
691 CommonArch::Aarch64 => {
692 vmm_tests_artifacts_windows_aarch64.use_openhcl_igvm_files =
693 Some(use_openhcl_igvm.clone());
694 vmm_tests_artifacts_windows_aarch64.use_pipette_linux_musl =
695 Some(use_pipette_linux_musl.clone());
696 vmm_tests_artifacts_windows_aarch64.use_tmk_vmm_linux_musl =
697 Some(use_tmk_vmm.clone());
698 }
699 }
700 let igvm_recipes = match arch {
701 CommonArch::X86_64 => vec![
702 OpenhclIgvmRecipe::X64,
703 OpenhclIgvmRecipe::X64Devkern,
704 OpenhclIgvmRecipe::X64TestLinuxDirect,
705 OpenhclIgvmRecipe::X64TestLinuxDirectDevkern,
706 OpenhclIgvmRecipe::X64Cvm,
707 ],
708 CommonArch::Aarch64 => {
709 vec![
710 OpenhclIgvmRecipe::Aarch64,
711 OpenhclIgvmRecipe::Aarch64Devkern,
712 ]
713 }
714 };
715
716 let build_openhcl_job_tag = |arch_tag| format!("build openhcl [{arch_tag}-linux]");
717 let job = pipeline
718 .new_job(
719 FlowPlatform::Linux(FlowPlatformLinuxDistro::Ubuntu),
720 FlowArch::X86_64,
721 build_openhcl_job_tag(arch_tag),
722 )
723 .gh_set_pool(crate::pipelines_shared::gh_pools::linux_self_hosted_largedisk())
724 .ado_set_pool(crate::pipelines_shared::ado_pools::default_x86_pool(
725 FlowPlatform::Linux(FlowPlatformLinuxDistro::Ubuntu),
726 ))
727 .dep_on(|ctx| {
728 let publish_baseline_artifact = pub_openhcl_baseline
729 .map(|baseline_artifact| ctx.publish_artifact(baseline_artifact));
730
731 flowey_lib_hvlite::_jobs::build_and_publish_openhcl_igvm_from_recipe::Params {
732 igvm_files: igvm_recipes
733 .clone()
734 .into_iter()
735 .map(|recipe| OpenhclIgvmBuildParams {
736 profile: openvmm_hcl_profile,
737 recipe,
738 custom_target: Some(CommonTriple::Custom(openhcl_musl_target(
739 arch,
740 ))),
741 })
742 .collect(),
743 artifact_dir_openhcl_igvm: ctx.publish_artifact(pub_openhcl_igvm),
744 artifact_dir_openhcl_igvm_extras: ctx
745 .publish_artifact(pub_openhcl_igvm_extras),
746 artifact_openhcl_verify_size_baseline: publish_baseline_artifact,
747 done: ctx.new_done_handle(),
748 }
749 })
750 .dep_on(|ctx| flowey_lib_hvlite::build_pipette::Request {
751 target: CommonTriple::Common {
752 arch,
753 platform: CommonPlatform::LinuxMusl,
754 },
755 profile: CommonProfile::from_release(release),
756 pipette: ctx.publish_typed_artifact(pub_pipette_linux_musl),
757 })
758 .dep_on(|ctx| flowey_lib_hvlite::build_tmk_vmm::Request {
759 target: CommonTriple::Common {
760 arch,
761 platform: CommonPlatform::LinuxMusl,
762 },
763 profile: CommonProfile::from_release(release),
764 unstable_whp: false,
765 tmk_vmm: ctx.publish_typed_artifact(pub_tmk_vmm),
766 });
767
768 all_jobs.push(job.finish());
769
770 if matches!(config, PipelineConfig::Pr)
772 && !matches!(backend_hint, PipelineBackendHint::Ado)
773 {
774 let job = pipeline
775 .new_job(
776 FlowPlatform::Linux(FlowPlatformLinuxDistro::Ubuntu),
777 FlowArch::X86_64,
778 format!("verify openhcl binary size [{}]", arch_tag),
779 )
780 .gh_set_pool(crate::pipelines_shared::gh_pools::gh_hosted_x64_linux())
781 .dep_on(
782 |ctx| flowey_lib_hvlite::_jobs::check_openvmm_hcl_size::Request {
783 target: CommonTriple::Common {
784 arch,
785 platform: CommonPlatform::LinuxMusl,
786 },
787 done: ctx.new_done_handle(),
788 pipeline_name: "openvmm-ci.yaml".into(),
789 job_name: build_openhcl_job_tag(arch_tag),
790 },
791 )
792 .finish();
793 all_jobs.push(job);
794 }
795 }
796
797 struct ClippyUnitTestJobParams<'a> {
802 platform: FlowPlatform,
803 arch: FlowArch,
804 gh_pool: GhRunner,
805 clippy_targets: Option<(&'a str, &'a [(Triple, bool)])>,
806 unit_test_target: Option<(&'a str, Triple)>,
807 }
808
809 for ClippyUnitTestJobParams {
810 platform,
811 arch,
812 gh_pool,
813 clippy_targets,
814 unit_test_target,
815 } in [
816 ClippyUnitTestJobParams {
817 platform: FlowPlatform::Windows,
818 arch: FlowArch::X86_64,
819 gh_pool: if release {
820 crate::pipelines_shared::gh_pools::windows_amd_self_hosted_largedisk()
821 } else {
822 crate::pipelines_shared::gh_pools::gh_hosted_x64_windows()
823 },
824 clippy_targets: Some((
825 "x64-windows",
826 &[(target_lexicon::triple!("x86_64-pc-windows-msvc"), false)],
827 )),
828 unit_test_target: Some((
829 "x64-windows",
830 target_lexicon::triple!("x86_64-pc-windows-msvc"),
831 )),
832 },
833 ClippyUnitTestJobParams {
834 platform: FlowPlatform::Linux(FlowPlatformLinuxDistro::Ubuntu),
835 arch: FlowArch::X86_64,
836 gh_pool: crate::pipelines_shared::gh_pools::linux_self_hosted_largedisk(),
839 clippy_targets: Some((
840 "x64-linux, macos",
841 &[
842 (target_lexicon::triple!("x86_64-unknown-linux-gnu"), false),
843 (target_lexicon::triple!("aarch64-apple-darwin"), false),
844 ],
845 )),
846 unit_test_target: Some((
847 "x64-linux",
848 target_lexicon::triple!("x86_64-unknown-linux-gnu"),
849 )),
850 },
851 ClippyUnitTestJobParams {
852 platform: FlowPlatform::Linux(FlowPlatformLinuxDistro::Ubuntu),
853 arch: FlowArch::X86_64,
854 gh_pool: crate::pipelines_shared::gh_pools::linux_self_hosted_largedisk(),
857 clippy_targets: Some((
858 "x64-linux-musl, misc nostd",
859 &[(openhcl_musl_target(CommonArch::X86_64), true)],
860 )),
861 unit_test_target: Some(("x64-linux-musl", openhcl_musl_target(CommonArch::X86_64))),
862 },
863 ClippyUnitTestJobParams {
864 platform: FlowPlatform::Windows,
865 arch: FlowArch::Aarch64,
866 gh_pool: if release {
867 crate::pipelines_shared::gh_pools::windows_arm_self_hosted()
868 } else {
869 crate::pipelines_shared::gh_pools::gh_hosted_arm_windows()
870 },
871 clippy_targets: Some((
872 "aarch64-windows",
873 &[(target_lexicon::triple!("aarch64-pc-windows-msvc"), false)],
874 )),
875 unit_test_target: Some((
876 "aarch64-windows",
877 target_lexicon::triple!("aarch64-pc-windows-msvc"),
878 )),
879 },
880 ClippyUnitTestJobParams {
881 platform: FlowPlatform::Linux(FlowPlatformLinuxDistro::Ubuntu),
882 arch: FlowArch::Aarch64,
883 gh_pool: if release {
884 crate::pipelines_shared::gh_pools::linux_arm_self_hosted()
885 } else {
886 crate::pipelines_shared::gh_pools::gh_hosted_arm_linux()
887 },
888 clippy_targets: Some((
889 "aarch64-linux",
890 &[(target_lexicon::triple!("aarch64-unknown-linux-gnu"), false)],
891 )),
892 unit_test_target: Some((
893 "aarch64-linux",
894 target_lexicon::triple!("aarch64-unknown-linux-gnu"),
895 )),
896 },
897 ClippyUnitTestJobParams {
898 platform: FlowPlatform::Linux(FlowPlatformLinuxDistro::Ubuntu),
899 arch: FlowArch::Aarch64,
900 gh_pool: if release {
901 crate::pipelines_shared::gh_pools::linux_arm_self_hosted()
902 } else {
903 crate::pipelines_shared::gh_pools::gh_hosted_arm_linux()
904 },
905 clippy_targets: Some((
906 "aarch64-linux-musl, misc nostd",
907 &[(openhcl_musl_target(CommonArch::Aarch64), true)],
908 )),
909 unit_test_target: Some((
910 "aarch64-linux-musl",
911 openhcl_musl_target(CommonArch::Aarch64),
912 )),
913 },
914 ] {
915 if matches!(arch, FlowArch::Aarch64) && matches!(backend_hint, PipelineBackendHint::Ado)
917 {
918 continue;
919 }
920
921 let mut job_name = Vec::new();
922 if let Some((label, _)) = &clippy_targets {
923 job_name.push(format!("clippy [{label}]"));
924 }
925 if let Some((label, _)) = &unit_test_target {
926 job_name.push(format!("unit tests [{label}]"));
927 }
928 let job_name = job_name.join(", ");
929
930 let unit_test_target = unit_test_target.map(|(label, target)| {
931 let test_label = format!("{label}-unit-tests");
932 let pub_unit_test_junit_xml = if matches!(backend_hint, PipelineBackendHint::Local)
933 {
934 Some(pipeline.new_artifact(&test_label).0)
935 } else {
936 None
937 };
938 (test_label, target, pub_unit_test_junit_xml)
939 });
940
941 let mut clippy_unit_test_job = pipeline
942 .new_job(platform, arch, job_name)
943 .gh_set_pool(gh_pool)
944 .ado_set_pool(match platform {
945 FlowPlatform::Windows => {
946 crate::pipelines_shared::ado_pools::default_x86_pool(FlowPlatform::Windows)
947 }
948 FlowPlatform::Linux(FlowPlatformLinuxDistro::Ubuntu) => {
949 crate::pipelines_shared::ado_pools::default_x86_pool(FlowPlatform::Linux(
950 FlowPlatformLinuxDistro::Ubuntu,
951 ))
952 }
953 _ => anyhow::bail!("unsupported platform"),
954 });
955
956 if let Some((_, targets)) = clippy_targets {
957 for (target, also_check_misc_nostd_crates) in targets {
958 clippy_unit_test_job = clippy_unit_test_job.dep_on(|ctx| {
959 flowey_lib_hvlite::_jobs::check_clippy::Request {
960 target: target.clone(),
961 profile: CommonProfile::from_release(release),
962 done: ctx.new_done_handle(),
963 also_check_misc_nostd_crates: *also_check_misc_nostd_crates,
964 }
965 });
966 }
967 }
968
969 if let Some((test_label, target, pub_unit_test_junit_xml)) = unit_test_target {
970 clippy_unit_test_job = clippy_unit_test_job
971 .dep_on(|ctx| {
972 flowey_lib_hvlite::_jobs::build_and_run_nextest_unit_tests::Params {
973 junit_test_label: test_label,
974 nextest_profile:
975 flowey_lib_hvlite::run_cargo_nextest_run::NextestProfile::Ci,
976 fail_job_on_test_fail: true,
977 target: target.clone(),
978 profile: CommonProfile::from_release(release),
979 artifact_dir: pub_unit_test_junit_xml.map(|x| ctx.publish_artifact(x)),
980 done: ctx.new_done_handle(),
981 }
982 })
983 .dep_on(
984 |ctx| flowey_lib_hvlite::_jobs::build_and_run_doc_tests::Params {
985 target,
986 profile: CommonProfile::from_release(release),
987 done: ctx.new_done_handle(),
988 },
989 );
990 }
991
992 all_jobs.push(clippy_unit_test_job.finish());
993 }
994
995 let vmm_tests_artifacts_windows_intel_x86 = vmm_tests_artifacts_windows_x86
996 .clone()
997 .finish()
998 .map_err(|missing| {
999 anyhow::anyhow!("missing required windows-intel vmm_tests artifact: {missing}")
1000 })?;
1001 let vmm_tests_artifacts_windows_intel_tdx_x86 = vmm_tests_artifacts_windows_x86
1002 .clone()
1003 .finish()
1004 .map_err(|missing| {
1005 anyhow::anyhow!("missing required windows-intel-tdx vmm_tests artifact: {missing}")
1006 })?;
1007 let vmm_tests_artifacts_windows_amd_x86 = vmm_tests_artifacts_windows_x86
1008 .clone()
1009 .finish()
1010 .map_err(|missing| {
1011 anyhow::anyhow!("missing required windows-amd vmm_tests artifact: {missing}")
1012 })?;
1013 let vmm_tests_artifacts_windows_amd_snp_x86 = vmm_tests_artifacts_windows_x86
1014 .finish()
1015 .map_err(|missing| {
1016 anyhow::anyhow!("missing required windows-amd-snp vmm_tests artifact: {missing}")
1017 })?;
1018 let vmm_tests_artifacts_linux_x86 =
1019 vmm_tests_artifacts_linux_x86.finish().map_err(|missing| {
1020 anyhow::anyhow!("missing required linux vmm_tests artifact: {missing}")
1021 })?;
1022 let vmm_tests_artifacts_windows_aarch64 = vmm_tests_artifacts_windows_aarch64
1023 .finish()
1024 .map_err(|missing| {
1025 anyhow::anyhow!("missing required windows-aarch64 vmm_tests artifact: {missing}")
1026 })?;
1027
1028 struct VmmTestJobParams<'a> {
1030 platform: FlowPlatform,
1031 arch: FlowArch,
1032 gh_pool: GhRunner,
1033 label: &'a str,
1034 target: CommonTriple,
1035 resolve_vmm_tests_artifacts: vmm_tests_artifact_builders::ResolveVmmTestsDepArtifacts,
1036 nextest_filter_expr: String,
1037 test_artifacts: Vec<KnownTestArtifacts>,
1038 needs_prep_run: bool,
1039 }
1040
1041 let standard_filter = {
1042 let mut filter = "all() & !test(very_heavy) & !test(openvmm_openhcl_uefi_x64_windows_datacenter_core_2025_x64_prepped_vbs) & !test(hyperv_openhcl_pcat)".to_string();
1058 match backend_hint {
1065 PipelineBackendHint::Ado => {
1066 filter.push_str(
1067 " & !(test(servicing) & (test(upgrade) + test(downgrade) + test(hyperv)))",
1068 );
1069 }
1070 _ => {
1071 filter.push_str(" & !(test(servicing) & test(hyperv))");
1072 }
1073 }
1074 filter
1075 };
1076
1077 let standard_x64_test_artifacts = vec![
1078 KnownTestArtifacts::Alpine323X64Vhd,
1079 KnownTestArtifacts::FreeBsd13_2X64Vhd,
1080 KnownTestArtifacts::FreeBsd13_2X64Iso,
1081 KnownTestArtifacts::Gen1WindowsDataCenterCore2022X64Vhd,
1082 KnownTestArtifacts::Gen2WindowsDataCenterCore2022X64Vhd,
1083 KnownTestArtifacts::Gen2WindowsDataCenterCore2025X64Vhd,
1084 KnownTestArtifacts::Ubuntu2404ServerX64Vhd,
1085 KnownTestArtifacts::Ubuntu2504ServerX64Vhd,
1086 KnownTestArtifacts::VmgsWithBootEntry,
1087 KnownTestArtifacts::VmgsWith16kTpm,
1088 ];
1089
1090 let cvm_filter = |isolation_type| {
1091 let mut filter = format!(
1092 "test({isolation_type}) + (test(vbs) & test(hyperv)) + test(very_heavy) + test(openvmm_openhcl_uefi_x64_windows_datacenter_core_2025_x64_prepped_vbs)"
1093 );
1094 if isolation_type == "tdx" {
1096 filter.push_str(" + test(hyperv_openhcl_pcat)");
1097 }
1098
1099 match backend_hint {
1101 PipelineBackendHint::Ado => {
1102 filter.push_str(
1103 " + (test(servicing) & !(test(upgrade) + test(downgrade)) & test(hyperv))",
1104 );
1105 }
1106 _ => {
1107 filter.push_str(" + (test(servicing) & test(hyperv))");
1108 }
1109 }
1110
1111 if isolation_type == "snp" {
1113 filter = format!("({filter}) & !test(pcat)")
1114 }
1115 filter
1116 };
1117 let cvm_x64_test_artifacts = vec![
1118 KnownTestArtifacts::Gen1WindowsDataCenterCore2022X64Vhd,
1119 KnownTestArtifacts::Gen2WindowsDataCenterCore2022X64Vhd,
1120 KnownTestArtifacts::Gen2WindowsDataCenterCore2025X64Vhd,
1121 KnownTestArtifacts::Ubuntu2504ServerX64Vhd,
1122 KnownTestArtifacts::VmgsWith16kTpm,
1123 ];
1124
1125 for VmmTestJobParams {
1126 platform,
1127 arch,
1128 gh_pool,
1129 label,
1130 target,
1131 resolve_vmm_tests_artifacts,
1132 nextest_filter_expr,
1133 test_artifacts,
1134 needs_prep_run,
1135 } in [
1136 VmmTestJobParams {
1137 platform: FlowPlatform::Windows,
1138 arch: FlowArch::X86_64,
1139 gh_pool: crate::pipelines_shared::gh_pools::windows_intel_self_hosted_largedisk(),
1140 label: "x64-windows-intel",
1141 target: CommonTriple::X86_64_WINDOWS_MSVC,
1142 resolve_vmm_tests_artifacts: vmm_tests_artifacts_windows_intel_x86,
1143 nextest_filter_expr: standard_filter.clone(),
1144 test_artifacts: standard_x64_test_artifacts.clone(),
1145 needs_prep_run: false,
1146 },
1147 VmmTestJobParams {
1148 platform: FlowPlatform::Windows,
1149 arch: FlowArch::X86_64,
1150 gh_pool: crate::pipelines_shared::gh_pools::windows_tdx_self_hosted_baremetal(),
1151 label: "x64-windows-intel-tdx",
1152 target: CommonTriple::X86_64_WINDOWS_MSVC,
1153 resolve_vmm_tests_artifacts: vmm_tests_artifacts_windows_intel_tdx_x86,
1154 nextest_filter_expr: cvm_filter("tdx"),
1155 test_artifacts: cvm_x64_test_artifacts.clone(),
1156 needs_prep_run: true,
1157 },
1158 VmmTestJobParams {
1159 platform: FlowPlatform::Windows,
1160 arch: FlowArch::X86_64,
1161 gh_pool: crate::pipelines_shared::gh_pools::windows_amd_self_hosted_largedisk(),
1162 label: "x64-windows-amd",
1163 target: CommonTriple::X86_64_WINDOWS_MSVC,
1164 resolve_vmm_tests_artifacts: vmm_tests_artifacts_windows_amd_x86,
1165 nextest_filter_expr: standard_filter.clone(),
1166 test_artifacts: standard_x64_test_artifacts.clone(),
1167 needs_prep_run: false,
1168 },
1169 VmmTestJobParams {
1170 platform: FlowPlatform::Windows,
1171 arch: FlowArch::X86_64,
1172 gh_pool: crate::pipelines_shared::gh_pools::windows_snp_self_hosted_baremetal(),
1173 label: "x64-windows-amd-snp",
1174 target: CommonTriple::X86_64_WINDOWS_MSVC,
1175 resolve_vmm_tests_artifacts: vmm_tests_artifacts_windows_amd_snp_x86,
1176 nextest_filter_expr: cvm_filter("snp"),
1177 test_artifacts: cvm_x64_test_artifacts,
1178 needs_prep_run: true,
1179 },
1180 VmmTestJobParams {
1181 platform: FlowPlatform::Linux(FlowPlatformLinuxDistro::Ubuntu),
1182 arch: FlowArch::X86_64,
1183 gh_pool: crate::pipelines_shared::gh_pools::linux_self_hosted_largedisk(),
1184 label: "x64-linux",
1185 target: CommonTriple::X86_64_LINUX_GNU,
1186 resolve_vmm_tests_artifacts: vmm_tests_artifacts_linux_x86,
1187 nextest_filter_expr: format!("{standard_filter} & !test(pcat_x64)"),
1189 test_artifacts: standard_x64_test_artifacts,
1190 needs_prep_run: false,
1191 },
1192 VmmTestJobParams {
1193 platform: FlowPlatform::Windows,
1194 arch: FlowArch::Aarch64,
1195 gh_pool: crate::pipelines_shared::gh_pools::windows_arm_self_hosted_baremetal(),
1196 label: "aarch64-windows",
1197 target: CommonTriple::AARCH64_WINDOWS_MSVC,
1198 resolve_vmm_tests_artifacts: vmm_tests_artifacts_windows_aarch64,
1199 nextest_filter_expr: "all()".to_string(),
1200 test_artifacts: vec![
1201 KnownTestArtifacts::Alpine323Aarch64Vhd,
1202 KnownTestArtifacts::Ubuntu2404ServerAarch64Vhd,
1203 KnownTestArtifacts::Windows11EnterpriseAarch64Vhdx,
1204 KnownTestArtifacts::VmgsWithBootEntry,
1205 KnownTestArtifacts::VmgsWith16kTpm,
1206 ],
1207 needs_prep_run: false,
1208 },
1209 ] {
1210 if matches!(backend_hint, PipelineBackendHint::Ado) {
1212 if matches!(arch, FlowArch::Aarch64)
1213 || label.contains("tdx")
1214 || label.contains("snp")
1215 {
1216 continue;
1217 }
1218 }
1219 let test_label = format!("{label}-vmm-tests");
1220
1221 let pub_vmm_tests_results = if matches!(backend_hint, PipelineBackendHint::Local) {
1222 Some(pipeline.new_artifact(&test_label).0)
1223 } else {
1224 None
1225 };
1226
1227 let use_vmm_tests_archive = match target {
1228 CommonTriple::X86_64_WINDOWS_MSVC => &use_vmm_tests_archive_windows_x86,
1229 CommonTriple::X86_64_LINUX_GNU => &use_vmm_tests_archive_linux_x86,
1230 CommonTriple::AARCH64_WINDOWS_MSVC => &use_vmm_tests_archive_windows_aarch64,
1231 _ => unreachable!(),
1232 };
1233
1234 let mut vmm_tests_run_job = pipeline
1235 .new_job(platform, arch, format!("run vmm-tests [{label}]"))
1236 .gh_set_pool(gh_pool);
1237
1238 if matches!(arch, FlowArch::X86_64) {
1240 vmm_tests_run_job = vmm_tests_run_job.ado_set_pool(match platform {
1241 FlowPlatform::Windows => {
1242 crate::pipelines_shared::ado_pools::default_x86_pool(FlowPlatform::Windows)
1243 }
1244 FlowPlatform::Linux(FlowPlatformLinuxDistro::Ubuntu) => {
1245 crate::pipelines_shared::ado_pools::default_x86_pool(FlowPlatform::Linux(
1246 FlowPlatformLinuxDistro::Ubuntu,
1247 ))
1248 }
1249 _ => anyhow::bail!("unsupported platform"),
1250 });
1251 }
1252
1253 vmm_tests_run_job = vmm_tests_run_job.dep_on(|ctx| {
1254 flowey_lib_hvlite::_jobs::consume_and_test_nextest_vmm_tests_archive::Params {
1255 junit_test_label: test_label,
1256 nextest_vmm_tests_archive: ctx.use_typed_artifact(use_vmm_tests_archive),
1257 target: target.as_triple(),
1258 nextest_profile: flowey_lib_hvlite::run_cargo_nextest_run::NextestProfile::Ci,
1259 nextest_filter_expr: Some(nextest_filter_expr),
1260 dep_artifact_dirs: resolve_vmm_tests_artifacts(ctx),
1261 test_artifacts,
1262 fail_job_on_test_fail: true,
1263 artifact_dir: pub_vmm_tests_results.map(|x| ctx.publish_artifact(x)),
1264 needs_prep_run,
1265 done: ctx.new_done_handle(),
1266 }
1267 });
1268
1269 if let Some(vmm_tests_disk_cache_dir) = vmm_tests_disk_cache_dir.clone() {
1270 vmm_tests_run_job = vmm_tests_run_job.dep_on(|_| {
1271 flowey_lib_hvlite::download_openvmm_vmm_tests_artifacts::Request::CustomCacheDir(
1272 vmm_tests_disk_cache_dir,
1273 )
1274 })
1275 }
1276
1277 all_jobs.push(vmm_tests_run_job.finish());
1278 }
1279
1280 {
1282 if matches!(backend_hint, PipelineBackendHint::Github) {
1283 let job = pipeline
1284 .new_job(
1285 FlowPlatform::Linux(FlowPlatformLinuxDistro::Ubuntu),
1286 FlowArch::X86_64,
1287 "test flowey local backend",
1288 )
1289 .gh_set_pool(crate::pipelines_shared::gh_pools::gh_hosted_x64_linux())
1290 .dep_on(
1291 |ctx| flowey_lib_hvlite::_jobs::test_local_flowey_build_igvm::Request {
1292 base_recipe: OpenhclIgvmRecipe::X64,
1293 done: ctx.new_done_handle(),
1294 },
1295 )
1296 .finish();
1297 all_jobs.push(job);
1298 }
1299 }
1300
1301 if matches!(config, PipelineConfig::Pr)
1302 && matches!(backend_hint, PipelineBackendHint::Github)
1303 {
1304 let all_good_job = pipeline
1314 .new_job(
1315 FlowPlatform::Linux(FlowPlatformLinuxDistro::Ubuntu),
1316 FlowArch::X86_64,
1317 "openvmm checkin gates",
1318 )
1319 .gh_set_pool(crate::pipelines_shared::gh_pools::gh_hosted_x64_linux())
1320 .gh_dangerous_override_if("always() && github.event.pull_request.draft == false")
1322 .gh_dangerous_global_env_var("ANY_JOBS_FAILED", "${{ contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'failure') }}")
1323 .dep_on(|ctx| flowey_lib_hvlite::_jobs::all_good_job::Params {
1324 did_fail_env_var: "ANY_JOBS_FAILED".into(),
1325 done: ctx.new_done_handle(),
1326 })
1327 .finish();
1328
1329 for job in all_jobs.iter() {
1330 pipeline.non_artifact_dep(&all_good_job, job);
1331 }
1332 }
1333
1334 if matches!(config, PipelineConfig::Ci)
1335 && matches!(backend_hint, PipelineBackendHint::Github)
1336 {
1337 let publish_vmgstool_job = pipeline
1338 .new_job(
1339 FlowPlatform::Linux(FlowPlatformLinuxDistro::Ubuntu),
1340 FlowArch::X86_64,
1341 "publish vmgstool",
1342 )
1343 .gh_grant_permissions::<flowey_lib_common::publish_gh_release::Node>([(
1344 GhPermission::Contents,
1345 GhPermissionValue::Write,
1346 )])
1347 .gh_set_pool(crate::pipelines_shared::gh_pools::gh_hosted_x64_linux())
1348 .dep_on(
1349 |ctx| flowey_lib_hvlite::_jobs::publish_vmgstool_gh_release::Request {
1350 vmgstools: vmgstools
1351 .into_iter()
1352 .map(|(t, v)| (t, ctx.use_typed_artifact(&v)))
1353 .collect(),
1354 done: ctx.new_done_handle(),
1355 },
1356 )
1357 .finish();
1358
1359 for job in all_jobs.iter() {
1361 pipeline.non_artifact_dep(&publish_vmgstool_job, job);
1362 }
1363 }
1364
1365 Ok(pipeline)
1366 }
1367}
1368
1369mod vmm_tests_artifact_builders {
1375 use flowey::pipeline::prelude::*;
1376 use flowey_lib_hvlite::_jobs::consume_and_test_nextest_vmm_tests_archive::VmmTestsDepArtifacts;
1377 use flowey_lib_hvlite::build_guest_test_uefi::GuestTestUefiOutput;
1378 use flowey_lib_hvlite::build_openvmm::OpenvmmOutput;
1379 use flowey_lib_hvlite::build_pipette::PipetteOutput;
1380 use flowey_lib_hvlite::build_prep_steps::PrepStepsOutput;
1381 use flowey_lib_hvlite::build_test_igvm_agent_rpc_server::TestIgvmAgentRpcServerOutput;
1382 use flowey_lib_hvlite::build_tmk_vmm::TmkVmmOutput;
1383 use flowey_lib_hvlite::build_tmks::TmksOutput;
1384 use flowey_lib_hvlite::build_tpm_guest_tests::TpmGuestTestsOutput;
1385 use flowey_lib_hvlite::build_vmgstool::VmgstoolOutput;
1386
1387 pub type ResolveVmmTestsDepArtifacts =
1388 Box<dyn Fn(&mut PipelineJobCtx<'_>) -> VmmTestsDepArtifacts>;
1389
1390 #[derive(Default)]
1391 pub struct VmmTestsArtifactsBuilderLinuxX86 {
1392 pub use_pipette_windows: Option<UseTypedArtifact<PipetteOutput>>,
1394 pub use_tmk_vmm: Option<UseTypedArtifact<TmkVmmOutput>>,
1395 pub use_openvmm: Option<UseTypedArtifact<OpenvmmOutput>>,
1397 pub use_pipette_linux_musl: Option<UseTypedArtifact<PipetteOutput>>,
1398 pub use_guest_test_uefi: Option<UseTypedArtifact<GuestTestUefiOutput>>,
1400 pub use_tmks: Option<UseTypedArtifact<TmksOutput>>,
1401 }
1402
1403 impl VmmTestsArtifactsBuilderLinuxX86 {
1404 pub fn finish(self) -> Result<ResolveVmmTestsDepArtifacts, &'static str> {
1405 let VmmTestsArtifactsBuilderLinuxX86 {
1406 use_openvmm,
1407 use_guest_test_uefi,
1408 use_pipette_windows,
1409 use_pipette_linux_musl,
1410 use_tmk_vmm,
1411 use_tmks,
1412 } = self;
1413
1414 let use_guest_test_uefi = use_guest_test_uefi.ok_or("guest_test_uefi")?;
1415 let use_openvmm = use_openvmm.ok_or("openvmm")?;
1416 let use_pipette_linux_musl = use_pipette_linux_musl.ok_or("pipette_linux_musl")?;
1417 let use_pipette_windows = use_pipette_windows.ok_or("pipette_windows")?;
1418 let use_tmk_vmm = use_tmk_vmm.ok_or("tmk_vmm")?;
1419 let use_tmks = use_tmks.ok_or("tmks")?;
1420
1421 Ok(Box::new(move |ctx| VmmTestsDepArtifacts {
1422 openvmm: Some(ctx.use_typed_artifact(&use_openvmm)),
1423 pipette_windows: Some(ctx.use_typed_artifact(&use_pipette_windows)),
1424 pipette_linux_musl: Some(ctx.use_typed_artifact(&use_pipette_linux_musl)),
1425 guest_test_uefi: Some(ctx.use_typed_artifact(&use_guest_test_uefi)),
1426 tmk_vmm: Some(ctx.use_typed_artifact(&use_tmk_vmm)),
1427 tmks: Some(ctx.use_typed_artifact(&use_tmks)),
1428 artifact_dir_openhcl_igvm_files: None,
1430 tmk_vmm_linux_musl: None,
1431 prep_steps: None,
1432 vmgstool: None,
1433 tpm_guest_tests_windows: None,
1434 tpm_guest_tests_linux: None,
1435 test_igvm_agent_rpc_server: None,
1436 }))
1437 }
1438 }
1439
1440 #[derive(Default, Clone)]
1441 pub struct VmmTestsArtifactsBuilderWindowsX86 {
1442 pub use_openvmm: Option<UseTypedArtifact<OpenvmmOutput>>,
1444 pub use_pipette_windows: Option<UseTypedArtifact<PipetteOutput>>,
1445 pub use_tmk_vmm: Option<UseTypedArtifact<TmkVmmOutput>>,
1446 pub use_prep_steps: Option<UseTypedArtifact<PrepStepsOutput>>,
1447 pub use_vmgstool: Option<UseTypedArtifact<VmgstoolOutput>>,
1448 pub use_tpm_guest_tests_windows: Option<UseTypedArtifact<TpmGuestTestsOutput>>,
1449 pub use_tpm_guest_tests_linux: Option<UseTypedArtifact<TpmGuestTestsOutput>>,
1450 pub use_test_igvm_agent_rpc_server: Option<UseTypedArtifact<TestIgvmAgentRpcServerOutput>>,
1451 pub use_openhcl_igvm_files: Option<UseArtifact>,
1453 pub use_pipette_linux_musl: Option<UseTypedArtifact<PipetteOutput>>,
1454 pub use_tmk_vmm_linux_musl: Option<UseTypedArtifact<TmkVmmOutput>>,
1455 pub use_guest_test_uefi: Option<UseTypedArtifact<GuestTestUefiOutput>>,
1457 pub use_tmks: Option<UseTypedArtifact<TmksOutput>>,
1458 }
1459
1460 impl VmmTestsArtifactsBuilderWindowsX86 {
1461 pub fn finish(self) -> Result<ResolveVmmTestsDepArtifacts, &'static str> {
1462 let VmmTestsArtifactsBuilderWindowsX86 {
1463 use_openvmm,
1464 use_pipette_windows,
1465 use_pipette_linux_musl,
1466 use_guest_test_uefi,
1467 use_openhcl_igvm_files,
1468 use_tmk_vmm,
1469 use_tmk_vmm_linux_musl,
1470 use_tmks,
1471 use_prep_steps,
1472 use_vmgstool,
1473 use_tpm_guest_tests_windows,
1474 use_tpm_guest_tests_linux,
1475 use_test_igvm_agent_rpc_server,
1476 } = self;
1477
1478 let use_openvmm = use_openvmm.ok_or("openvmm")?;
1479 let use_pipette_windows = use_pipette_windows.ok_or("pipette_windows")?;
1480 let use_pipette_linux_musl = use_pipette_linux_musl.ok_or("pipette_linux_musl")?;
1481 let use_guest_test_uefi = use_guest_test_uefi.ok_or("guest_test_uefi")?;
1482 let use_openhcl_igvm_files = use_openhcl_igvm_files.ok_or("openhcl_igvm_files")?;
1483 let use_tmk_vmm = use_tmk_vmm.ok_or("tmk_vmm")?;
1484 let use_tmk_vmm_linux_musl = use_tmk_vmm_linux_musl.ok_or("tmk_vmm_linux_musl")?;
1485 let use_tmks = use_tmks.ok_or("tmks")?;
1486 let use_prep_steps = use_prep_steps.ok_or("prep_steps")?;
1487 let use_vmgstool = use_vmgstool.ok_or("vmgstool")?;
1488 let use_tpm_guest_tests_windows =
1489 use_tpm_guest_tests_windows.ok_or("tpm_guest_tests_windows")?;
1490 let use_tpm_guest_tests_linux =
1491 use_tpm_guest_tests_linux.ok_or("tpm_guest_tests_linux")?;
1492 let use_test_igvm_agent_rpc_server =
1493 use_test_igvm_agent_rpc_server.ok_or("test_igvm_agent_rpc_server")?;
1494
1495 Ok(Box::new(move |ctx| VmmTestsDepArtifacts {
1496 openvmm: Some(ctx.use_typed_artifact(&use_openvmm)),
1497 pipette_windows: Some(ctx.use_typed_artifact(&use_pipette_windows)),
1498 pipette_linux_musl: Some(ctx.use_typed_artifact(&use_pipette_linux_musl)),
1499 guest_test_uefi: Some(ctx.use_typed_artifact(&use_guest_test_uefi)),
1500 artifact_dir_openhcl_igvm_files: Some(ctx.use_artifact(&use_openhcl_igvm_files)),
1501 tmk_vmm: Some(ctx.use_typed_artifact(&use_tmk_vmm)),
1502 tmk_vmm_linux_musl: Some(ctx.use_typed_artifact(&use_tmk_vmm_linux_musl)),
1503 tmks: Some(ctx.use_typed_artifact(&use_tmks)),
1504 prep_steps: Some(ctx.use_typed_artifact(&use_prep_steps)),
1505 vmgstool: Some(ctx.use_typed_artifact(&use_vmgstool)),
1506 tpm_guest_tests_windows: Some(ctx.use_typed_artifact(&use_tpm_guest_tests_windows)),
1507 tpm_guest_tests_linux: Some(ctx.use_typed_artifact(&use_tpm_guest_tests_linux)),
1508 test_igvm_agent_rpc_server: Some(
1509 ctx.use_typed_artifact(&use_test_igvm_agent_rpc_server),
1510 ),
1511 }))
1512 }
1513 }
1514
1515 #[derive(Default, Clone)]
1516 pub struct VmmTestsArtifactsBuilderWindowsAarch64 {
1517 pub use_openvmm: Option<UseTypedArtifact<OpenvmmOutput>>,
1519 pub use_pipette_windows: Option<UseTypedArtifact<PipetteOutput>>,
1520 pub use_tmk_vmm: Option<UseTypedArtifact<TmkVmmOutput>>,
1521 pub use_vmgstool: Option<UseTypedArtifact<VmgstoolOutput>>,
1522 pub use_openhcl_igvm_files: Option<UseArtifact>,
1524 pub use_pipette_linux_musl: Option<UseTypedArtifact<PipetteOutput>>,
1525 pub use_tmk_vmm_linux_musl: Option<UseTypedArtifact<TmkVmmOutput>>,
1526 pub use_guest_test_uefi: Option<UseTypedArtifact<GuestTestUefiOutput>>,
1528 pub use_tmks: Option<UseTypedArtifact<TmksOutput>>,
1529 }
1530
1531 impl VmmTestsArtifactsBuilderWindowsAarch64 {
1532 pub fn finish(self) -> Result<ResolveVmmTestsDepArtifacts, &'static str> {
1533 let VmmTestsArtifactsBuilderWindowsAarch64 {
1534 use_openvmm,
1535 use_pipette_windows,
1536 use_pipette_linux_musl,
1537 use_guest_test_uefi,
1538 use_openhcl_igvm_files,
1539 use_tmk_vmm,
1540 use_tmk_vmm_linux_musl,
1541 use_tmks,
1542 use_vmgstool,
1543 } = self;
1544
1545 let use_openvmm = use_openvmm.ok_or("openvmm")?;
1546 let use_pipette_windows = use_pipette_windows.ok_or("pipette_windows")?;
1547 let use_pipette_linux_musl = use_pipette_linux_musl.ok_or("pipette_linux_musl")?;
1548 let use_guest_test_uefi = use_guest_test_uefi.ok_or("guest_test_uefi")?;
1549 let use_openhcl_igvm_files = use_openhcl_igvm_files.ok_or("openhcl_igvm_files")?;
1550 let use_tmk_vmm = use_tmk_vmm.ok_or("tmk_vmm")?;
1551 let use_tmk_vmm_linux_musl = use_tmk_vmm_linux_musl.ok_or("tmk_vmm_linux_musl")?;
1552 let use_tmks = use_tmks.ok_or("tmks")?;
1553 let use_vmgstool = use_vmgstool.ok_or("vmgstool")?;
1554
1555 Ok(Box::new(move |ctx| VmmTestsDepArtifacts {
1556 openvmm: Some(ctx.use_typed_artifact(&use_openvmm)),
1557 pipette_windows: Some(ctx.use_typed_artifact(&use_pipette_windows)),
1558 pipette_linux_musl: Some(ctx.use_typed_artifact(&use_pipette_linux_musl)),
1559 guest_test_uefi: Some(ctx.use_typed_artifact(&use_guest_test_uefi)),
1560 artifact_dir_openhcl_igvm_files: Some(ctx.use_artifact(&use_openhcl_igvm_files)),
1561 tmk_vmm: Some(ctx.use_typed_artifact(&use_tmk_vmm)),
1562 tmk_vmm_linux_musl: Some(ctx.use_typed_artifact(&use_tmk_vmm_linux_musl)),
1563 tmks: Some(ctx.use_typed_artifact(&use_tmks)),
1564 prep_steps: None,
1565 vmgstool: Some(ctx.use_typed_artifact(&use_vmgstool)),
1566 tpm_guest_tests_windows: None,
1567 tpm_guest_tests_linux: None,
1568 test_igvm_agent_rpc_server: None,
1569 }))
1570 }
1571 }
1572}