feat(dev): add Overmind-based development workflow

Add Procfile.dev for parallel backend/frontend development with
Overmind, replacing the sequential build approach. The new `just dev`
recipe starts both servers simultaneously with log multiplexing.

Changes:
- Update `just dev` to use Overmind
- Add `build-demo` recipe with optional Windows cross-compilation
- Add `smoke` recipe to verify development setup
- Improve logging in backend with bind address and dev mode indicator
- Allow missing Windows executable in debug builds
This commit is contained in:
2025-12-11 18:19:48 -06:00
parent 4a191a59f4
commit f86a2db161
4 changed files with 102 additions and 7 deletions

1
.gitignore vendored
View File

@@ -3,3 +3,4 @@
demo-*
/public
.env
.overmind.sock

View File

@@ -45,20 +45,63 @@ frontend-build:
@echo "Building frontend..."
pnpm --dir frontend build
# Development server with hot reload (backend + ensures frontend is built)
dev: frontend-build
@echo "Starting backend development server with bacon..."
@echo "Frontend is served from ./public (built from frontend/)"
bacon run
# Build demo executables (debug mode for faster dev builds)
build-demo:
#!/usr/bin/env bash
set -euo pipefail
echo "Building demo executables..."
# Always build Linux demo
echo "Building Linux demo..."
cargo build --bin demo
cp target/debug/demo ./demo-linux
echo " [OK] Linux demo built"
# Try to build Windows demo if cross-compilation is available
if rustup target list --installed | grep -q x86_64-pc-windows-gnu; then
echo "Building Windows demo..."
if cargo build --bin demo --target x86_64-pc-windows-gnu 2>/dev/null; then
cp target/x86_64-pc-windows-gnu/debug/demo.exe ./demo.exe
echo " [OK] Windows demo built"
else
echo " [!] Windows build failed (mingw-w64 toolchain may not be installed)"
echo " Continuing without Windows demo..."
fi
else
echo " [SKIP] Windows target not installed"
echo " Install with: rustup target add x86_64-pc-windows-gnu"
echo " Also requires: sudo apt install mingw-w64"
fi
echo "Demo executables ready!"
# Development server with hot reload (backend + frontend using Overmind)
dev: build-demo
@echo "Starting development servers with Overmind..."
@echo ""
@echo "Backend will run on: http://localhost:5800"
@echo "Frontend will run on: http://localhost:4321"
@echo ""
@echo "Overmind multiplexes logs with prefixes:"
@echo " [backend] - Bacon watching Rust backend"
@echo " [frontend] - Astro dev server"
@echo ""
@echo "Overmind shortcuts:"
@echo " Ctrl+C - Stop all processes"
@echo " 'overmind connect <process>' - Attach to a specific process"
@echo ""
overmind start -f Procfile.dev
# Watch backend only (for when frontend is already built)
dev-backend:
dev-backend: build-demo
@echo "Starting backend watch with bacon..."
bacon run
# Watch and serve frontend only
dev-frontend:
@echo "Starting frontend dev server..."
@echo "Make sure the backend is running on port 5800!"
pnpm --dir frontend dev
# Simple development run (no hot reload)
@@ -119,3 +162,30 @@ quick: format
@echo "Running quick clippy check..."
cargo clippy --workspace --all-targets --all-features -- -D warnings
@echo "Quick check completed!"
# Verify dev setup is ready (builds demo executables and checks dependencies)
smoke: build-demo
@echo "Verifying development setup..."
@echo ""
@echo "Checking for overmind (required for 'just dev')..."
@command -v overmind >/dev/null 2>&1 || { echo " [!] overmind not found. Install from: https://github.com/DarthSim/overmind#installation"; exit 1; }
@echo " [OK] overmind found"
@echo ""
@echo "Checking for bacon..."
@command -v bacon >/dev/null 2>&1 || { echo " [!] bacon not found. Install with: cargo install bacon"; exit 1; }
@echo " [OK] bacon found"
@echo ""
@echo "Checking for pnpm..."
@command -v pnpm >/dev/null 2>&1 || { echo " [!] pnpm not found. Install from: https://pnpm.io/installation"; exit 1; }
@echo " [OK] pnpm found"
@echo ""
@echo "Checking demo executables..."
@test -f ./demo-linux || { echo " [!] demo-linux not found"; exit 1; }
@echo " [OK] demo-linux exists"
@if [ -f ./demo.exe ]; then \
echo " [OK] demo.exe exists"; \
else \
echo " [SKIP] demo.exe not found (Windows builds not available)"; \
fi
@echo ""
@echo "[OK] Development setup is ready! Run 'just dev' to start."

5
Procfile.dev Normal file
View File

@@ -0,0 +1,5 @@
# Procfile for Overmind development workflow
# Start with: overmind start -f Procfile.dev
backend: PORT=5800 bacon run --headless
frontend: pnpm --dir frontend dev

View File

@@ -66,6 +66,16 @@ async fn main() {
// ("MacOS", "./demo-macos"),
] {
if let Err(e) = store.add_executable(exe_type, exe_path) {
// In debug mode, allow missing Windows executable for dev convenience
if cfg!(debug_assertions) && exe_type == "Windows" {
tracing::warn!(
"Windows executable not found at {} (skipping - cross-compilation not set up)",
exe_path
);
tracing::warn!("To enable Windows builds: rustup target add x86_64-pc-windows-gnu && sudo apt install mingw-w64");
continue;
}
tracing::error!("{}", e);
std::process::exit(1);
}
@@ -105,6 +115,15 @@ async fn main() {
let service = Service::new(router).hoop(cors).hoop(Logger::new());
let acceptor = TcpListener::new(config.bind_addr()).bind().await;
let bind_addr = config.bind_addr();
tracing::info!("Server starting on http://{}", bind_addr);
tracing::info!("WebSocket endpoint: ws://{}/ws", bind_addr);
if cfg!(debug_assertions) {
tracing::info!("Development mode - CORS allows all origins");
tracing::info!("Access the app at http://localhost:4321 (Astro dev server)");
}
let acceptor = TcpListener::new(&bind_addr).bind().await;
Server::new(acceptor).serve(service).await;
}