flowey_lib_common/
download_gh_artifact.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Download a github release artifact
5
6use flowey::node::prelude::*;
7
8flowey_request! {
9    pub struct Request {
10        /// First component of a github repo path
11        ///
12        /// e.g: the "foo" in "github.com/foo/bar"
13        pub repo_owner: String,
14        /// Second component of a github repo path
15        ///
16        /// e.g: the "bar" in "github.com/foo/bar"
17        pub repo_name: String,
18        /// Specific artifact to download.
19        pub file_name: String,
20        /// Path to downloaded artifact.
21        pub path: WriteVar<PathBuf>,
22        /// The Github actions run id to download artifacts from
23        pub run_id: ReadVar<String>,
24    }
25}
26
27new_simple_flow_node!(struct Node);
28
29impl SimpleFlowNode for Node {
30    type Request = Request;
31
32    fn imports(ctx: &mut ImportCtx<'_>) {
33        ctx.import::<crate::cache::Node>();
34        ctx.import::<crate::use_gh_cli::Node>();
35    }
36
37    fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
38        let Request {
39            repo_owner,
40            repo_name,
41            file_name,
42            path,
43            run_id,
44        } = request;
45
46        let gh_cli = ctx.reqv(crate::use_gh_cli::Request::Get);
47
48        ctx.emit_rust_step("download artifacts from github actions run", |ctx| {
49            let gh_cli = gh_cli.claim(ctx);
50            let run_id = run_id.claim(ctx);
51            let path = path.claim(ctx);
52            move |rt| {
53                let sh = xshell::Shell::new()?;
54                let gh_cli = rt.read(gh_cli);
55                let run_id = rt.read(run_id);
56
57                let path_end = format!("{repo_owner}/{repo_name}/{run_id}");
58                let out_dir = std::env::current_dir()?.absolute()?.join(path_end);
59                fs_err::create_dir_all(&out_dir)?;
60                sh.change_dir(&out_dir);
61
62                xshell::cmd!(sh, "{gh_cli} run download {run_id} -R {repo_owner}/{repo_name} --pattern {file_name}").run()?;
63
64                if !out_dir.join(file_name).exists() {
65                    anyhow::bail!("Failed to download artifact");
66                }
67
68                rt.write(path, &out_dir);
69                Ok(())
70            }
71        });
72
73        Ok(())
74    }
75}