# Starts the whole app: game server, Vite client and the Aspire dashboard. # Skips MSBuild when AppHost and Server dlls are newer than C# / csproj / props. # .\run-aspire.ps1 # .\run-aspire.ps1 --launch-profile http # .\run-aspire.ps1 --rebuild # .\run-aspire.ps1 --no-tailscale Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $PSNativeCommandUseErrorActionPreference = $false Set-Location -LiteralPath $PSScriptRoot function Write-Log([string] $Message) { Write-Host "[run-aspire] $Message" } function Write-TailscaleSkipped([string] $Why) { Write-Log "WARNING: $Why" Write-Host ' Friends cannot reach the client over the tailnet.' Write-Host ' Continuing with local access only (http://localhost:5173).' } $configuration = 'Debug' $rebuild = $false $tailscaleServe = $true $dotnetArgs = @() $expectConfiguration = $false foreach ($arg in $args) { if ($expectConfiguration) { $configuration = $arg $expectConfiguration = $false continue } switch ($arg) { '--rebuild' { $rebuild = $true } '--no-tailscale' { $tailscaleServe = $false } { $_ -in '-c', '--configuration' } { $expectConfiguration = $true } default { $dotnetArgs += $arg } } } if ($expectConfiguration) { Write-Log 'missing value for -c / --configuration.' exit 1 } if (-not (Get-Command dotnet -ErrorAction SilentlyContinue)) { Write-Log 'dotnet SDK not found in PATH.' Write-Host ' Install .NET 10: https://dotnet.microsoft.com/download' exit 1 } if (-not (Get-Command node -ErrorAction SilentlyContinue)) { Write-Log 'Node.js not found in PATH - the client resource will fail to start.' Write-Host ' Install Node 22.12 or newer: https://nodejs.org' Write-Host '' } if ($rebuild) { Write-Log '--rebuild: building.' $needBuild = $true } else { $stamp = Join-Path $PSScriptRoot 'tools\apphost-uptodate.ps1' & powershell.exe -NoProfile -ExecutionPolicy Bypass -File $stamp -RepoRoot $PSScriptRoot -Configuration $configuration if ($LASTEXITCODE -eq 0) { Write-Log 'binaries are up to date, skipping build.' $needBuild = $false } else { Write-Log 'sources changed or binaries missing, building.' $needBuild = $true } } if ($needBuild) { Write-Host '' & dotnet build (Join-Path $PSScriptRoot 'src\HSchool.AppHost\HSchool.AppHost.csproj') -c $configuration if ($LASTEXITCODE -ne 0) { Write-Host '' Write-Log 'build failed.' exit $LASTEXITCODE } Write-Host '' } $clientTailscaleUrl = $null if ($tailscaleServe) { if (-not (Get-Command tailscale -ErrorAction SilentlyContinue)) { Write-TailscaleSkipped 'tailscale not found in PATH.' } else { & tailscale status 2>$null | Out-Null if ($LASTEXITCODE -ne 0) { Write-TailscaleSkipped 'tailscale is not connected or not running.' } else { Write-Log 'tailscale serve --bg 5173' & tailscale serve --bg 5173 if ($LASTEXITCODE -ne 0) { Write-TailscaleSkipped 'tailscale serve failed.' } else { $line = & tailscale serve status 2>$null | Select-Object -First 1 $token = if ($line) { ($line -split '\s+', 2)[0] } else { $null } if ($token -like 'https://*') { $clientTailscaleUrl = $token } } } } Write-Host '' } Write-Log 'Starting the Aspire AppHost. Press Ctrl+C to shut everything down.' Write-Log 'Client: http://localhost:5173' if ($clientTailscaleUrl) { Write-Log "Client (Tailscale): $clientTailscaleUrl" } Write-Host '' $run = @( '--project', (Join-Path $PSScriptRoot 'src\HSchool.AppHost\HSchool.AppHost.csproj') '--no-build' '--no-restore' ) + $dotnetArgs & dotnet run @run $exitCode = $LASTEXITCODE if ($exitCode -ne 0) { Write-Host '' Write-Log "AppHost exited with code $exitCode." } exit $exitCode