package infra import ( "fmt" "os/exec" "strings" ) // DeployAppRemote orquesta el deploy continuo de una app a un VPS remoto. // Pasos: verificar SSH → build local → rsync → restart systemd → health check. func DeployAppRemote(conn SSHConn, cfg DeployConfig) error { // 1. Verificar conectividad SSH if err := SSHCheck(conn); err != nil { return fmt.Errorf("deploy_app_remote: ssh check: %w", err) } // 2. Build local (si hay comando de build) if cfg.BuildCmd != "" { cmd := exec.Command("bash", "-c", cfg.BuildCmd) cmd.Dir = cfg.LocalDir out, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("deploy_app_remote: build failed: %s\n%s", err, strings.TrimSpace(string(out))) } } // 3. Subir binario compilado if err := uploadAppFiles(conn, cfg); err != nil { return fmt.Errorf("deploy_app_remote: upload: %w", err) } // 4. Restart systemd service if err := SystemdRestart(conn, cfg.AppName); err != nil { return fmt.Errorf("deploy_app_remote: restart: %w", err) } // 5. Health check (si está configurado) if cfg.HealthPath != "" && cfg.Port > 0 { url := fmt.Sprintf("http://%s:%d%s", conn.Host, cfg.Port, cfg.HealthPath) if err := HealthCheckHTTP(url, 30, 2000); err != nil { return fmt.Errorf("deploy_app_remote: health check: %w", err) } } return nil }