#Requires -Version 5.1 [CmdletBinding()] param([string]$OutputDirectory,[ValidatePattern('^\d+\.\d+\.\d+$')][string]$Version='0.0.4') Set-StrictMode -Version Latest $ErrorActionPreference='Stop' if (-not $OutputDirectory) { $OutputDirectory=Join-Path $PSScriptRoot 'dist' } Add-Type -AssemblyName System.IO.Compression Add-Type -AssemblyName System.IO.Compression.FileSystem $output=[IO.Path]::GetFullPath($OutputDirectory) [IO.Directory]::CreateDirectory($output) | Out-Null $zipPath=Join-Path $output ("ms-private-$Version.zip") if (Test-Path -LiteralPath $zipPath) {throw 'Archive already exists. Choose an empty output directory to avoid overwriting a release.'} $root=[IO.Path]::GetFullPath($PSScriptRoot) # Explicit source folders: never include local reports, research archives or dependencies. $files=@(Get-ChildItem -LiteralPath $root -File | Where-Object { $_.Extension -in @('.ps1','.md') -or $_.Name -in @('.gitignore','.gitattributes') }) foreach ($folder in @('src','config','tests','docs','.gitea','ame','native')) { $files+=@(Get-ChildItem -LiteralPath (Join-Path $root $folder) -Recurse -File -Force | Where-Object { $_.FullName -notmatch '[\\/](bin|obj)[\\/]' }) } $zip=[IO.Compression.ZipFile]::Open($zipPath,[IO.Compression.ZipArchiveMode]::Create) try { foreach ($file in @($files | Sort-Object FullName)) { if (-not $file.FullName.StartsWith($root+'\',[StringComparison]::OrdinalIgnoreCase) -or ($file.Attributes -band [IO.FileAttributes]::ReparsePoint)) {throw 'Unsafe release input.'} $relative=$file.FullName.Substring($root.Length+1).Replace('\','/') [IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zip,$file.FullName,('ms-private/'+$relative),[IO.Compression.CompressionLevel]::Optimal) | Out-Null } } finally {$zip.Dispose()} $hash=(Get-FileHash -LiteralPath $zipPath -Algorithm SHA256).Hash.ToLowerInvariant() [IO.File]::WriteAllText((Join-Path $output 'SHA256SUMS.txt'),($hash+' '+[IO.Path]::GetFileName($zipPath)+[Environment]::NewLine),[Text.UTF8Encoding]::new($false)) Write-Output "Created $zipPath ($($files.Count) source files). SHA256: $hash"