Skip to main content

flowey_lib_hvlite/
download_release_igvm_files_from_gh.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use flowey::node::prelude::*;
5
6#[derive(Serialize, Deserialize)]
7pub struct ReleaseOutput {
8    // Individual artifact paths (may reside in different directories)
9    pub openhcl_direct: Option<PathBuf>,
10    pub openhcl: Option<PathBuf>,
11    pub openhcl_aarch64: Option<PathBuf>,
12}
13
14impl Artifact for ReleaseOutput {}
15
16#[derive(Serialize, Deserialize, Clone, Debug, Copy)]
17pub enum OpenhclReleaseVersion {
18    Release2411,
19    Release2505,
20    Release2511,
21}
22
23impl OpenhclReleaseVersion {
24    pub fn branch_name(&self) -> String {
25        match self {
26            OpenhclReleaseVersion::Release2411 => "release/2411".to_string(),
27            OpenhclReleaseVersion::Release2505 => "release/2505".to_string(),
28            OpenhclReleaseVersion::Release2511 => "release/1.7.2511".to_string(),
29        }
30    }
31
32    pub const ALL: [OpenhclReleaseVersion; 3] = [
33        OpenhclReleaseVersion::Release2411,
34        OpenhclReleaseVersion::Release2505,
35        OpenhclReleaseVersion::Release2511,
36    ];
37
38    pub fn latest() -> Self {
39        *Self::ALL.last().unwrap()
40    }
41}
42
43impl std::fmt::Display for OpenhclReleaseVersion {
44    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45        let s = match self {
46            OpenhclReleaseVersion::Release2411 => "release-2411",
47            OpenhclReleaseVersion::Release2505 => "release-2505",
48            OpenhclReleaseVersion::Release2511 => "release-2511",
49        };
50        f.write_str(s)
51    }
52}
53
54pub mod resolve {
55    use super::OpenhclReleaseVersion;
56    use super::ReleaseOutput;
57    use crate::common::CommonArch;
58    use flowey::node::prelude::*;
59    use flowey_lib_common::gh_workflow_id;
60
61    flowey_request! {
62        pub struct Request {
63            pub release_igvm_files: WriteVar<ReleaseOutput>,
64            pub release_version: OpenhclReleaseVersion,
65            pub arch: CommonArch,
66        }
67    }
68
69    new_simple_flow_node!(struct Node);
70
71    impl SimpleFlowNode for Node {
72        type Request = Request;
73
74        fn imports(ctx: &mut ImportCtx<'_>) {
75            ctx.import::<flowey_lib_common::download_gh_artifact::Node>();
76            ctx.import::<gh_workflow_id::Node>();
77        }
78
79        fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
80            let branch_name: ReadVar<String> =
81                ReadVar::from_static(request.release_version.branch_name());
82
83            let run = ctx.reqv(|v| gh_workflow_id::Request {
84                repo_owner: "microsoft".into(),
85                repo_name: "openvmm".into(),
86                commit_or_branch: gh_workflow_id::GitCommitOrBranch::Branch(branch_name),
87                pipeline_name: "openvmm-ci.yaml".into(),
88                require_run_status: Some(gh_workflow_id::GhRunStatus::Success),
89                require_successful_job_with_name: None,
90                gh_workflow: v,
91            });
92            let run_id = run.map(ctx, |r| r.id);
93
94            let output = request.release_igvm_files;
95
96            let arch_str = match request.arch {
97                CommonArch::X86_64 => "x64",
98                CommonArch::Aarch64 => "aarch64",
99            };
100
101            let downloaded_artifact =
102                ctx.reqv(|v| flowey_lib_common::download_gh_artifact::Request {
103                    repo_owner: "microsoft".into(),
104                    repo_name: "openvmm".into(),
105                    file_name: format!("{arch_str}-openhcl-igvm"),
106                    path: v,
107                    run_id: run_id.clone(),
108                });
109            let arch = request.arch;
110
111            ctx.emit_minor_rust_step("write to directory variables", |ctx| {
112                let downloaded_artifact = downloaded_artifact.claim(ctx);
113                let write_release_output = output.claim(ctx);
114
115                move |rt| {
116                    let downloaded_artifact = rt.read(downloaded_artifact);
117                    let mut openhcl_direct = None;
118                    let mut openhcl = None;
119                    let mut openhcl_aarch64 = None;
120
121                    match arch {
122                        CommonArch::X86_64 => {
123                            // x64 build contains both openhcl.bin and openhcl-direct.bin
124                            openhcl_direct = Some(downloaded_artifact.join("openhcl-direct.bin"));
125                            openhcl = Some(downloaded_artifact.join("openhcl.bin"));
126                        }
127                        CommonArch::Aarch64 => {
128                            openhcl_aarch64 = Some(downloaded_artifact.join("openhcl-aarch64.bin"));
129                        }
130                    }
131
132                    rt.write_not_secret(
133                        write_release_output,
134                        &ReleaseOutput {
135                            openhcl_direct,
136                            openhcl,
137                            openhcl_aarch64,
138                        },
139                    );
140                }
141            });
142
143            Ok(())
144        }
145    }
146}