beet_cli/commands/
run_deploy.rs

1use crate::prelude::*;
2use anyhow::Result;
3use beet::prelude::*;
4use clap::Parser;
5use std::process::Command;
6
7/// Deploy to AWS Lambda in release mode.
8#[derive(Debug, Parser)]
9pub struct RunDeploy {
10	#[command(flatten)]
11	pub build: RunBuild,
12	/// Specify the region to deploy the lambda function to
13	#[arg(long)]
14	pub region: Option<String>,
15	/// use a specificed name for the lambda function,
16	/// defaults to the package name
17	#[arg(long)]
18	pub function_name: Option<String>,
19	/// Specify the IAM role that the lambda function should use
20	#[arg(long)]
21	pub iam_role: Option<String>,
22	/// Build but do not deploy
23	#[arg(long)]
24	pub dry_run: bool,
25	/// Also deploy sst infrastructure using a config file
26	/// located at `infra/sst.config.ts`
27	#[arg(long)]
28	pub sst: bool,
29}
30
31
32impl RunDeploy {
33	/// Builds all required files and runs:
34	/// - Build template map used by the binary
35	/// - Build static files
36
37	pub fn run(mut self) -> Result<()> {
38		self.build.build_cmd.release = true;
39		self.build.clone().into_group()?.run()?;
40
41		self.lambda_build()?;
42		if !self.dry_run {
43			if self.sst {
44				self.sst_deploy()?;
45			}
46			self.lambda_deploy()?;
47		}
48		Ok(())
49	}
50
51	fn lambda_build(&self) -> Result<()> {
52		let mut cmd = Command::new("cargo");
53		cmd.arg("lambda")
54			.arg("build")
55			.arg("--features")
56			.arg("beet/lambda")
57			.arg("--release");
58		// this is where sst expects the boostrap to be located
59		// .arg("--lambda-dir")
60		// .arg("target/lambda/crates");
61
62		if let Some(pkg) = &self.build.build_cmd.package {
63			cmd.arg("--package").arg(pkg);
64		}
65		println!("🌱 Compiling lambda binary");
66		cmd.spawn()?.wait()?.exit_ok()?;
67		Ok(())
68	}
69	fn sst_deploy(&self) -> Result<()> {
70		Command::new("npx")
71			.arg("sst")
72			.arg("deploy")
73			.arg("--stage")
74			.arg("production")
75			.arg("--config")
76			.arg("infra/sst.config.ts")
77			.spawn()?
78			.wait()?
79			.exit_ok()?
80			.xok()
81	}
82
83	/// Deploy to lambda, using best effort to determine the binary name
84	#[allow(unused)]
85	fn lambda_deploy(&self) -> Result<()> {
86		let mut cmd = Command::new("cargo");
87
88		let binary_name = if let Some(bin) = &self.build.build_cmd.bin {
89			Some(bin)
90		} else if let Some(pkg) = &self.build.build_cmd.package {
91			Some(pkg)
92		} else {
93			None
94		};
95
96		cmd.arg("lambda")
97			.arg("deploy")
98			.arg("--enable-function-url")
99			.arg("--include")
100			.arg(&self.build.build_args.html_dir);
101
102		if let Some(bin) = &binary_name {
103			cmd.arg("--binary-name").arg(&bin);
104		}
105
106		if let Some(iam_role) = &self.iam_role {
107			cmd.arg("--iam-role").arg(iam_role);
108		}
109		if let Some(region) = &self.region {
110			cmd.arg("--region").arg(region);
111		};
112
113		if let Some(name) = &self.function_name {
114			cmd.arg(name);
115		}
116
117		cmd.spawn()?.wait()?.exit_ok()?;
118
119		Ok(())
120	}
121}