diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index b1ecf5a..b889be9 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -28,8 +28,9 @@ pub async fn release_run( password: String, with_api: bool, with_mcp: bool, + with_web: bool, ) -> CmdResult<()> { - launcher.release_run(password, with_api, with_mcp).await + launcher.release_run(password, with_api, with_mcp, with_web).await } #[tauri::command] diff --git a/src-tauri/src/launcher.rs b/src-tauri/src/launcher.rs index 794b1ae..1c869ac 100644 --- a/src-tauri/src/launcher.rs +++ b/src-tauri/src/launcher.rs @@ -2496,7 +2496,7 @@ impl Launcher { /// Start a release. Returns once it has started, not when it is done: its output arrives /// in the console panel, which reads `release_console` as it fills. - pub async fn release_run(&self, password: String, with_api: bool, with_mcp: bool) -> Result<(), String> { + pub async fn release_run(&self, password: String, with_api: bool, with_mcp: bool, with_web: bool) -> Result<(), String> { // Two at once would interleave into one buffer and fight over the same build dirs. if self.release_console.lock().is_ok_and(|c| c.is_running()) { return Err("A release is already running: wait for it to finish.".to_string()); @@ -2533,6 +2533,7 @@ impl Launcher { launcher_next.as_deref(), with_api && plan.docker, with_mcp && plan.docker, + with_web && plan.docker, &password, &self.release_console, ) diff --git a/src-tauri/src/release.rs b/src-tauri/src/release.rs index 4612dd3..2ae9369 100644 --- a/src-tauri/src/release.rs +++ b/src-tauri/src/release.rs @@ -384,6 +384,7 @@ pub fn run_release( launcher_version: Option<&str>, with_api: bool, with_mcp: bool, + with_web: bool, sudo: &str, console: &Shared, ) -> Result { @@ -430,6 +431,19 @@ pub fn run_release( )); } + if with_web { + // From _WEB in the Engine checkout. Its Dockerfile runs npm inside the image, so this + // needs Docker and nothing else - no Node, no node_modules on this PC. + body.push_str(&format!( + "Write-Host '=== ODIAN WEB ===' -ForegroundColor Cyan + & '{}' + if ($LASTEXITCODE -eq 2) {{ Write-Host 'web: already serving this commit' -ForegroundColor Yellow }} + elseif ($LASTEXITCODE -ne 0) {{ throw 'the web step failed' }} +", + scripts.join("deploy_web.ps1").display() + )); + } + if with_mcp { // LAST, always. The MCP serves /download/* and proxies /dhp, so rolling it interrupts // the very road the steps above publish over; anything still in flight would fail. diff --git a/src/components/ReleasePanel.svelte b/src/components/ReleasePanel.svelte index 019fcf8..aef485b 100644 --- a/src/components/ReleasePanel.svelte +++ b/src/components/ReleasePanel.svelte @@ -16,9 +16,11 @@ // Off by default, deliberately: it serves /download/* and proxies /dhp, so it is the one // step that interrupts the road everything else publishes over. let withMcp = $state(false); + // The browser client at web.odian.fr. Built from _WEB in the Engine checkout, in Docker. + let withWeb = $state(false); async function release() { - await launcher.releaseRun(password, withApi, withMcp); + await launcher.releaseRun(password, withApi, withMcp, withWeb); password = ""; // held for the one run, never kept } @@ -194,6 +196,13 @@ — every operator is logged out +