214 lines
6.4 KiB
PowerShell
214 lines
6.4 KiB
PowerShell
#!/usr/bin/env pwsh
|
|
<#
|
|
.SYNOPSIS
|
|
Builds (and optionally tests) all module solutions under src/.
|
|
|
|
.DESCRIPTION
|
|
Discovers all *.sln files under src/ (excluding the root StellaOps.sln)
|
|
and runs dotnet build on each. Pass -Test to also run dotnet test.
|
|
|
|
.PARAMETER Test
|
|
Also run dotnet test on each solution after building.
|
|
|
|
.PARAMETER Configuration
|
|
Build configuration. Defaults to Debug.
|
|
|
|
.EXAMPLE
|
|
.\scripts\build-all-solutions.ps1
|
|
.\scripts\build-all-solutions.ps1 -Test
|
|
.\scripts\build-all-solutions.ps1 -Test -Configuration Release
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[switch]$Test,
|
|
[switch]$StopRepoHostProcesses,
|
|
[ValidateSet('Debug', 'Release')]
|
|
[string]$Configuration = 'Debug'
|
|
)
|
|
|
|
Set-StrictMode -Version Latest
|
|
$ErrorActionPreference = 'Continue'
|
|
|
|
$repoRoot = Split-Path -Parent $PSScriptRoot
|
|
$srcDir = Join-Path $repoRoot 'src'
|
|
|
|
function Get-RepoRelativePath {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Root,
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Path
|
|
)
|
|
|
|
$normalizedRoot = [System.IO.Path]::GetFullPath($Root).TrimEnd('\', '/')
|
|
$normalizedPath = [System.IO.Path]::GetFullPath($Path)
|
|
|
|
if ($normalizedPath.StartsWith($normalizedRoot, [System.StringComparison]::OrdinalIgnoreCase)) {
|
|
return $normalizedPath.Substring($normalizedRoot.Length).TrimStart('\', '/')
|
|
}
|
|
|
|
return $normalizedPath
|
|
}
|
|
|
|
function Test-RepoOwnedText {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Root,
|
|
[AllowNull()]
|
|
[string]$Value
|
|
)
|
|
|
|
if ([string]::IsNullOrWhiteSpace($Value)) {
|
|
return $false
|
|
}
|
|
|
|
$normalizedRoot = [System.IO.Path]::GetFullPath($Root).TrimEnd('\', '/')
|
|
$normalizedValue = $Value.Replace('/', '\')
|
|
|
|
return $normalizedValue.IndexOf($normalizedRoot, [System.StringComparison]::OrdinalIgnoreCase) -ge 0
|
|
}
|
|
|
|
function Test-IsWindowsPlatform {
|
|
return [System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform(
|
|
[System.Runtime.InteropServices.OSPlatform]::Windows)
|
|
}
|
|
|
|
function Stop-RepoHostProcesses {
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Root
|
|
)
|
|
|
|
if (-not (Test-IsWindowsPlatform)) {
|
|
return
|
|
}
|
|
|
|
$candidates = @(Get-CimInstance Win32_Process -Filter "Name = 'dotnet.exe' OR Name LIKE 'StellaOps.%'")
|
|
$staleProcesses = @()
|
|
|
|
foreach ($candidate in $candidates) {
|
|
if ($candidate.ProcessId -eq $PID) {
|
|
continue
|
|
}
|
|
|
|
$executablePath = "$($candidate.ExecutablePath)"
|
|
$commandLine = "$($candidate.CommandLine)"
|
|
$name = "$($candidate.Name)"
|
|
|
|
$repoOwned = (Test-RepoOwnedText -Root $Root -Value $executablePath) -or
|
|
(Test-RepoOwnedText -Root $Root -Value $commandLine)
|
|
if (-not $repoOwned) {
|
|
continue
|
|
}
|
|
|
|
$looksLikeService = $name -like 'StellaOps.*' -or $commandLine -match 'StellaOps\.[A-Za-z0-9_.-]+'
|
|
if (-not $looksLikeService) {
|
|
continue
|
|
}
|
|
|
|
$staleProcesses += [pscustomobject]@{
|
|
ProcessId = $candidate.ProcessId
|
|
Name = $name
|
|
ExecutablePath = $executablePath
|
|
CommandLine = $commandLine
|
|
}
|
|
}
|
|
|
|
$staleProcesses = @($staleProcesses | Sort-Object ProcessId -Unique)
|
|
if ($staleProcesses.Count -eq 0) {
|
|
Write-Host 'No repo-local Stella host processes detected.' -ForegroundColor DarkGray
|
|
return
|
|
}
|
|
|
|
Write-Host "Stopping $($staleProcesses.Count) repo-local Stella host process(es) before build." -ForegroundColor Yellow
|
|
|
|
foreach ($stale in $staleProcesses) {
|
|
$location = if (-not [string]::IsNullOrWhiteSpace($stale.ExecutablePath)) {
|
|
Get-RepoRelativePath -Root $Root -Path $stale.ExecutablePath
|
|
} else {
|
|
$stale.CommandLine
|
|
}
|
|
|
|
Write-Host " - [$($stale.ProcessId)] $($stale.Name) :: $location" -ForegroundColor DarkYellow
|
|
Stop-Process -Id $stale.ProcessId -Force -ErrorAction Stop
|
|
}
|
|
|
|
Start-Sleep -Seconds 1
|
|
$remaining = @($staleProcesses | Where-Object { Get-Process -Id $_.ProcessId -ErrorAction SilentlyContinue })
|
|
if ($remaining.Count -gt 0) {
|
|
$remainingIds = ($remaining | ForEach-Object { $_.ProcessId }) -join ', '
|
|
throw "Failed to stop repo-local Stella host processes: $remainingIds"
|
|
}
|
|
|
|
Write-Host 'Repo-local Stella host processes stopped.' -ForegroundColor Green
|
|
}
|
|
|
|
if ($StopRepoHostProcesses) {
|
|
Stop-RepoHostProcesses -Root $repoRoot
|
|
}
|
|
|
|
$solutions = Get-ChildItem -Path $srcDir -Filter '*.sln' -Recurse |
|
|
Where-Object {
|
|
$_.Name -ne 'StellaOps.sln' -and
|
|
$_.FullName -notmatch '[\\/](node_modules|bin|obj)[\\/]'
|
|
} |
|
|
Sort-Object FullName
|
|
|
|
if ($solutions.Count -eq 0) {
|
|
Write-Error 'No solution files found under src/.'
|
|
exit 1
|
|
}
|
|
|
|
Write-Host "Found $($solutions.Count) solution(s) to build." -ForegroundColor Cyan
|
|
Write-Host ''
|
|
|
|
$buildPass = @()
|
|
$buildFail = @()
|
|
$testPass = @()
|
|
$testFail = @()
|
|
$testSkipped = @()
|
|
|
|
foreach ($sln in $solutions) {
|
|
$rel = Get-RepoRelativePath -Root $repoRoot -Path $sln.FullName
|
|
Write-Host "--- BUILD: $rel ---" -ForegroundColor Yellow
|
|
|
|
dotnet build $sln.FullName --configuration $Configuration --nologo -v quiet
|
|
if ($LASTEXITCODE -eq 0) {
|
|
$buildPass += $rel
|
|
} else {
|
|
$buildFail += $rel
|
|
Write-Host " FAILED" -ForegroundColor Red
|
|
continue # skip test if build failed
|
|
}
|
|
|
|
if ($Test) {
|
|
Write-Host "--- TEST: $rel ---" -ForegroundColor Yellow
|
|
dotnet test $sln.FullName --configuration $Configuration --nologo --no-build -v quiet
|
|
if ($LASTEXITCODE -eq 0) {
|
|
$testPass += $rel
|
|
} else {
|
|
$testFail += $rel
|
|
Write-Host " TEST FAILED" -ForegroundColor Red
|
|
}
|
|
}
|
|
}
|
|
|
|
Write-Host ''
|
|
Write-Host '========== Summary ==========' -ForegroundColor Cyan
|
|
Write-Host "Build passed : $($buildPass.Count)" -ForegroundColor Green
|
|
if ($buildFail.Count -gt 0) {
|
|
Write-Host "Build failed : $($buildFail.Count)" -ForegroundColor Red
|
|
$buildFail | ForEach-Object { Write-Host " - $_" -ForegroundColor Red }
|
|
}
|
|
if ($Test) {
|
|
Write-Host "Test passed : $($testPass.Count)" -ForegroundColor Green
|
|
if ($testFail.Count -gt 0) {
|
|
Write-Host "Test failed : $($testFail.Count)" -ForegroundColor Red
|
|
$testFail | ForEach-Object { Write-Host " - $_" -ForegroundColor Red }
|
|
}
|
|
}
|
|
|
|
if ($buildFail.Count -gt 0 -or $testFail.Count -gt 0) {
|
|
exit 1
|
|
}
|