Deploy SvelteKit apps with kind = "sveltekit"
The vite-spa deploy path is now process_deploy_static_site.rs, and its record/rsync/mark-done flow is shared by both kinds. A sveltekit project builds with SvelteKitBuild and ships adapter-static's output, which defaults to build/ instead of dist/. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
keypair34 committed
Sep 30, 2026 at 14:12 UTC
cc6389f03311de02acdbf8da8f26f8ccc54ae739
4 files changed
+55
-15
crates/cli/src/cloud-deploy/mod.rs
+1
-1
@@ -4,8 +4,8 @@ pub mod process_deploy;
4
pub mod process_deploy_nextjs_ssr;
5
pub mod process_deploy_rails;
6
pub mod process_deploy_rust;
7
+pub mod process_deploy_static_site;
8
pub mod process_deploy_swift;
8
-pub mod process_deploy_vite_spa;
9
pub mod process_migrate;
10
mod remote_messages;
11
pub(crate) mod setup_create_new_project;
crates/cli/src/cloud-deploy/process_deploy.rs
+6
-1
@@ -9,8 +9,8 @@ use {
9
process_deploy_nextjs_ssr::process_deploy_nextjs_ssr,
10
process_deploy_rails::process_deploy_rails,
11
process_deploy_rust::process_deploy_rust,
12
+ process_deploy_static_site::{process_deploy_sveltekit, process_deploy_vite_spa},
13
process_deploy_swift::process_deploy_swift,
13
- process_deploy_vite_spa::process_deploy_vite_spa,
14
remote_messages::{build_next_app, start_server},
15
},
16
token::{get_smb_token::get_smb_token, is_logged_in::is_logged_in},
@@ -144,6 +144,11 @@ pub async fn process_deploy(
144
return process_deploy_vite_spa(env, config).await;
145
}
146
147
+ // Route SvelteKit projects built with adapter-static: install + build, rsync the output.
148
+ if config.project.kind.as_deref() == Some("sveltekit") {
149
+ return process_deploy_sveltekit(env, config).await;
150
+ }
151
+
152
// Route Next.js SSR projects: pnpm install + build, rsync 8 items, SSH pm2 restart.
153
if config.project.kind.as_deref() == Some("nextjs-ssr") {
154
return process_deploy_nextjs_ssr(env, config).await;
crates/cli/src/cloud-deploy/process_deploy_static_site.rs
renamed
+46
-11
@@ -18,13 +18,53 @@ use {
18
};
19
20
pub async fn process_deploy_vite_spa(env: Environment, config: Config) -> Result<CommandResult> {
21
- // Resolve required SPA fields from the project config.
21
// `source` is the local directory containing the vite project (e.g. "frontend/connected-devices/").
22
// `path` is the remote destination on the server, consumed by rsync_deploy.
24
- let project_path = config.project.source.as_deref().unwrap_or(".");
25
- let output_dir = config.project.output.as_deref().unwrap_or("dist");
26
- let package_manager = config.project.package_manager.as_deref().unwrap_or("pnpm");
23
+ let strategy = smbcloud_deploy::ViteSpaBuild {
24
+ project_path: config.project.source.as_deref().unwrap_or(".").to_string(),
25
+ output_dir: config
26
+ .project
27
+ .output
28
+ .as_deref()
29
+ .unwrap_or("dist")
30
+ .to_string(),
31
+ package_manager: config
32
+ .project
33
+ .package_manager
34
+ .as_deref()
35
+ .unwrap_or("pnpm")
36
+ .to_string(),
37
+ };
38
+ deploy_static_build(env, config, &strategy).await
39
+}
40
+
41
+pub async fn process_deploy_sveltekit(env: Environment, config: Config) -> Result<CommandResult> {
42
+ // adapter-static writes to `build/` unless svelte.config.js sets `pages`.
43
+ let strategy = smbcloud_deploy::SvelteKitBuild {
44
+ project_path: config.project.source.as_deref().unwrap_or(".").to_string(),
45
+ output_dir: config
46
+ .project
47
+ .output
48
+ .as_deref()
49
+ .unwrap_or("build")
50
+ .to_string(),
51
+ package_manager: config
52
+ .project
53
+ .package_manager
54
+ .as_deref()
55
+ .unwrap_or("pnpm")
56
+ .to_string(),
57
+ };
58
+ deploy_static_build(env, config, &strategy).await
59
+}
60
61
+/// Builds locally with `strategy`, then rsyncs the output to the project's
62
+/// remote `path` for nginx to serve as static files.
63
+async fn deploy_static_build(
64
+ env: Environment,
65
+ config: Config,
66
+ strategy: &dyn BuildStrategy,
67
+) -> Result<CommandResult> {
68
// Fetch user for SSH key and deployment record.
69
let access_token = crate::token::get_smb_token::get_smb_token(env)?;
70
let user = me(env, client(), &access_token).await?;
@@ -32,16 +72,11 @@ pub async fn process_deploy_vite_spa(env: Environment, config: Config) -> Result
72
// ── Step 1: build locally (engine BuildStrategy) ─────────────────────────
73
74
let reporter = crate::ui::reporter::SpinnerReporter::new();
35
- let artifact = smbcloud_deploy::ViteSpaBuild {
36
- project_path: project_path.to_string(),
37
- output_dir: output_dir.to_string(),
38
- package_manager: package_manager.to_string(),
39
- }
40
- .build(&reporter)?;
75
+ let artifact = strategy.build(&reporter)?;
76
77
// ── Step 2: record deployment as Started ─────────────────────────────────
78
//
44
- // A pure rsync SPA deploy has no git commit hash; use a UTC timestamp as a
79
+ // A pure rsync static deploy has no git commit hash; use a UTC timestamp as a
80
// lightweight, non-empty identifier for the API record.
81
82
let deploy_ref = Utc::now().format("%Y%m%dT%H%M%SZ").to_string();
crates/smbcloud-model/src/project.rs
+2
-2
@@ -85,11 +85,11 @@ pub struct Project {
85
pub created_at: DateTime<Utc>,
86
#[serde(default = "default_datetime")]
87
pub updated_at: DateTime<Utc>,
88
- /// Deployment kind, e.g. "vite-spa", "nextjs-ssr", or "rust".
88
+ /// Deployment kind, e.g. "vite-spa", "sveltekit", "nextjs-ssr", or "rust".
89
pub kind: Option<String>,
90
/// Local source directory to build from, e.g. "frontend/connected-devices"
91
/// or a Rust crate root like ".".
92
- /// Used by local-build deploys such as vite-spa, nextjs-ssr, and rust.
92
+ /// Used by local-build deploys such as vite-spa, sveltekit, nextjs-ssr, and rust.
93
/// Distinct from `path`, which is the remote destination on the server.
94
pub source: Option<String>,
95
/// Build output directory relative to `source`, e.g. "dist".