flowey_lib_common/
install_azure_cli.rs1use flowey::node::prelude::*;
7
8flowey_request! {
9 pub enum Request {
10 AutoInstall(bool),
14 Version(String),
16 GetAzureCli(WriteVar<PathBuf>),
18 }
19}
20
21new_flow_node!(struct Node);
22
23impl FlowNode for Node {
24 type Request = Request;
25
26 fn imports(_ctx: &mut ImportCtx<'_>) {}
27
28 fn emit(requests: Vec<Self::Request>, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
29 let mut auto_install = None;
30 let mut version = None;
31 let mut get_az_cli = Vec::new();
32
33 for req in requests {
34 match req {
35 Request::AutoInstall(v) => {
36 same_across_all_reqs("AutoInstall", &mut auto_install, v)?
37 }
38 Request::Version(v) => same_across_all_reqs("Version", &mut version, v)?,
39 Request::GetAzureCli(v) => get_az_cli.push(v),
40 }
41 }
42
43 if get_az_cli.is_empty() {
46 return Ok(());
47 }
48
49 let auto_install = auto_install;
50 let version = version.ok_or(anyhow::anyhow!("Missing essential request: Version"))?;
51 let get_az_cli = get_az_cli;
52
53 let check_az_install = {
56 |_rt: &RustRuntimeServices<'_>| -> anyhow::Result<PathBuf> {
57 let Ok(path) = which::which("az") else {
58 anyhow::bail!("did not find `az` on $PATH");
59 };
60
61 anyhow::Ok(path)
63 }
64 };
65
66 match ctx.backend() {
67 FlowBackend::Local => {
68 let auto_install = auto_install
69 .ok_or(anyhow::anyhow!("Missing essential request: AutoInstall"))?;
70
71 if auto_install {
72 ctx.emit_rust_step("installing azure-cli", |ctx| {
73 let get_az_cli = get_az_cli.claim(ctx);
74 move |rt| {
75 log::warn!("automatic azure-cli installation is not supported yet!");
76 log::warn!(
77 "follow the guide, and manually ensure you have azure-cli installed"
78 );
79 log::warn!(" ensure you have azure-cli version {version} installed");
80 log::warn!("press <enter> to continue");
81 let _ = std::io::stdin().read_line(&mut String::new());
82
83 let path = check_az_install(rt)?;
84 rt.write_all(get_az_cli, &path);
85 Ok(())
86 }
87 })
88 } else {
89 ctx.emit_rust_step("detecting azure-cli install", |ctx| {
90 let get_az_cli = get_az_cli.claim(ctx);
91 move |rt| {
92 let path = check_az_install(rt)?;
93 rt.write_all(get_az_cli, &path);
94 Ok(())
95 }
96 })
97 }
98 }
99 FlowBackend::Ado => {
100 if !auto_install.unwrap_or(true) {
101 anyhow::bail!("AutoInstall must be `true` when running on ADO")
102 }
103
104 ctx.emit_rust_step("detecting azure-cli install", |ctx| {
107 let get_az_cli = get_az_cli.claim(ctx);
108 move |rt| {
109 let path = check_az_install(rt)?;
110 rt.write_all(get_az_cli, &path);
111 Ok(())
112 }
113 })
114 }
115 FlowBackend::Github => {
116 if !auto_install.unwrap_or(true) {
117 anyhow::bail!("AutoInstall must be `true` when running on Github Actions")
118 }
119
120 ctx.emit_rust_step("installing azure-cli", |ctx| {
121 let get_az_cli = get_az_cli.claim(ctx);
122 move |rt| {
123 let sh = xshell::Shell::new()?;
124 if let Ok(path) = check_az_install(rt) {
125 rt.write_all(get_az_cli, &path);
126 return Ok(());
127 }
128 match rt.platform() {
129 FlowPlatform::Windows => {
130 let az_dir = sh.current_dir().join("az");
131 sh.create_dir(&az_dir)?;
132 sh.change_dir(&az_dir);
133 xshell::cmd!(
134 sh,
135 "curl --fail -L https://aka.ms/installazurecliwindowszipx64 -o az.zip"
136 )
137 .run()?;
138 xshell::cmd!(sh, "tar -xf az.zip").run()?;
139 rt.write_all(get_az_cli, &az_dir.join("bin\\az.cmd"));
140 }
141 FlowPlatform::Linux(_) => {
142 xshell::cmd!(
143 sh,
144 "curl --fail -sL https://aka.ms/InstallAzureCLIDeb -o InstallAzureCLIDeb.sh"
145 )
146 .run()?;
147 xshell::cmd!(sh, "chmod +x ./InstallAzureCLIDeb.sh").run()?;
148 xshell::cmd!(sh, "sudo ./InstallAzureCLIDeb.sh").run()?;
149 let path = check_az_install(rt)?;
150 rt.write_all(get_az_cli, &path);
151 }
152 platform => anyhow::bail!("unsupported platform {platform}"),
153 };
154
155 Ok(())
156 }
157 })
158 }
159 };
160
161 Ok(())
162 }
163}