[CmdletBinding()] param( [string]$Version ) $ErrorActionPreference = 'Stop' $repositoryRoot = [System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..')) $projectPath = Join-Path $repositoryRoot 'apps\KronaStaffTerminal\KronaStaffTerminal.csproj' $installerScript = Join-Path $repositoryRoot 'installer\KronaStaffTerminal.nsi' $stagingRoot = Join-Path $repositoryRoot 'artifacts\terminal-release' $publishDirectory = Join-Path $stagingRoot 'publish' $outputDirectory = Join-Path $repositoryRoot 'artifacts' if ([string]::IsNullOrWhiteSpace($Version)) { [xml]$project = Get-Content -LiteralPath $projectPath -Raw $Version = [string]$project.Project.PropertyGroup.Version } if ($Version -notmatch '^\d+\.\d+\.\d+$') { throw "Version must use MAJOR.MINOR.PATCH format." } $expectedStagingPrefix = $repositoryRoot.TrimEnd('\') + '\artifacts\' $resolvedStaging = [System.IO.Path]::GetFullPath($stagingRoot) if (-not $resolvedStaging.StartsWith($expectedStagingPrefix, [StringComparison]::OrdinalIgnoreCase)) { throw "Refusing to clean staging outside repository artifacts." } if (Test-Path -LiteralPath $stagingRoot) { Remove-Item -LiteralPath $stagingRoot -Recurse -Force } New-Item -ItemType Directory -Path $publishDirectory -Force | Out-Null New-Item -ItemType Directory -Path $outputDirectory -Force | Out-Null $serviceProjectPath = Join-Path $repositoryRoot 'apps\KronaStaffService\KronaStaffService.csproj' $publishArguments = @( 'publish', $projectPath, '-c', 'Release', '-r', 'win-x64', '--self-contained', 'true', '-p:Platform=x64', "-p:Version=$Version", "-p:BaseOutputPath=$(Join-Path $stagingRoot 'bin')\", '-o', $publishDirectory ) & dotnet @publishArguments if ($LASTEXITCODE -ne 0) { throw "Terminal publish failed." } $servicePublishArguments = @( 'publish', $serviceProjectPath, '-c', 'Release', '-r', 'win-x64', '--self-contained', 'true', '-p:Platform=x64', "-p:Version=$Version", "-p:BaseOutputPath=$(Join-Path $stagingRoot 'bin-service')\", '-o', $publishDirectory ) & dotnet @servicePublishArguments if ($LASTEXITCODE -ne 0) { throw "Service publish failed." } $nsisCandidates = @( (Join-Path ${env:ProgramFiles(x86)} 'NSIS\makensis.exe'), (Join-Path $env:ProgramFiles 'NSIS\makensis.exe'), (Join-Path ([Environment]::GetFolderPath('LocalApplicationData')) 'Programs\NSIS\makensis.exe') ) $makensis = $nsisCandidates | Where-Object { Test-Path -LiteralPath $_ -PathType Leaf } | Select-Object -First 1 if ($null -eq $makensis) { throw "NSIS 3 is not installed." } $nsisArguments = @( '/INPUTCHARSET', 'UTF8', "/DAPP_VERSION=$Version", "/DPUBLISH_DIR=$publishDirectory", "/DOUTPUT_DIR=$outputDirectory", "/DPROJECT_ROOT=$repositoryRoot", $installerScript ) & $makensis @nsisArguments if ($LASTEXITCODE -ne 0) { throw "Installer compilation failed." } $installerPath = Join-Path $outputDirectory "KronaStaffTerminal-Setup-$Version.exe" $hash = (Get-FileHash -LiteralPath $installerPath -Algorithm SHA256).Hash.ToLowerInvariant() $checksumPath = "$installerPath.sha256" $checksumLine = "$hash $([System.IO.Path]::GetFileName($installerPath))" + [Environment]::NewLine [System.IO.File]::WriteAllText( $checksumPath, $checksumLine, [System.Text.UTF8Encoding]::new($false)) Write-Output $installerPath Write-Output $checksumPath