function Zip-Includes { param ( [string]$IncludesFile, [string]$BuildNumber, [string]$BuildFolder, [string]$AppRoot ) # Read all paths from .includes $itemsToZip = @() Get-Content $IncludesFile | ForEach-Object { $relPath = $_.Trim() if ($relPath -ne "") { $fullPath = Join-Path $AppRoot $relPath if (Test-Path $fullPath) { $itemsToZip += [PSCustomObject]@{ FullPath = $fullPath RelativePath = $relPath } } else { Write-Warning "Path not found: $fullPath" } } } if (-Not $itemsToZip) { Write-Warning "No valid files or folders to zip." return } $zipFileName = Join-Path $BuildFolder "controllers-$BuildNumber.zip" if (Test-Path $zipFileName) { Remove-Item $zipFileName } # Create zip preserving relative paths $tempFolder = Join-Path $env:TEMP "zip-temp-$BuildNumber" if (Test-Path $tempFolder) { Remove-Item $tempFolder -Recurse -Force } New-Item -Path $tempFolder -ItemType Directory | Out-Null foreach ($item in $itemsToZip) { $dest = Join-Path $tempFolder $item.RelativePath $destDir = Split-Path $dest if (-Not (Test-Path $destDir)) { New-Item -Path $destDir -ItemType Directory | Out-Null } if ((Get-Item $item.FullPath).PSIsContainer) { Copy-Item -Path $item.FullPath -Destination $dest -Recurse } else { Copy-Item -Path $item.FullPath -Destination $dest } } Compress-Archive -Path (Join-Path $tempFolder "*") -DestinationPath $zipFileName # Cleanup temp folder Remove-Item $tempFolder -Recurse -Force Write-Output "Created zip: $zipFileName" }