1use crate::cli::{BuildArgs, DeployArgs, WasmPlatform};
6use crate::error::{CliError, CliResult};
7use std::path::Path;
8use std::process::Command;
9
10pub fn execute(args: &DeployArgs) -> CliResult<()> {
12 let project_path = args.path.canonicalize().map_err(|e| {
13 CliError::Other(format!(
14 "Failed to resolve project path '{}': {}",
15 args.path.display(),
16 e
17 ))
18 })?;
19
20 println!("Deploying MCP server to {}...", args.platform);
21
22 if !args.skip_build {
24 build_for_deploy(args, &project_path)?;
25 }
26
27 match args.platform {
29 WasmPlatform::CloudflareWorkers => deploy_cloudflare(args, &project_path),
30 WasmPlatform::DenoWorkers => deploy_deno(args, &project_path),
31 WasmPlatform::Wasm32 => Err(CliError::NotSupported(
32 "Generic WASM32 deployment is not supported. Please specify a platform.".to_string(),
33 )),
34 }
35}
36
37fn build_for_deploy(args: &DeployArgs, project_path: &Path) -> CliResult<()> {
39 let build_args = BuildArgs {
40 path: project_path.to_path_buf(),
41 platform: Some(args.platform.clone()),
42 target: None,
43 release: args.release,
44 optimize: args.optimize,
45 features: vec![],
46 no_default_features: false,
47 output: None,
48 };
49
50 crate::build::execute(&build_args)
51}
52
53fn deploy_cloudflare(args: &DeployArgs, project_path: &Path) -> CliResult<()> {
55 let wrangler_check = Command::new("wrangler").arg("--version").output();
57
58 if wrangler_check.is_err() {
59 return Err(CliError::Other(
60 "wrangler CLI not found. Install with: npm install -g wrangler".to_string(),
61 ));
62 }
63
64 let config_path = args
66 .wrangler_config
67 .clone()
68 .unwrap_or_else(|| project_path.join("wrangler.toml"));
69
70 if !config_path.exists() {
71 return Err(CliError::Other(format!(
72 "wrangler.toml not found at '{}'. Create one or specify --wrangler-config",
73 config_path.display()
74 )));
75 }
76
77 let mut cmd = Command::new("wrangler");
79 cmd.arg("deploy");
80 cmd.current_dir(project_path);
81
82 if args.wrangler_config.is_some() {
84 cmd.arg("--config").arg(&config_path);
85 }
86
87 if let Some(ref env) = args.env {
89 cmd.arg("--env").arg(env);
90 }
91
92 if args.dry_run {
94 cmd.arg("--dry-run");
95 }
96
97 println!(
98 "Running: wrangler deploy{}",
99 if args.dry_run { " --dry-run" } else { "" }
100 );
101
102 let status = cmd
104 .status()
105 .map_err(|e| CliError::Other(format!("Failed to execute wrangler: {}", e)))?;
106
107 if !status.success() {
108 return Err(CliError::Other("Wrangler deploy failed".to_string()));
109 }
110
111 if args.dry_run {
112 println!("Dry run complete. No changes were made.");
113 } else {
114 println!("Deployment successful!");
115 }
116
117 Ok(())
118}
119
120fn deploy_deno(args: &DeployArgs, project_path: &Path) -> CliResult<()> {
122 let deployctl_check = Command::new("deployctl").arg("--version").output();
124
125 if deployctl_check.is_err() {
126 return Err(CliError::Other(
127 "deployctl not found. Install with: deno install --allow-all --name=deployctl https://deno.land/x/deploy/deployctl.ts".to_string(),
128 ));
129 }
130
131 let config_path = project_path.join("deno.json");
133 let main_path = if config_path.exists() {
134 None } else {
137 let candidates = ["main.ts", "mod.ts", "index.ts", "src/main.ts"];
139 candidates
140 .iter()
141 .map(|c| project_path.join(c))
142 .find(|p| p.exists())
143 };
144
145 let mut cmd = Command::new("deployctl");
147 cmd.arg("deploy");
148 cmd.current_dir(project_path);
149
150 if let Some(ref main) = main_path {
152 cmd.arg("--entrypoint").arg(main);
153 }
154
155 if let Some(ref env) = args.env {
157 cmd.arg("--project").arg(env);
158 }
159
160 if args.dry_run {
162 cmd.arg("--dry-run");
163 }
164
165 println!(
166 "Running: deployctl deploy{}",
167 if args.dry_run { " --dry-run" } else { "" }
168 );
169
170 let status = cmd
172 .status()
173 .map_err(|e| CliError::Other(format!("Failed to execute deployctl: {}", e)))?;
174
175 if !status.success() {
176 return Err(CliError::Other("Deno Deploy failed".to_string()));
177 }
178
179 if args.dry_run {
180 println!("Dry run complete. No changes were made.");
181 } else {
182 println!("Deployment successful!");
183 }
184
185 Ok(())
186}
187
188#[cfg(test)]
189mod tests {
190 use super::*;
191
192 #[test]
193 fn test_platform_display() {
194 assert_eq!(
195 WasmPlatform::CloudflareWorkers.to_string(),
196 "cloudflare-workers"
197 );
198 assert_eq!(WasmPlatform::DenoWorkers.to_string(), "deno-workers");
199 assert_eq!(WasmPlatform::Wasm32.to_string(), "wasm32");
200 }
201}