flowey_lib_hvlite/_jobs/
check_openvmm_hcl_size.rs1use crate::artifact_openhcl_igvm_from_recipe_extras;
7use crate::build_openhcl_igvm_from_recipe;
8use crate::build_openhcl_igvm_from_recipe::OpenhclIgvmRecipe;
9use crate::build_openvmm_hcl;
10use crate::build_openvmm_hcl::OpenvmmHclBuildParams;
11use crate::build_openvmm_hcl::OpenvmmHclBuildProfile::OpenvmmHclShip;
12use crate::run_cargo_build::common::CommonArch;
13use crate::run_cargo_build::common::CommonPlatform;
14use crate::run_cargo_build::common::CommonTriple;
15use flowey::node::prelude::*;
16use flowey_lib_common::download_gh_artifact;
17use flowey_lib_common::gh_workflow_id;
18use flowey_lib_common::git_merge_commit;
19
20flowey_request! {
21 pub struct Request {
22 pub target: CommonTriple,
23 pub done: WriteVar<SideEffect>,
24 pub pipeline_name: String,
25 pub job_name: String,
26 }
27}
28
29new_simple_flow_node!(struct Node);
30
31impl SimpleFlowNode for Node {
32 type Request = Request;
33
34 fn imports(ctx: &mut ImportCtx<'_>) {
35 ctx.import::<crate::build_xtask::Node>();
36 ctx.import::<crate::git_checkout_openvmm_repo::Node>();
37 ctx.import::<download_gh_artifact::Node>();
38 ctx.import::<git_merge_commit::Node>();
39 ctx.import::<gh_workflow_id::Node>();
40 ctx.import::<build_openhcl_igvm_from_recipe::Node>();
41 ctx.import::<build_openvmm_hcl::Node>();
42 ctx.import::<artifact_openhcl_igvm_from_recipe_extras::publish::Node>();
43 }
44
45 fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
46 let Request {
47 target,
48 done,
49 pipeline_name,
50 job_name,
51 } = request;
52
53 let xtask_target = CommonTriple::Common {
54 arch: match ctx.arch() {
55 FlowArch::X86_64 => CommonArch::X86_64,
56 FlowArch::Aarch64 => CommonArch::Aarch64,
57 arch => anyhow::bail!("unsupported arch {arch}"),
58 },
59 platform: match ctx.platform() {
60 FlowPlatform::Windows => CommonPlatform::WindowsMsvc,
61 FlowPlatform::Linux(_) => CommonPlatform::LinuxGnu,
62 FlowPlatform::MacOs => CommonPlatform::MacOs,
63 platform => anyhow::bail!("unsupported platform {platform}"),
64 },
65 };
66
67 let xtask = ctx.reqv(|v| crate::build_xtask::Request {
68 target: xtask_target,
69 xtask: v,
70 });
71 let openvmm_repo_path = ctx.reqv(crate::git_checkout_openvmm_repo::req::GetRepoDir);
72
73 let recipe = match target.common_arch().unwrap() {
74 CommonArch::X86_64 => OpenhclIgvmRecipe::X64,
75 CommonArch::Aarch64 => OpenhclIgvmRecipe::Aarch64,
76 }
77 .recipe_details(true);
78
79 let built_openvmm_hcl = ctx.reqv(|v| build_openvmm_hcl::Request {
80 build_params: OpenvmmHclBuildParams {
81 target: target.clone(),
82 profile: OpenvmmHclShip,
83 features: recipe.openvmm_hcl_features,
84 no_split_dbg_info: false,
85 max_trace_level: recipe.max_trace_level,
86 },
87 openvmm_hcl_output: v,
88 });
89
90 let file_name = match target.common_arch().unwrap() {
91 CommonArch::X86_64 => "x64-openhcl-baseline",
92 CommonArch::Aarch64 => "aarch64-openhcl-baseline",
93 };
94
95 let merge_commit = ctx.reqv(|v| git_merge_commit::Request {
96 repo_path: openvmm_repo_path.clone(),
97 merge_commit: v,
98 base_branch: "main".into(),
99 });
100
101 let merge_run = ctx.reqv(|v| {
102 gh_workflow_id::Request::WithStatusAndJob(gh_workflow_id::QueryWithStatusAndJob {
103 params: gh_workflow_id::WorkflowQueryParams {
104 github_commit_hash: merge_commit,
105 repo_path: openvmm_repo_path.clone(),
106 pipeline_name,
107 gh_workflow: v,
108 },
109 gh_run_status: gh_workflow_id::GhRunStatus::Completed,
110 gh_run_job_name: job_name,
111 })
112 });
113
114 let run_id = merge_run.map(ctx, |r| r.id);
115 let merge_head_artifact = ctx.reqv(|old_openhcl| download_gh_artifact::Request {
116 repo_owner: "microsoft".into(),
117 repo_name: "openvmm".into(),
118 file_name: file_name.into(),
119 path: old_openhcl,
120 run_id,
121 });
122
123 let publish_artifact = if ctx.backend() == FlowBackend::Github {
129 let dir = ctx.emit_rust_stepv("collect openvmm_hcl files for analysis", |ctx| {
130 let built_openvmm_hcl = built_openvmm_hcl.clone().claim(ctx);
131 move |rt| {
132 let built_openvmm_hcl = rt.read(built_openvmm_hcl);
133 let path = Path::new("artifact");
134 fs_err::create_dir_all(path)?;
135 fs_err::copy(built_openvmm_hcl.bin, path.join("openvmm_hcl"))?;
136 if let Some(dbg) = built_openvmm_hcl.dbg {
137 fs_err::copy(dbg, path.join("openvmm_hcl.dbg"))?;
138 }
139 Ok(path
140 .absolute()?
141 .into_os_string()
142 .into_string()
143 .ok()
144 .unwrap())
145 }
146 });
147 let name = format!(
148 "{}_openvmm_hcl_for_size_analysis",
149 target.common_arch().unwrap().as_arch()
150 );
151 Some(
152 ctx.emit_gh_step(
153 "publish openvmm_hcl for analysis",
154 "actions/upload-artifact@v4",
155 )
156 .with("name", name)
157 .with("path", dir)
158 .finish(ctx),
159 )
160 } else {
161 None
162 };
163
164 let comparison = ctx.emit_rust_step("binary size comparison", |ctx| {
165 let _publish_artifact = publish_artifact.claim(ctx);
167 let xtask = xtask.claim(ctx);
168 let openvmm_repo_path = openvmm_repo_path.claim(ctx);
169 let old_openhcl = merge_head_artifact.claim(ctx);
170 let new_openhcl = built_openvmm_hcl.claim(ctx);
171 let merge_run = merge_run.claim(ctx);
172
173 move |rt| {
174 let xtask = match rt.read(xtask) {
175 crate::build_xtask::XtaskOutput::LinuxBin { bin, .. } => bin,
176 crate::build_xtask::XtaskOutput::WindowsBin { exe, .. } => exe,
177 };
178
179 let old_openhcl = rt.read(old_openhcl);
180 let new_openhcl = rt.read(new_openhcl);
181 let merge_run = rt.read(merge_run);
182
183 let old_path = old_openhcl.join(file_name).join("openhcl");
184 let new_path = new_openhcl.bin;
185
186 println!(
187 "comparing HEAD to merge commit {} and workflow {}",
188 merge_run.commit, merge_run.id
189 );
190
191 let sh = xshell::Shell::new()?;
192 sh.change_dir(rt.read(openvmm_repo_path));
193 xshell::cmd!(
194 sh,
195 "{xtask} verify-size --original {old_path} --new {new_path}"
196 )
197 .run()?;
198
199 Ok(())
200 }
201 });
202
203 ctx.emit_side_effect_step(vec![comparison], [done]);
204
205 Ok(())
206 }
207}