Scripts/Build-FoModuleRelease.ps1

#Requires -Version 5.1
[CmdletBinding()]
param(
    [string]$ModuleRoot = (Split-Path -Parent $PSScriptRoot),
    [string]$OutputDirectory,
    [string]$ManifestPath
)

$ErrorActionPreference = 'Stop'

function Get-FoShipRootNames {
    return @(
        'FileOptimizer.psd1'
        'FileOptimizer.psm1'
        'Public'
        'Private'
        'Pipelines'
        'Scripts'
        'Data'
        'Templates'
        'en-US'
        'README.md'
        'LICENSE'
        'THIRD_PARTY_NOTICES.md'
        'RELEASE_NOTES.md'
        'ReleaseNotes'
    )
}

if (-not $ManifestPath) {
    $ManifestPath = Join-Path $ModuleRoot 'FileOptimizer.psd1'
}

if (-not (Test-Path -LiteralPath $ManifestPath)) {
    throw "Module manifest not found: $ManifestPath"
}

$manifestContent = Get-Content -LiteralPath $ManifestPath -Raw
$manifest = & ([scriptblock]::Create($manifestContent))
$version = [version]$manifest.ModuleVersion

if (-not $OutputDirectory) {
    $OutputDirectory = Join-Path $ModuleRoot 'dist'
}

$moduleFolder = Join-Path (Join-Path $OutputDirectory 'FileOptimizer') $version.ToString()
$zipStagingRoot = Join-Path ([System.IO.Path]::GetTempPath()) ("fo-release-{0}" -f [guid]::NewGuid().ToString('N'))

try {
    if (Test-Path -LiteralPath $moduleFolder) {
        Remove-Item -LiteralPath $moduleFolder -Recurse -Force
    }

    New-Item -ItemType Directory -Path $moduleFolder -Force | Out-Null

    foreach ($name in (Get-FoShipRootNames)) {
        $source = Join-Path $ModuleRoot $name
        if (-not (Test-Path -LiteralPath $source)) {
            throw "Required release path missing: $source"
        }

        $destination = Join-Path $moduleFolder $name
        if (Test-Path -LiteralPath $source -PathType Container) {
            Copy-Item -LiteralPath $source -Destination $destination -Recurse -Force
        }
        else {
            Copy-Item -LiteralPath $source -Destination $destination -Force
        }
    }

    if (-not (Test-Path -LiteralPath $OutputDirectory)) {
        New-Item -ItemType Directory -Path $OutputDirectory -Force | Out-Null
    }

    $zipName = 'FileOptimizer-{0}.zip' -f $version
    $zipPath = Join-Path $OutputDirectory $zipName
    if (Test-Path -LiteralPath $zipPath) {
        Remove-Item -LiteralPath $zipPath -Force
    }

    $zipModuleRoot = Join-Path $zipStagingRoot 'FileOptimizer'
    $zipVersionFolder = Join-Path $zipModuleRoot $version.ToString()
    New-Item -ItemType Directory -Path $zipVersionFolder -Force | Out-Null
    Get-ChildItem -LiteralPath $moduleFolder | Copy-Item -Destination $zipVersionFolder -Recurse -Force
    Compress-Archive -LiteralPath $zipModuleRoot -DestinationPath $zipPath -Force

    [PSCustomObject]@{
        Version     = $version
        ArchivePath = (Resolve-Path -LiteralPath $zipPath).Path
        ModulePath  = (Resolve-Path -LiteralPath $moduleFolder).Path
        ModuleRoot  = $ModuleRoot
    }
}
finally {
    if (Test-Path -LiteralPath $zipStagingRoot) {
        Remove-Item -LiteralPath $zipStagingRoot -Recurse -Force -ErrorAction SilentlyContinue
    }
}