param( [string]$Version = "v1.0", [string]$OutputPath = "" ) $ErrorActionPreference = "Stop" if ([string]::IsNullOrWhiteSpace($Version) -or $Version -notmatch '^v[0-9]+(?:\.[0-9]+){1,2}$') { throw "Version must use vMAJOR.MINOR or vMAJOR.MINOR.PATCH format" } $repositoryRoot = Split-Path -Parent $PSScriptRoot if ([string]::IsNullOrWhiteSpace($OutputPath)) { $OutputPath = Join-Path $repositoryRoot "dist/proxy-pool-docs-$Version.zip" } elseif (-not [System.IO.Path]::IsPathRooted($OutputPath)) { $OutputPath = Join-Path $repositoryRoot $OutputPath } $OutputPath = [System.IO.Path]::GetFullPath($OutputPath) if ([System.IO.Path]::GetExtension($OutputPath) -ne ".zip") { throw "OutputPath must end in .zip" } $revision = (& git -C $repositoryRoot rev-parse --verify HEAD 2>$null).Trim() if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($revision)) { throw "could not resolve the current Git revision" } $sources = @( "README.md", "docs", "diagrams", "api/openapi", "api/proto", "deploy/README.md", "deploy/kubernetes/overlays/development-mtls/README.md" ) $stagingRoot = Join-Path ([System.IO.Path]::GetTempPath()) ("proxy-pool-docs-" + [Guid]::NewGuid().ToString("N")) $temporaryArchive = "" try { New-Item -ItemType Directory -Force -Path $stagingRoot | Out-Null foreach ($relative in $sources) { $source = Join-Path $repositoryRoot $relative if (-not (Test-Path -LiteralPath $source)) { throw "documentation source is missing: $relative" } $destination = Join-Path $stagingRoot $relative $destinationParent = Split-Path -Parent $destination New-Item -ItemType Directory -Force -Path $destinationParent | Out-Null Copy-Item -LiteralPath $source -Destination $destination -Recurse -Force } $files = @(Get-ChildItem -LiteralPath $stagingRoot -File -Recurse | Sort-Object FullName) if ($files.Count -eq 0) { throw "documentation package has no files" } $manifestFiles = @( foreach ($file in $files) { [ordered]@{ path = [System.IO.Path]::GetRelativePath($stagingRoot, $file.FullName).Replace("\", "/") sha256 = (Get-FileHash -LiteralPath $file.FullName -Algorithm SHA256).Hash.ToLowerInvariant() bytes = $file.Length } } ) [ordered]@{ package = "proxy-pool-docs" version = $Version revision = $revision generatedAtUtc = [DateTime]::UtcNow.ToString("O") files = $manifestFiles } | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath (Join-Path $stagingRoot "manifest.json") -Encoding utf8 $outputDirectory = Split-Path -Parent $OutputPath New-Item -ItemType Directory -Force -Path $outputDirectory | Out-Null $temporaryArchive = Join-Path $outputDirectory ("." + [System.IO.Path]::GetFileName($OutputPath) + "." + [Guid]::NewGuid().ToString("N") + ".tmp") Add-Type -AssemblyName System.IO.Compression.FileSystem [System.IO.Compression.ZipFile]::CreateFromDirectory( $stagingRoot, $temporaryArchive, [System.IO.Compression.CompressionLevel]::Optimal, $false ) [System.IO.File]::Move($temporaryArchive, $OutputPath, $true) $temporaryArchive = "" Write-Host "documentation package: $OutputPath ($($manifestFiles.Count) files, $revision)" } finally { if (-not [string]::IsNullOrWhiteSpace($temporaryArchive) -and (Test-Path -LiteralPath $temporaryArchive)) { Remove-Item -LiteralPath $temporaryArchive -Force } if (Test-Path -LiteralPath $stagingRoot) { Remove-Item -LiteralPath $stagingRoot -Recurse -Force } }