Skip to content

Commit baf29d8

Browse files
committed
Improve installer startup feedback and add upgrade command
1 parent d6b7f97 commit baf29d8

4 files changed

Lines changed: 146 additions & 11 deletions

File tree

executor/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ Common binary commands:
7979

8080
```bash
8181
executor doctor
82+
executor upgrade
8283
executor down
8384
executor up
8485
executor web

executor/executor.ts

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ function printHelp(): void {
3535
3636
Usage:
3737
executor doctor [--verbose]
38+
executor upgrade [--version <version>]
3839
executor up [backend-args]
3940
executor down
4041
executor backend <args>
@@ -43,6 +44,7 @@ Usage:
4344
4445
Commands:
4546
doctor Show install health and quick status
47+
upgrade Re-run installer to update executor
4648
up Run managed backend and auto-bootstrap Convex functions
4749
down Stop background backend/web services started by installer
4850
backend Pass through arguments to managed convex-local-backend binary
@@ -488,6 +490,96 @@ Options:
488490
return 0;
489491
}
490492

493+
async function runUpgrade(args: string[]): Promise<number> {
494+
let requestedVersion: string | undefined;
495+
let noModifyPath = false;
496+
let noStarPrompt = false;
497+
let index = 0;
498+
499+
while (index < args.length) {
500+
const arg = args[index];
501+
502+
if (arg === "-h" || arg === "--help") {
503+
console.log(`Usage:
504+
executor upgrade [--version <version>] [--no-modify-path] [--no-star-prompt]
505+
506+
Aliases:
507+
executor update
508+
509+
Options:
510+
-v, --version <version> Install specific release version
511+
--no-modify-path Do not modify shell PATH entries
512+
--no-star-prompt Do not print GitHub star prompt
513+
-h, --help Show this help`);
514+
return 0;
515+
}
516+
517+
if (arg === "-v" || arg === "--version") {
518+
const value = args[index + 1];
519+
if (!value || value.startsWith("-")) {
520+
console.log("Missing value for --version");
521+
return 1;
522+
}
523+
requestedVersion = value;
524+
index += 2;
525+
continue;
526+
}
527+
528+
if (arg === "--no-modify-path") {
529+
noModifyPath = true;
530+
index += 1;
531+
continue;
532+
}
533+
534+
if (arg === "--no-star-prompt") {
535+
noStarPrompt = true;
536+
index += 1;
537+
continue;
538+
}
539+
540+
console.log(`Unknown option: ${arg}`);
541+
return 1;
542+
}
543+
544+
const installUrl = Bun.env.EXECUTOR_INSTALL_URL ?? "https://executor.sh/install";
545+
console.log(`[executor] upgrading via ${installUrl}`);
546+
547+
const response = await fetch(installUrl);
548+
if (!response.ok) {
549+
throw new Error(`Failed to download installer: ${response.status} ${response.statusText}`);
550+
}
551+
552+
const script = await response.text();
553+
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "executor-upgrade-"));
554+
const scriptPath = path.join(tempDir, "install.sh");
555+
556+
try {
557+
await fs.writeFile(scriptPath, script, "utf8");
558+
await fs.chmod(scriptPath, 0o755);
559+
560+
const installerArgs: string[] = [];
561+
if (requestedVersion) {
562+
installerArgs.push("--version", requestedVersion);
563+
}
564+
if (noModifyPath) {
565+
installerArgs.push("--no-modify-path");
566+
}
567+
if (noStarPrompt) {
568+
installerArgs.push("--no-star-prompt");
569+
}
570+
571+
const proc = Bun.spawn(["bash", scriptPath, ...installerArgs], {
572+
env: process.env,
573+
stdin: "inherit",
574+
stdout: "inherit",
575+
stderr: "inherit",
576+
});
577+
return await proc.exited;
578+
} finally {
579+
await fs.rm(tempDir, { recursive: true, force: true });
580+
}
581+
}
582+
491583
async function run(): Promise<void> {
492584
const [command, ...rest] = process.argv.slice(2);
493585

@@ -501,6 +593,11 @@ async function run(): Promise<void> {
501593
process.exit(exitCode);
502594
}
503595

596+
if (command === "upgrade" || command === "update") {
597+
const exitCode = await runUpgrade(rest);
598+
process.exit(exitCode);
599+
}
600+
504601
if (command === "down" || command === "stop") {
505602
const exitCode = await runDown(rest);
506603
process.exit(exitCode);

executor/install

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -303,8 +303,7 @@ start_background_services() {
303303
if wait_for_http "http://127.0.0.1:${BACKEND_PORT}/version"; then
304304
echo -e "${MUTED}Started managed backend${NC} http://127.0.0.1:${BACKEND_PORT}"
305305
else
306-
echo -e "${RED}Managed backend did not become ready automatically.${NC}"
307-
echo " Check logs: $LOG_DIR/backend.log"
306+
echo -e "${MUTED}Managed backend is still initializing${NC} (continuing readiness checks)"
308307
fi
309308
fi
310309

@@ -318,29 +317,65 @@ start_background_services() {
318317
if wait_for_http "http://127.0.0.1:${WEB_PORT}/"; then
319318
echo -e "${MUTED}Started web UI${NC} http://127.0.0.1:${WEB_PORT}"
320319
else
321-
echo -e "${RED}Web UI did not become ready automatically.${NC}"
322-
echo " Check logs: $LOG_DIR/web.log"
320+
echo -e "${MUTED}Web UI is still initializing${NC} (continuing readiness checks)"
323321
fi
324322
fi
325323
}
326324

327325
wait_for_executor_ready() {
328-
local max_seconds="${1:-120}"
329-
local started
326+
local max_seconds="${1:-90}"
327+
local started now elapsed
328+
local doctor_interval=5
329+
local last_doctor_at=0
330+
local backend_up=0
331+
local web_up=0
332+
local doctor_ok=1
333+
330334
started="$(date +%s)"
335+
echo -e "${MUTED}Waiting for services to become healthy (up to ${max_seconds}s)${NC}"
331336

332337
while true; do
333-
if "$INSTALL_DIR/$APP" doctor >/dev/null 2>&1; then
334-
echo -e "${MUTED}Executor services healthy${NC}"
335-
return 0
338+
if wait_for_http "http://127.0.0.1:${BACKEND_PORT}/version" 1; then
339+
backend_up=1
340+
fi
341+
if wait_for_http "http://127.0.0.1:${WEB_PORT}/" 1; then
342+
web_up=1
336343
fi
337344

338-
local now
339345
now="$(date +%s)"
340-
if (( now - started >= max_seconds )); then
346+
elapsed=$((now - started))
347+
348+
if (( backend_up == 1 && web_up == 1 )); then
349+
if (( now - last_doctor_at >= doctor_interval )); then
350+
if "$INSTALL_DIR/$APP" doctor >/dev/null 2>&1; then
351+
echo -e "${MUTED}Executor services healthy${NC}"
352+
return 0
353+
fi
354+
last_doctor_at=$now
355+
fi
356+
doctor_ok=0
357+
fi
358+
359+
if (( elapsed >= max_seconds )); then
341360
break
342361
fi
343362

363+
if (( elapsed > 0 && elapsed % 5 == 0 )); then
364+
if (( backend_up == 0 || web_up == 0 )); then
365+
local backend_state="starting"
366+
local web_state="starting"
367+
if (( backend_up == 1 )); then
368+
backend_state="running"
369+
fi
370+
if (( web_up == 1 )); then
371+
web_state="running"
372+
fi
373+
echo -e "${MUTED}Still starting... backend=${backend_state} web=${web_state}${NC}"
374+
elif (( doctor_ok == 0 )); then
375+
echo -e "${MUTED}Services up; waiting for Convex functions bootstrap...${NC}"
376+
fi
377+
fi
378+
344379
sleep 0.5
345380
done
346381

@@ -384,6 +419,7 @@ fi
384419
echo "Dashboard: http://localhost:${WEB_PORT}"
385420
echo "Use:"
386421
echo " executor doctor # friendly health check"
422+
echo " executor upgrade # update to latest release"
387423
echo " executor down # stop background services"
388424
echo " executor up # start backend manually"
389425
echo " executor web # start web manually"

executor/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"iac:diff": "bun run --cwd infra diff",
2020
"iac:remove": "bun run --cwd infra remove",
2121
"up": "bun run executor.ts up",
22+
"upgrade": "bun run executor.ts upgrade",
2223
"down": "bun run executor.ts down",
2324
"backend": "bun run executor.ts backend",
2425
"convex": "bun run executor.ts backend",

0 commit comments

Comments
 (0)