155 lines
7.3 KiB
PowerShell
155 lines
7.3 KiB
PowerShell
[CmdletBinding()]
|
|
param()
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
$repoRoot = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..\..'))
|
|
$artifactsRoot = [IO.Path]::GetFullPath((Join-Path $repoRoot 'artifacts'))
|
|
$buildRoot = $null
|
|
$previousRustFlags = $env:RUSTFLAGS
|
|
$env:RUSTFLAGS = '-C target-feature=+crt-static'
|
|
|
|
function Invoke-Checked {
|
|
param(
|
|
[Parameter(Mandatory)]
|
|
[scriptblock]$Command,
|
|
[Parameter(Mandatory)]
|
|
[string]$Description
|
|
)
|
|
|
|
& $Command
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "$Description failed with exit code $LASTEXITCODE"
|
|
}
|
|
}
|
|
|
|
function Assert-ArtifactPath {
|
|
param([Parameter(Mandatory)][string]$Path)
|
|
|
|
$fullPath = [IO.Path]::GetFullPath($Path)
|
|
$prefix = $artifactsRoot.TrimEnd([IO.Path]::DirectorySeparatorChar) + [IO.Path]::DirectorySeparatorChar
|
|
if (-not $fullPath.StartsWith($prefix, [StringComparison]::OrdinalIgnoreCase)) {
|
|
throw "Refusing to modify a path outside $artifactsRoot"
|
|
}
|
|
}
|
|
|
|
Push-Location $repoRoot
|
|
try {
|
|
Invoke-Checked -Description 'Native Rust client release build' -Command {
|
|
& cargo.exe build --release --jobs 2 -p remotedesk-native-gui -p remotedesk-credential-store -p remotedesk-native-video -p remotedesk-rdp-session -p remotedesk-rdp-viewer -p remotedesk-windows-agent-viewer
|
|
}
|
|
|
|
$metadata = (& cargo.exe metadata --no-deps --format-version 1 | ConvertFrom-Json)
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw 'Unable to read Cargo workspace metadata'
|
|
}
|
|
$helperPackage = $metadata.packages | Where-Object name -eq 'remotedesk-native-video'
|
|
if ($null -eq $helperPackage) {
|
|
throw 'remotedesk-native-video is missing from Cargo metadata'
|
|
}
|
|
$version = [string]$helperPackage.version
|
|
if ($version -notmatch '^[0-9A-Za-z.-]+$') {
|
|
throw "Unsafe package version: $version"
|
|
}
|
|
|
|
$hostLine = (& rustc.exe -vV | Select-String '^host: ').Line
|
|
if (-not $hostLine) {
|
|
throw 'Unable to determine the Rust host target'
|
|
}
|
|
$hostTarget = $hostLine.Substring(6).Trim()
|
|
$architecture = if ($hostTarget.StartsWith('x86_64-')) {
|
|
'x64'
|
|
} elseif ($hostTarget.StartsWith('aarch64-')) {
|
|
'arm64'
|
|
} else {
|
|
throw "Unsupported packaging architecture: $hostTarget"
|
|
}
|
|
|
|
$packageName = "RemoteDesk-Portable-M0-$version-windows-$architecture"
|
|
$buildRoot = Join-Path $artifactsRoot ".package-preview-$PID-$([guid]::NewGuid().ToString('N'))"
|
|
$stagingRoot = Join-Path $buildRoot $packageName
|
|
$zipPath = Join-Path $artifactsRoot "$packageName.zip"
|
|
Assert-ArtifactPath $buildRoot
|
|
Assert-ArtifactPath $stagingRoot
|
|
Assert-ArtifactPath $zipPath
|
|
|
|
New-Item -ItemType Directory -Force -Path $artifactsRoot | Out-Null
|
|
if (Test-Path -LiteralPath $zipPath) {
|
|
Remove-Item -LiteralPath $zipPath -Force
|
|
}
|
|
|
|
$binRoot = Join-Path $stagingRoot 'bin'
|
|
$docsRoot = Join-Path $stagingRoot 'docs'
|
|
New-Item -ItemType Directory -Force -Path $binRoot, $docsRoot | Out-Null
|
|
|
|
Copy-Item -LiteralPath (Join-Path $repoRoot 'target\release\remotedesk-native.exe') -Destination (Join-Path $binRoot 'remotedesk.exe')
|
|
Copy-Item -LiteralPath (Join-Path $repoRoot 'target\release\remotedesk-credential-store.exe') -Destination $binRoot
|
|
Copy-Item -LiteralPath (Join-Path $repoRoot 'target\release\remotedesk-native-video.exe') -Destination $binRoot
|
|
Copy-Item -LiteralPath (Join-Path $repoRoot 'target\release\remotedesk-rdp-session.exe') -Destination $binRoot
|
|
Copy-Item -LiteralPath (Join-Path $repoRoot 'target\release\remotedesk-rdp-viewer.exe') -Destination $binRoot
|
|
Copy-Item -LiteralPath (Join-Path $repoRoot 'target\release\remotedesk-windows-agent-viewer.exe') -Destination $binRoot
|
|
Copy-Item -LiteralPath (Join-Path $repoRoot 'docs\user-guide.md') -Destination $docsRoot
|
|
Copy-Item -LiteralPath (Join-Path $repoRoot 'docs\implementation-status.md') -Destination $docsRoot
|
|
Copy-Item -LiteralPath (Join-Path $repoRoot 'docs\online-updates.md') -Destination $docsRoot
|
|
Copy-Item -LiteralPath (Join-Path $repoRoot 'client\README.md') -Destination $docsRoot
|
|
Copy-Item -LiteralPath (Join-Path $repoRoot 'README.md') -Destination $stagingRoot
|
|
Copy-Item -LiteralPath (Join-Path $repoRoot 'packaging\windows\README-PREVIEW.md') -Destination $stagingRoot
|
|
Copy-Item -LiteralPath (Join-Path $repoRoot 'packaging\windows\Apply-RemoteDesk-Update.ps1') -Destination $stagingRoot
|
|
|
|
$manifest = [ordered]@{
|
|
product = 'RemoteDesk'
|
|
version = $version
|
|
channel = 'm0-preview'
|
|
distribution = 'portable'
|
|
target = $hostTarget
|
|
runnable_ui = 'bin/remotedesk.exe'
|
|
desktop_shell = 'winit-wgpu-egui'
|
|
credential_store = 'bin/remotedesk-credential-store.exe'
|
|
native_helper = 'bin/remotedesk-native-video.exe'
|
|
rdp_probe_helper = 'bin/remotedesk-rdp-session.exe'
|
|
rdp_viewer = 'bin/remotedesk-rdp-viewer.exe'
|
|
windows_agent_viewer = 'bin/remotedesk-windows-agent-viewer.exe'
|
|
update_helper = 'Apply-RemoteDesk-Update.ps1'
|
|
d3d11_probe = 'bin/remotedesk-native-video.exe --probe-d3d11'
|
|
d3d11_rendering = $false
|
|
limitations = @(
|
|
'Portable archive only; no MSI installation or Start menu registration'
|
|
'Native IronRDP uses merged dirty-rect D3D11 CPU texture uploads and swap-chain presentation when available; it is not hardware decode or zero-copy'
|
|
'The RDP protocol probe validates negotiation and TLS certificate identity but stops before NLA authentication'
|
|
'Native IronRDP custom monitor subsets are not available; all-local-monitor mode uses RDPEDISP'
|
|
'Linux graphical desktop, WebRTC, and CDN connector capabilities remain disabled until native builds and end-to-end validation complete'
|
|
'The Linux Agent controlled endpoint is packaged separately'
|
|
)
|
|
}
|
|
$manifest | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath (Join-Path $stagingRoot 'manifest.json') -Encoding utf8
|
|
|
|
$hashLines = Get-ChildItem -LiteralPath $stagingRoot -Recurse -File |
|
|
Sort-Object FullName |
|
|
ForEach-Object {
|
|
$rootUri = [Uri]((Resolve-Path -LiteralPath $stagingRoot).Path.TrimEnd('\') + '\')
|
|
$fileUri = [Uri]((Resolve-Path -LiteralPath $_.FullName).Path)
|
|
$relative = [Uri]::UnescapeDataString($rootUri.MakeRelativeUri($fileUri).ToString()).Replace('\', '/')
|
|
$hash = (Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash.ToLowerInvariant()
|
|
"$hash $relative"
|
|
}
|
|
$hashLines | Set-Content -LiteralPath (Join-Path $stagingRoot 'SHA256SUMS.txt') -Encoding ascii
|
|
|
|
Compress-Archive -LiteralPath $stagingRoot -DestinationPath $zipPath -CompressionLevel Optimal
|
|
$zipHash = (Get-FileHash -LiteralPath $zipPath -Algorithm SHA256).Hash.ToLowerInvariant()
|
|
"$zipHash $([IO.Path]::GetFileName($zipPath))" |
|
|
Set-Content -LiteralPath (Join-Path $artifactsRoot 'SHA256SUMS.txt') -Encoding ascii
|
|
|
|
Write-Output "Package: $zipPath"
|
|
Write-Output "SHA256: $zipHash"
|
|
} finally {
|
|
if ($null -eq $previousRustFlags) {
|
|
Remove-Item Env:RUSTFLAGS -ErrorAction SilentlyContinue
|
|
} else {
|
|
$env:RUSTFLAGS = $previousRustFlags
|
|
}
|
|
if ($buildRoot -and (Test-Path -LiteralPath $buildRoot)) {
|
|
Assert-ArtifactPath $buildRoot
|
|
Remove-Item -LiteralPath $buildRoot -Recurse -Force
|
|
}
|
|
Pop-Location
|
|
}
|