Package.ps1 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. param(
  2. [Parameter(Mandatory = $true)][string]$OutputDirectory,
  3. [string]$BinaryDirectory = '',
  4. [switch]$SourceOnly
  5. )
  6. $ErrorActionPreference = 'Stop'
  7. Add-Type -AssemblyName System.IO.Compression, System.IO.Compression.FileSystem
  8. $repo = Split-Path -Parent $PSScriptRoot
  9. if (-not $BinaryDirectory) { $BinaryDirectory = Join-Path $repo 'artifacts\PCL-Communist-2.99.0.0' }
  10. New-Item -ItemType Directory -Path $OutputDirectory -Force | Out-Null
  11. $excludedDirectories = @('.git', '.local', 'bin', 'obj', 'artifacts', '.vs', '.idea', '__pycache__')
  12. function Add-PackageDirectory([IO.Compression.ZipArchive]$Archive, [string]$Directory, [string]$Prefix, [bool]$Source) {
  13. foreach ($item in Get-ChildItem -LiteralPath $Directory -Force) {
  14. if ($item.PSIsContainer) {
  15. if ($excludedDirectories -contains $item.Name) { continue }
  16. Add-PackageDirectory $Archive $item.FullName ($Prefix + $item.Name + '/') $Source
  17. } else {
  18. if ($item.Name -in @('.git', 'build-credentials.json', 'decompiled.cs') -or
  19. $item.Name -like '.env*' -or $item.Extension -in @('.pfx', '.pem', '.key', '.snk', '.user', '.suo')) { continue }
  20. if ($Source -and $Directory -eq $repo -and $item.Extension -eq '.zip') { continue }
  21. [void][IO.Compression.ZipFileExtensions]::CreateEntryFromFile($Archive, $item.FullName, $Prefix + $item.Name, [IO.Compression.CompressionLevel]::Optimal)
  22. }
  23. }
  24. }
  25. function New-ProjectZip([string]$Path, [string]$Directory, [string]$Prefix, [bool]$Source) {
  26. $stream = [IO.File]::Open($Path, [IO.FileMode]::Create, [IO.FileAccess]::Write)
  27. try {
  28. $archive = New-Object IO.Compression.ZipArchive($stream, [IO.Compression.ZipArchiveMode]::Create, $true)
  29. try { Add-PackageDirectory $archive $Directory $Prefix $Source }
  30. finally { $archive.Dispose() }
  31. } finally { $stream.Dispose() }
  32. }
  33. $binaryZip = Join-Path $OutputDirectory 'PCL-Communist-2.99.0.0.zip'
  34. $sourceZip = Join-Path $OutputDirectory 'PCL-Communist-2.99.0.0-source.zip'
  35. if (-not $SourceOnly) { New-ProjectZip $binaryZip $BinaryDirectory 'PCL-Communist-2.99.0.0/' $false }
  36. New-ProjectZip $sourceZip $repo 'PCL-Communist-source/' $true
  37. $sourceArchive = [IO.Compression.ZipFile]::OpenRead($sourceZip)
  38. try {
  39. if ($sourceArchive.Entries.FullName -match '(^|/)(\.git|\.local|bin|obj|artifacts)(/|$)' -or
  40. $sourceArchive.Entries.FullName -match '(build-credentials\.json|decompiled\.cs)$') {
  41. throw 'Unexpected private or generated file in source package.'
  42. }
  43. if (-not ($sourceArchive.Entries.FullName -contains 'PCL-Communist-source/MeloongCore/Shared/MeloongCore.csproj')) {
  44. throw 'Source package is missing the pinned MeloongCore source.'
  45. }
  46. Write-Output "Source package: $($sourceArchive.Entries.Count) files; private and generated directories excluded."
  47. } finally { $sourceArchive.Dispose() }
  48. $packagePaths = @($sourceZip)
  49. if (-not $SourceOnly) { $packagePaths = @($binaryZip, $sourceZip) }
  50. $hashes = $packagePaths | ForEach-Object { Get-FileHash -LiteralPath $_ -Algorithm SHA256 }
  51. if (-not $SourceOnly) {
  52. $hashLines = $hashes | ForEach-Object { "$($_.Hash.ToLowerInvariant()) $([IO.Path]::GetFileName($_.Path))" }
  53. [IO.File]::WriteAllLines((Join-Path $OutputDirectory 'PCL-Communist-2.99.0.0.sha256'), [string[]]$hashLines, (New-Object Text.UTF8Encoding($false)))
  54. }
  55. $hashes