Skip to content

Commit 4035ab4

Browse files
committed
update docs
1 parent 9848735 commit 4035ab4

3 files changed

Lines changed: 109 additions & 74 deletions

File tree

apps/cli/src/cloud.rs

Lines changed: 91 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,7 +1022,86 @@ fn deploy() -> Result<()> {
10221022
println!(" Deployment v{} created. Waiting for provisioning...", version);
10231023
println!();
10241024

1025-
// Stream deployment events via SSE
1025+
// Phase 1: Stream events until infra is ready (migrating state)
1026+
let phase1_status = stream_deployment_events(&client, &pid)?;
1027+
1028+
match phase1_status.as_str() {
1029+
"migrating" => {
1030+
println!();
1031+
println!(" ▸ Infrastructure ready. Running migrations...");
1032+
1033+
// Get the SurrealDB URL from deployment status
1034+
if let Ok(status_resp) = client.get(&format!("/v1/projects/{}/deployment", pid)) {
1035+
if let Ok(status_data) = status_resp.into_json::<serde_json::Value>() {
1036+
if let Some(db_url) = status_data["urls"]["surrealdb"].as_str() {
1037+
// Run migrations against the cloud SurrealDB
1038+
let resolved = config.resolved_surrealdb();
1039+
let surreal_client = crate::surreal_client::SurrealClient::new(
1040+
&format!("{}/sql", db_url),
1041+
&resolved.namespace,
1042+
&resolved.database,
1043+
"root",
1044+
"root",
1045+
);
1046+
1047+
let schema = config.resolved_schema();
1048+
let config_dir = config_path.parent().unwrap_or(std::path::Path::new("."));
1049+
let migrations_dir = config_dir.join(&schema.migrations);
1050+
1051+
if migrations_dir.exists() {
1052+
match crate::migrate::apply(&surreal_client, &migrations_dir) {
1053+
Ok(()) => println!(" ▸ Migrations complete."),
1054+
Err(e) => println!(" ▸ Migration warning: {}", e),
1055+
}
1056+
} else {
1057+
println!(" ▸ No migrations directory found, skipping.");
1058+
}
1059+
}
1060+
}
1061+
}
1062+
1063+
// Phase 2: Finalize deployment (triggers app VM provisioning)
1064+
println!(" ▸ Deploying applications...");
1065+
client.post(
1066+
&format!("/v1/projects/{}/deploy/finalize", pid),
1067+
&serde_json::json!({}),
1068+
)?;
1069+
1070+
// Stream events until fully running
1071+
let phase2_status = stream_deployment_events(&client, &pid)?;
1072+
match phase2_status.as_str() {
1073+
"running" => {
1074+
println!();
1075+
println!(" Deployment is running!");
1076+
if let Ok(status_resp) = client.get(&format!("/v1/projects/{}/deployment", pid)) {
1077+
if let Ok(status) = status_resp.into_json::<serde_json::Value>() {
1078+
print_deployment_details(&status);
1079+
}
1080+
}
1081+
}
1082+
"failed" => bail!("Deployment failed."),
1083+
_ => bail!("Deployment ended unexpectedly (status: {})", phase2_status),
1084+
}
1085+
}
1086+
"running" => {
1087+
// No migration phase (legacy or no infra VMs)
1088+
println!();
1089+
println!(" Deployment is running!");
1090+
if let Ok(status_resp) = client.get(&format!("/v1/projects/{}/deployment", pid)) {
1091+
if let Ok(status) = status_resp.into_json::<serde_json::Value>() {
1092+
print_deployment_details(&status);
1093+
}
1094+
}
1095+
}
1096+
"failed" => bail!("Deployment failed."),
1097+
_ => bail!("Deployment ended unexpectedly (status: {})", phase1_status),
1098+
}
1099+
1100+
Ok(())
1101+
}
1102+
1103+
/// Stream SSE deployment events and return the final status when the stream closes.
1104+
fn stream_deployment_events(client: &CloudClient, pid: &str) -> Result<String> {
10261105
let events_url = format!(
10271106
"{}/v1/projects/{}/deployment/events",
10281107
client.base_url, pid
@@ -1038,7 +1117,6 @@ fn deploy() -> Result<()> {
10381117
use std::io::BufRead;
10391118

10401119
let mut final_status = String::new();
1041-
let mut final_error = String::new();
10421120

10431121
for line in reader.lines() {
10441122
let line = match line {
@@ -1072,87 +1150,27 @@ fn deploy() -> Result<()> {
10721150
"deployment" => {
10731151
let status = event["status"].as_str().unwrap_or("unknown");
10741152
final_status = status.to_string();
1075-
if let Some(err) = event["error"].as_str() {
1076-
if !err.is_empty() {
1077-
final_error = err.to_string();
1078-
}
1079-
}
10801153
match status {
1081-
"provisioning" => {
1082-
println!(" ▸ Provisioning VMs...");
1083-
}
1084-
"running" | "failed" | "destroyed" => {
1085-
// Stream will close, handled below
1086-
}
1087-
_ => {
1088-
println!(" ▸ {}", status);
1089-
}
1154+
"provisioning" => println!(" ▸ Provisioning VMs..."),
1155+
"deploying_apps" => println!(" ▸ Deploying applications..."),
1156+
"migrating" | "running" | "failed" | "destroyed" => {}
1157+
_ => println!(" ▸ {}", status),
10901158
}
10911159
}
10921160
_ => {}
10931161
}
10941162
}
10951163

1096-
// Stream ended — check final state
1097-
match final_status.as_str() {
1098-
"running" => {
1099-
println!();
1100-
println!(" Deployment is running!");
1101-
// Fetch final details
1102-
if let Ok(status_resp) = client.get(&format!("/v1/projects/{}/deployment", pid)) {
1103-
if let Ok(status) = status_resp.into_json::<serde_json::Value>() {
1104-
print_deployment_details(&status);
1105-
}
1106-
}
1107-
}
1108-
"failed" => {
1109-
bail!("Deployment failed: {}", if final_error.is_empty() { "unknown error" } else { &final_error });
1110-
}
1111-
"destroyed" => {
1112-
bail!("Deployment was destroyed.");
1113-
}
1114-
_ => {
1115-
bail!("Deployment stream ended unexpectedly (status: {})", final_status);
1116-
}
1117-
}
1164+
Ok(final_status)
11181165
}
1119-
Err(_) => {
1120-
// Fallback: poll for status (server may not support SSE yet)
1121-
loop {
1122-
thread::sleep(Duration::from_secs(2));
1123-
1124-
let status_resp = client.get(&format!("/v1/projects/{}/deployment", pid))?;
1125-
let status: serde_json::Value =
1126-
status_resp.into_json().context("Failed to parse status")?;
1127-
1128-
let dep_status = status["deployment"]["status"]
1129-
.as_str()
1130-
.unwrap_or("unknown");
1131-
1132-
match dep_status {
1133-
"running" => {
1134-
println!(" Deployment is running!");
1135-
print_deployment_details(&status);
1136-
return Ok(());
1137-
}
1138-
"failed" => {
1139-
let error = status["deployment"]["error"]
1140-
.as_str()
1141-
.unwrap_or("unknown error");
1142-
bail!("Deployment failed: {}", error);
1143-
}
1144-
"destroyed" => {
1145-
bail!("Deployment was destroyed.");
1146-
}
1147-
_ => {
1148-
print!(" Status: {}...\r", dep_status);
1149-
}
1150-
}
1151-
}
1166+
Err(ureq::Error::Status(code, resp)) => {
1167+
let body = resp.into_string().unwrap_or_default();
1168+
bail!("Failed to stream events (HTTP {}): {}", code, body);
1169+
}
1170+
Err(ureq::Error::Transport(t)) => {
1171+
bail!("Connection error: {}", t);
11521172
}
11531173
}
1154-
1155-
Ok(())
11561174
}
11571175

11581176
fn status() -> Result<()> {

apps/landing-page/src/layouts/DocsLayout.astro

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,15 @@ const activeGroup = nav.find((g: any) =>
2222
<head>
2323
<meta charset="utf-8" />
2424
<meta name="viewport" content="width=device-width" />
25-
<title>{title} | ZeroIndex</title>
25+
<meta property="og:type" content="article" />
26+
<meta property="og:title" content={`${title} — sp00ky Docs`} />
27+
<meta property="og:description" content="sp00ky documentation — The Reactive, Local-First Framework for SurrealDB" />
28+
<meta property="og:image" content={new URL('/social-card.png', Astro.site)} />
29+
<meta property="twitter:card" content="summary_large_image" />
30+
<meta property="twitter:title" content={`${title} — sp00ky Docs`} />
31+
<meta property="twitter:description" content="sp00ky documentation — The Reactive, Local-First Framework for SurrealDB" />
32+
<meta property="twitter:image" content={new URL('/social-card.png', Astro.site)} />
33+
<title>{title} — sp00ky Docs</title>
2634
<link rel="preconnect" href="https://fonts.googleapis.com" />
2735
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
2836
<link

apps/landing-page/src/pages/pricing.astro

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ import { basePath } from '../config/nav';
1212
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
1313
<meta name="generator" content={Astro.generator} />
1414
<meta name="description" content="sp00ky Pricing - Simple, transparent pricing for every team" />
15+
<meta property="og:type" content="website" />
16+
<meta property="og:url" content={Astro.site + 'pricing'} />
17+
<meta property="og:title" content="Pricing — sp00ky" />
18+
<meta property="og:description" content="Simple, transparent pricing for every team" />
19+
<meta property="og:image" content={new URL('/social-card.png', Astro.site)} />
20+
<meta property="twitter:card" content="summary_large_image" />
21+
<meta property="twitter:title" content="Pricing — sp00ky" />
22+
<meta property="twitter:description" content="Simple, transparent pricing for every team" />
23+
<meta property="twitter:image" content={new URL('/social-card.png', Astro.site)} />
1524
<title>Pricing — sp00ky</title>
1625
</head>
1726

0 commit comments

Comments
 (0)