param( [string]$SourceDir = "", [string]$OutputDir = "", [string]$ZipFile = "", [string]$SdkVersion = "0.1.0", [string]$ExampleConfig = "", [switch]$IncludeDemoMainApp, [switch]$IncludeQtRuntime ) $ErrorActionPreference = "Stop" $RepoRoot = Split-Path -Parent $PSScriptRoot if ([string]::IsNullOrWhiteSpace($SourceDir)) { $SourceDir = Join-Path $RepoRoot "out/bin" } if ([string]::IsNullOrWhiteSpace($OutputDir)) { $OutputDir = Join-Path $RepoRoot "dist/UpdateClientSDK" } if ([string]::IsNullOrWhiteSpace($ZipFile)) { $ZipFile = Join-Path $RepoRoot "dist/UpdateClientSDK.zip" } if ([string]::IsNullOrWhiteSpace($ExampleConfig)) { $ExampleConfig = Join-Path $RepoRoot "config/app_config.example.json" } $source = (Resolve-Path $SourceDir).Path $exampleConfigPath = (Resolve-Path $ExampleConfig).Path $requiredFiles = @("Launcher.exe", "Updater.exe", "Bootstrap.exe") foreach ($name in $requiredFiles) { $path = Join-Path $source $name if (-not (Test-Path $path)) { throw "SDK source directory is missing required file: $path" } } $publicKeyCandidates = @( (Join-Path $source "config/manifest_public_key.pem"), (Join-Path $source "manifest_public_key.pem"), (Join-Path $RepoRoot "config/manifest_public_key.pem") ) $publicKey = $publicKeyCandidates | Where-Object { Test-Path $_ } | Select-Object -First 1 if (-not $publicKey) { throw "manifest_public_key.pem is missing. Prepare the public key that matches the server signing private key." } $debugArtifacts = Get-ChildItem $source -Recurse -File | Where-Object { $_.Name -match '^(Qt5.*d|qwindowsd|libEGLd|libGLESv2d|msvcp.*d|vcruntime.*d)\.dll$' -or $_.Extension -in @('.pdb', '.ilk') } if ($debugArtifacts) { throw "SDK source directory contains Debug artifacts. Use a clean Release output directory. Example: $($debugArtifacts[0].FullName)" } if (Test-Path $OutputDir) { Remove-Item $OutputDir -Recurse -Force } New-Item $OutputDir -ItemType Directory -Force | Out-Null $binDir = Join-Path $OutputDir "bin" $configDir = Join-Path $OutputDir "config" $scriptsDir = Join-Path $OutputDir "scripts" $commonDir = Join-Path $OutputDir "Common" New-Item $binDir,$configDir,$scriptsDir,$commonDir -ItemType Directory -Force | Out-Null $excludedTopLevel = @("config", "update", "update_temp", "manifest_public_key.pem") if (-not $IncludeDemoMainApp) { $excludedTopLevel += "MainApp.exe" } if (-not $IncludeQtRuntime) { $excludedTopLevel += @( "bearer", "iconengines", "imageformats", "platforms", "styles", "translations" ) } function Test-IsQtRuntimeFile { param([System.IO.FileSystemInfo]$Item) if ($IncludeQtRuntime -or $Item.PSIsContainer) { return $false } return ( $Item.Name -match '^Qt5.*\.dll$' -or $Item.Name -in @( "libEGL.dll", "libGLESv2.dll", "opengl32sw.dll", "d3dcompiler_47.dll" ) ) } Get-ChildItem $source -Force | Where-Object { $_.Name -notin $excludedTopLevel -and -not (Test-IsQtRuntimeFile $_) } | Copy-Item -Destination $binDir -Recurse -Force Copy-Item $exampleConfigPath (Join-Path $configDir "app_config.json") -Force Copy-Item $publicKey (Join-Path $configDir "manifest_public_key.pem") -Force $commonSourceDir = Join-Path $RepoRoot "Common" $commonSourceFiles = @( "ConfigHelper.h", "ConfigHelper.cpp", "TicketHelper.h", "TicketHelper.cpp" ) foreach ($commonFile in $commonSourceFiles) { $commonPath = Join-Path $commonSourceDir $commonFile if (-not (Test-Path $commonPath)) { throw "SDK Common integration source is missing: $commonPath" } Copy-Item $commonPath (Join-Path $commonDir $commonFile) -Force } $wordGuideSource = @($RepoRoot, (Join-Path $RepoRoot "Docs")) | Where-Object { Test-Path $_ } | ForEach-Object { Get-ChildItem $_ -File -Filter "*.docx" } | Where-Object { $_.Name -like "*SDK*.docx" -and $_.Name -notlike "~$*" } | Sort-Object Name | Select-Object -First 1 if (-not $wordGuideSource) { throw "SDK integration Word guide is missing. Expected a *SDK*.docx file in the repository root or Docs directory." } Copy-Item $wordGuideSource.FullName (Join-Path $OutputDir $wordGuideSource.Name) -Force Copy-Item (Join-Path $PSScriptRoot "package-client.ps1") (Join-Path $scriptsDir "package-client.ps1") -Force Copy-Item (Join-Path $PSScriptRoot "package-sdk.ps1") (Join-Path $scriptsDir "package-sdk.ps1") -Force Copy-Item (Join-Path $PSScriptRoot "install-sdk.ps1") (Join-Path $scriptsDir "install-sdk.ps1") -Force @{ sdk_version = $SdkVersion generated_at = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") sdk_type = "external-updater-runtime" required_entry = "Launcher.exe" contains_demo_main_app = [bool]$IncludeDemoMainApp integration_sources = $commonSourceFiles } | ConvertTo-Json -Depth 3 | Set-Content (Join-Path $OutputDir "sdk_manifest.json") -Encoding UTF8 $zipParent = Split-Path $ZipFile -Parent New-Item $zipParent -ItemType Directory -Force | Out-Null if (Test-Path $ZipFile) { Remove-Item $ZipFile -Force } Compress-Archive -Path (Join-Path $OutputDir "*") -DestinationPath $ZipFile -CompressionLevel Optimal Write-Host "SDK directory: $OutputDir" Write-Host "SDK zip: $ZipFile" Write-Host "SDK version: $SdkVersion"