param( [string]$OutputDir = "dist" ) $ErrorActionPreference = "Stop" $root = (Resolve-Path ".").Path New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null $timestamp = Get-Date -Format "yyyyMMdd-HHmmss" $archivePath = Join-Path $OutputDir "cargoradar-nas-$timestamp.zip" $staging = Join-Path $OutputDir "cargoradar-nas-stage" if (Test-Path $staging) { $resolvedStaging = (Resolve-Path $staging).Path if (-not $resolvedStaging.StartsWith($root)) { throw "Refusing to remove outside the repository: $resolvedStaging" } Remove-Item -LiteralPath $resolvedStaging -Recurse -Force } New-Item -ItemType Directory -Path $staging | Out-Null $stagingPath = (Resolve-Path $staging).Path $items = @( ".dockerignore", ".env.example", ".env.nas.example", "Dockerfile", "docker-compose.yml", "README.md", "apps", "docs", "scripts" ) foreach ($item in $items) { $source = Join-Path $root $item if (-not (Test-Path $source)) { throw "Missing deploy item: $item" } Copy-Item -Path $source -Destination $stagingPath -Recurse -Force } Add-Type -AssemblyName System.IO.Compression Add-Type -AssemblyName System.IO.Compression.FileSystem if (Test-Path $archivePath) { Remove-Item -LiteralPath $archivePath -Force } $zip = [System.IO.Compression.ZipFile]::Open($archivePath, [System.IO.Compression.ZipArchiveMode]::Create) try { $files = Get-ChildItem -Path $stagingPath -Recurse -File -Force foreach ($file in $files) { $relativePath = $file.FullName.Substring($stagingPath.Length) $relativePath = $relativePath -replace "^[\\/]+", "" $entryName = $relativePath -replace "\\", "/" [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile( $zip, $file.FullName, $entryName, [System.IO.Compression.CompressionLevel]::Optimal ) | Out-Null } } finally { $zip.Dispose() } Remove-Item -LiteralPath $stagingPath -Recurse -Force [pscustomobject]@{ Archive = (Resolve-Path $archivePath).Path } | Format-List