Improve ADO package build and validation across platforms (#26398)

This commit is contained in:
Travis Plunk
2025-11-07 11:53:43 -08:00
committed by GitHub
parent 3953976592
commit e7bf5621bf
5 changed files with 116 additions and 74 deletions
+1 -1
View File
@@ -205,7 +205,7 @@ jobs:
} }
Import-Module Pester Import-Module Pester
$pesterConfig = New-PesterConfiguration $pesterConfig = New-PesterConfiguration
$pesterConfig.Run.Path = './tools/packaging/releaseTests/macOSPackage.tests.ps1' $pesterConfig.Run.Path = './test/packaging/macos/package-validation.tests.ps1'
$pesterConfig.Run.PassThru = $true $pesterConfig.Run.PassThru = $true
$pesterConfig.Output.Verbosity = 'Detailed' $pesterConfig.Output.Verbosity = 'Detailed'
$pesterConfig.TestResult.Enabled = $true $pesterConfig.TestResult.Enabled = $true
+19 -7
View File
@@ -116,13 +116,25 @@ jobs:
Start-PSPackage -Type osxpkg -SkipReleaseChecks -MacOSRuntime $macosRuntime -ReleaseTag $(ReleaseTagVar) -PackageBinPath $signedFilesPath -LTS:$LTS Start-PSPackage -Type osxpkg -SkipReleaseChecks -MacOSRuntime $macosRuntime -ReleaseTag $(ReleaseTagVar) -PackageBinPath $signedFilesPath -LTS:$LTS
$pkgNameFilter = "powershell-*$macosRuntime.pkg" $pkgNameFilter = "powershell-*$macosRuntime.pkg"
$pkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $pkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName Write-Verbose -Verbose "Looking for pkg packages with filter: $pkgNameFilter in '$(Pipeline.Workspace)' to upload..."
Write-Host "##vso[artifact.upload containerfolder=macos-pkgs;artifactname=macos-pkgs]$pkgPath" $pkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $pkgNameFilter -Recurse -File
foreach($p in $pkgPath) {
$file = $p.FullName
Write-Verbose -verbose "Uploading $file to macos-pkgs"
Write-Host "##vso[artifact.upload containerfolder=macos-pkgs;artifactname=macos-pkgs]$file"
}
Start-PSPackage -Type tar -SkipReleaseChecks -MacOSRuntime $macosRuntime -ReleaseTag $(ReleaseTagVar) -PackageBinPath $signedFilesPath -LTS:$LTS Start-PSPackage -Type tar -SkipReleaseChecks -MacOSRuntime $macosRuntime -ReleaseTag $(ReleaseTagVar) -PackageBinPath $signedFilesPath -LTS:$LTS
$tarPkgNameFilter = "powershell-*$macosRuntime.tar.gz" $tarPkgNameFilter = "powershell-*$macosRuntime.tar.gz"
$tarPkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $tarPkgNameFilter -Recurse -File | Select-Object -ExpandProperty FullName Write-Verbose -Verbose "Looking for tar packages with filter: $tarPkgNameFilter in '$(Pipeline.Workspace)' to upload..."
Write-Host "##vso[artifact.upload containerfolder=macos-pkgs;artifactname=macos-pkgs]$tarPkgPath" $tarPkgPath = Get-ChildItem -Path $(Pipeline.Workspace) -Filter $tarPkgNameFilter -Recurse -File
foreach($t in $tarPkgPath) {
$file = $t.FullName
Write-Verbose -verbose "Uploading $file to macos-pkgs"
Write-Host "##vso[artifact.upload containerfolder=macos-pkgs;artifactname=macos-pkgs]$file"
}
displayName: 'Package ${{ parameters.buildArchitecture}}' displayName: 'Package ${{ parameters.buildArchitecture}}'
env: env:
@@ -195,14 +207,14 @@ jobs:
- pwsh: | - pwsh: |
$signedPkg = Get-ChildItem -Path $(Pipeline.Workspace) -Filter "*osx*.zip" -File $signedPkg = Get-ChildItem -Path $(Pipeline.Workspace) -Filter "*osx*.zip" -File
$signedPkg | ForEach-Object { $signedPkg | ForEach-Object {
Write-Verbose -Verbose "Signed package zip: $_" Write-Verbose -Verbose "Signed package zip: $_"
if (-not (Test-Path $_)) { if (-not (Test-Path $_)) {
throw "Package not found: $_" throw "Package not found: $_"
} }
if (-not (Test-Path $(ob_outputDirectory))) { if (-not (Test-Path $(ob_outputDirectory))) {
$null = New-Item -Path $(ob_outputDirectory) -ItemType Directory $null = New-Item -Path $(ob_outputDirectory) -ItemType Directory
} }
+8 -3
View File
@@ -2399,7 +2399,7 @@ function Start-PSBootstrap {
Start-NativeExecution -sb ([ScriptBlock]::Create("$sudo $PackageManager install -y rpm-build")) -IgnoreExitcode Start-NativeExecution -sb ([ScriptBlock]::Create("$sudo $PackageManager install -y rpm-build")) -IgnoreExitcode
} }
} }
# For Debian-based systems and Mariner, ensure dpkg-deb is available # For Debian-based systems and Mariner, ensure dpkg-deb is available
if ($environment.IsLinux -and ($environment.IsDebianFamily -or $environment.IsMariner)) { if ($environment.IsLinux -and ($environment.IsDebianFamily -or $environment.IsMariner)) {
Write-Verbose -Verbose "Checking for dpkg-deb..." Write-Verbose -Verbose "Checking for dpkg-deb..."
@@ -2407,9 +2407,14 @@ function Start-PSBootstrap {
Write-Warning "dpkg-deb not found. Installing dpkg package..." Write-Warning "dpkg-deb not found. Installing dpkg package..."
if ($environment.IsMariner) { if ($environment.IsMariner) {
# For Mariner (Azure Linux), install the extended repo first to access dpkg. # For Mariner (Azure Linux), install the extended repo first to access dpkg.
Write-Verbose -verbose "BEGIN: /etc/os-release content:"
Get-Content /etc/os-release | Write-Verbose -verbose
Write-Verbose -verbose "END: /etc/os-release content"
Write-Verbose -Verbose "Installing azurelinux-repos-extended for Mariner..." Write-Verbose -Verbose "Installing azurelinux-repos-extended for Mariner..."
Start-NativeExecution -sb ([ScriptBlock]::Create("$sudo $PackageManager install -y azurelinux-repos-extended")) -IgnoreExitcode
Start-NativeExecution -sb ([ScriptBlock]::Create("$sudo $PackageManager install -y dpkg")) -IgnoreExitcode Start-NativeExecution -sb ([ScriptBlock]::Create("$sudo $PackageManager azurelinux-repos-extended")) -IgnoreExitcode -Verbose
Start-NativeExecution -sb ([ScriptBlock]::Create("$sudo $PackageManager dpkg")) -IgnoreExitcode -Verbose
} else { } else {
Start-NativeExecution -sb ([ScriptBlock]::Create("$sudo apt-get install -y dpkg")) -IgnoreExitcode Start-NativeExecution -sb ([ScriptBlock]::Create("$sudo apt-get install -y dpkg")) -IgnoreExitcode
} }
@@ -1,51 +1,54 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
Describe "Verify macOS Package" { Describe "Verify macOS Package" {
BeforeAll { BeforeAll {
Write-Verbose "In Describe BeforeAll" -Verbose Write-Verbose "In Describe BeforeAll" -Verbose
Import-Module $PSScriptRoot/../../../build.psm1 Import-Module $PSScriptRoot/../../../build.psm1
# Find the macOS package # Find the macOS package
$packagePath = $env:PACKAGE_FOLDER $packagePath = $env:PACKAGE_FOLDER
if (-not $packagePath) { if (-not $packagePath) {
$packagePath = Get-Location $packagePath = Get-Location
} }
Write-Verbose "Looking for package in: $packagePath" -Verbose Write-Verbose "Looking for package in: $packagePath" -Verbose
$package = Get-ChildItem -Path $packagePath -Filter "*.pkg" -ErrorAction SilentlyContinue | Select-Object -First 1 $package = Get-ChildItem -Path $packagePath -Filter "*.pkg" -ErrorAction SilentlyContinue | Select-Object -First 1
if (-not $package) { if (-not $package) {
Write-Warning "No .pkg file found in $packagePath" Write-Warning "No .pkg file found in $packagePath"
} else { } else {
Write-Verbose "Found package: $($package.FullName)" -Verbose Write-Verbose "Found package: $($package.FullName)" -Verbose
} }
# Set up test directories # Set up test directories
$script:package = $package $script:package = $package
$script:expandDir = $null $script:expandDir = $null
$script:payloadDir = $null $script:payloadDir = $null
$script:extractedFiles = @() $script:extractedFiles = @()
if ($package) { if ($package) {
# Use TestDrive for temporary directories - pkgutil will create the expand directory # Use TestDrive for temporary directories - pkgutil will create the expand directory
$script:expandDir = Join-Path "TestDrive:" -ChildPath "package-contents-test" $script:expandDir = Join-Path "TestDrive:" -ChildPath "package-contents-test"
$expandDirResolved = (Resolve-Path "TestDrive:").ProviderPath $expandDirResolved = (Resolve-Path "TestDrive:").ProviderPath
$script:expandDir = Join-Path $expandDirResolved -ChildPath "package-contents-test" $script:expandDir = Join-Path $expandDirResolved -ChildPath "package-contents-test"
Write-Verbose "Expanding package to: $($script:expandDir)" -Verbose Write-Verbose "Expanding package to: $($script:expandDir)" -Verbose
# pkgutil will create the directory itself, so don't pre-create it # pkgutil will create the directory itself, so don't pre-create it
Start-NativeExecution { Start-NativeExecution {
pkgutil --expand $package.FullName $script:expandDir pkgutil --expand $package.FullName $script:expandDir
} }
# Extract the payload to verify files # Extract the payload to verify files
$script:payloadDir = Join-Path "TestDrive:" -ChildPath "package-payload-test" $script:payloadDir = Join-Path "TestDrive:" -ChildPath "package-payload-test"
$payloadDirResolved = (Resolve-Path "TestDrive:").ProviderPath $payloadDirResolved = (Resolve-Path "TestDrive:").ProviderPath
$script:payloadDir = Join-Path $payloadDirResolved -ChildPath "package-payload-test" $script:payloadDir = Join-Path $payloadDirResolved -ChildPath "package-payload-test"
# Create payload directory since cpio needs it # Create payload directory since cpio needs it
if (-not (Test-Path $script:payloadDir)) { if (-not (Test-Path $script:payloadDir)) {
$null = New-Item -ItemType Directory -Path $script:payloadDir -Force $null = New-Item -ItemType Directory -Path $script:payloadDir -Force
} }
$componentPkg = Get-ChildItem -Path $script:expandDir -Filter "*.pkg" -Recurse | Select-Object -First 1 $componentPkg = Get-ChildItem -Path $script:expandDir -Filter "*.pkg" -Recurse | Select-Object -First 1
if ($componentPkg) { if ($componentPkg) {
Write-Verbose "Extracting payload from: $($componentPkg.FullName)" -Verbose Write-Verbose "Extracting payload from: $($componentPkg.FullName)" -Verbose
@@ -57,40 +60,60 @@ Describe "Verify macOS Package" {
Pop-Location Pop-Location
} }
} }
# Get all extracted files for verification # Get all extracted files for verification
$script:extractedFiles = Get-ChildItem -Path $script:payloadDir -Recurse -ErrorAction SilentlyContinue $script:extractedFiles = Get-ChildItem -Path $script:payloadDir -Recurse -ErrorAction SilentlyContinue
Write-Verbose "Extracted $($script:extractedFiles.Count) files" -Verbose Write-Verbose "Extracted $($script:extractedFiles.Count) files" -Verbose
} }
} }
AfterAll { AfterAll {
# TestDrive automatically cleans up, but we can ensure cleanup happens # TestDrive automatically cleans up, but we can ensure cleanup happens
# No manual cleanup needed as TestDrive handles it # No manual cleanup needed as TestDrive handles it
} }
Context "Package existence and structure" { Context "Package existence and structure" {
It "Package file should exist" { It "Package file should exist" {
$script:package | Should -Not -BeNullOrEmpty -Because "A .pkg file should be created" $script:package | Should -Not -BeNullOrEmpty -Because "A .pkg file should be created"
$script:package.Extension | Should -Be ".pkg" $script:package.Extension | Should -Be ".pkg"
} }
It "Package name should follow correct naming convention" {
$script:package | Should -Not -BeNullOrEmpty
# Regex pattern for valid macOS PKG package names.
# Valid examples:
# - powershell-7.4.13-osx-x64.pkg (Intel x64 - note: x64 with hyphens for compatibility)
# - powershell-7.4.13-osx-arm64.pkg (Apple Silicon)
# - powershell-preview-7.6.0-preview.6-osx-x64.pkg
# - powershell-lts-7.4.13-osx-arm64.pkg
$pkgPackageNamePattern = '^powershell(-preview|-lts)?-\d+\.\d+\.\d+(-[a-z]+\.\d+)?-osx-(x64|arm64)\.pkg$'
$script:package.Name | Should -Match $pkgPackageNamePattern -Because "Package name should follow the standard naming convention"
}
It "Package name should NOT use x86_64 with underscores" {
$script:package | Should -Not -BeNullOrEmpty
$script:package.Name | Should -Not -Match 'x86_64' -Because "Package should use 'x64' not 'x86_64' (with underscores) for compatibility"
}
It "Package should expand successfully" { It "Package should expand successfully" {
$script:expandDir | Should -Exist $script:expandDir | Should -Exist
Get-ChildItem -Path $script:expandDir | Should -Not -BeNullOrEmpty Get-ChildItem -Path $script:expandDir | Should -Not -BeNullOrEmpty
} }
It "Package should have a component package" { It "Package should have a component package" {
$componentPkg = Get-ChildItem -Path $script:expandDir -Filter "*.pkg" -Recurse -ErrorAction SilentlyContinue $componentPkg = Get-ChildItem -Path $script:expandDir -Filter "*.pkg" -Recurse -ErrorAction SilentlyContinue
$componentPkg | Should -Not -BeNullOrEmpty -Because "Package should contain a component.pkg" $componentPkg | Should -Not -BeNullOrEmpty -Because "Package should contain a component.pkg"
} }
It "Payload should extract successfully" { It "Payload should extract successfully" {
$script:payloadDir | Should -Exist $script:payloadDir | Should -Exist
$script:extractedFiles | Should -Not -BeNullOrEmpty -Because "Package payload should contain files" $script:extractedFiles | Should -Not -BeNullOrEmpty -Because "Package payload should contain files"
} }
} }
Context "Required files in package" { Context "Required files in package" {
BeforeAll { BeforeAll {
$expectedFilePatterns = @{ $expectedFilePatterns = @{
@@ -99,7 +122,7 @@ Describe "Verify macOS Package" {
"Man page" = "usr/local/share/man/man1/pwsh*.gz" "Man page" = "usr/local/share/man/man1/pwsh*.gz"
"Launcher application plist" = "Applications/PowerShell*.app/Contents/Info.plist" "Launcher application plist" = "Applications/PowerShell*.app/Contents/Info.plist"
} }
$testCases = @() $testCases = @()
foreach ($key in $expectedFilePatterns.Keys) { foreach ($key in $expectedFilePatterns.Keys) {
$testCases += @{ $testCases += @{
@@ -107,23 +130,23 @@ Describe "Verify macOS Package" {
Pattern = $expectedFilePatterns[$key] Pattern = $expectedFilePatterns[$key]
} }
} }
$script:testCases = $testCases $script:testCases = $testCases
} }
It "Should contain <Description>" -TestCases $script:testCases { It "Should contain <Description>" -TestCases $script:testCases {
param($Description, $Pattern) param($Description, $Pattern)
$found = $script:extractedFiles | Where-Object { $_.FullName -like "*$Pattern*" } $found = $script:extractedFiles | Where-Object { $_.FullName -like "*$Pattern*" }
$found | Should -Not -BeNullOrEmpty -Because "$Description should exist in the package at path matching '$Pattern'" $found | Should -Not -BeNullOrEmpty -Because "$Description should exist in the package at path matching '$Pattern'"
} }
} }
Context "PowerShell binary verification" { Context "PowerShell binary verification" {
It "PowerShell executable should be executable" { It "PowerShell executable should be executable" {
$pwshBinary = $script:extractedFiles | Where-Object { $_.FullName -like "*/pwsh" -and $_.FullName -like "*/microsoft/powershell/*" } $pwshBinary = $script:extractedFiles | Where-Object { $_.FullName -like "*/pwsh" -and $_.FullName -like "*/microsoft/powershell/*" }
$pwshBinary | Should -Not -BeNullOrEmpty $pwshBinary | Should -Not -BeNullOrEmpty
# Check if file has executable permissions (on Unix-like systems) # Check if file has executable permissions (on Unix-like systems)
if ($IsLinux -or $IsMacOS) { if ($IsLinux -or $IsMacOS) {
$permissions = (Get-Item $pwshBinary[0].FullName).UnixFileMode $permissions = (Get-Item $pwshBinary[0].FullName).UnixFileMode
@@ -132,27 +155,27 @@ Describe "Verify macOS Package" {
} }
} }
} }
Context "Launcher application" { Context "Launcher application" {
It "Launcher app should have proper bundle structure" { It "Launcher app should have proper bundle structure" {
$plistFile = $script:extractedFiles | Where-Object { $_.FullName -like "*PowerShell*.app/Contents/Info.plist" } $plistFile = $script:extractedFiles | Where-Object { $_.FullName -like "*PowerShell*.app/Contents/Info.plist" }
$plistFile | Should -Not -BeNullOrEmpty $plistFile | Should -Not -BeNullOrEmpty
# Verify the bundle has required components # Verify the bundle has required components
$appPath = Split-Path (Split-Path $plistFile[0].FullName -Parent) -Parent $appPath = Split-Path (Split-Path $plistFile[0].FullName -Parent) -Parent
$macOSDir = Join-Path $appPath "Contents/MacOS" $macOSDir = Join-Path $appPath "Contents/MacOS"
$resourcesDir = Join-Path $appPath "Contents/Resources" $resourcesDir = Join-Path $appPath "Contents/Resources"
Test-Path $macOSDir | Should -Be $true -Because "App bundle should have Contents/MacOS directory" Test-Path $macOSDir | Should -Be $true -Because "App bundle should have Contents/MacOS directory"
Test-Path $resourcesDir | Should -Be $true -Because "App bundle should have Contents/Resources directory" Test-Path $resourcesDir | Should -Be $true -Because "App bundle should have Contents/Resources directory"
} }
It "Launcher script should exist and be executable" { It "Launcher script should exist and be executable" {
$launcherScript = $script:extractedFiles | Where-Object { $launcherScript = $script:extractedFiles | Where-Object {
$_.FullName -like "*PowerShell*.app/Contents/MacOS/PowerShell.sh" $_.FullName -like "*PowerShell*.app/Contents/MacOS/PowerShell.sh"
} }
$launcherScript | Should -Not -BeNullOrEmpty -Because "Launcher script should exist" $launcherScript | Should -Not -BeNullOrEmpty -Because "Launcher script should exist"
if ($IsLinux -or $IsMacOS) { if ($IsLinux -or $IsMacOS) {
$permissions = (Get-Item $launcherScript[0].FullName).UnixFileMode $permissions = (Get-Item $launcherScript[0].FullName).UnixFileMode
$permissions.ToString() | Should -Match 'x' -Because "Launcher script should have execute permissions" $permissions.ToString() | Should -Match 'x' -Because "Launcher script should have execute permissions"
+36 -34
View File
@@ -1239,15 +1239,15 @@ function New-UnixPackage {
# Use rpmbuild directly for RPM packages # Use rpmbuild directly for RPM packages
if ($PSCmdlet.ShouldProcess("Create RPM package with rpmbuild")) { if ($PSCmdlet.ShouldProcess("Create RPM package with rpmbuild")) {
Write-Log "Creating RPM package with rpmbuild..." Write-Log "Creating RPM package with rpmbuild..."
# Create rpmbuild directory structure # Create rpmbuild directory structure
$rpmBuildRoot = Join-Path $env:HOME "rpmbuild" $rpmBuildRoot = Join-Path $env:HOME "rpmbuild"
$specsDir = Join-Path $rpmBuildRoot "SPECS" $specsDir = Join-Path $rpmBuildRoot "SPECS"
$rpmsDir = Join-Path $rpmBuildRoot "RPMS" $rpmsDir = Join-Path $rpmBuildRoot "RPMS"
New-Item -ItemType Directory -Path $specsDir -Force | Out-Null New-Item -ItemType Directory -Path $specsDir -Force | Out-Null
New-Item -ItemType Directory -Path $rpmsDir -Force | Out-Null New-Item -ItemType Directory -Path $rpmsDir -Force | Out-Null
# Generate RPM spec file # Generate RPM spec file
$specContent = New-RpmSpec ` $specContent = New-RpmSpec `
-Name $Name ` -Name $Name `
@@ -1264,11 +1264,11 @@ function New-UnixPackage {
-LinkInfo $Links ` -LinkInfo $Links `
-Distribution $DebDistro ` -Distribution $DebDistro `
-HostArchitecture $HostArchitecture -HostArchitecture $HostArchitecture
$specFile = Join-Path $specsDir "$Name.spec" $specFile = Join-Path $specsDir "$Name.spec"
$specContent | Out-File -FilePath $specFile -Encoding ascii $specContent | Out-File -FilePath $specFile -Encoding ascii
Write-Verbose "Generated spec file: $specFile" -Verbose Write-Verbose "Generated spec file: $specFile" -Verbose
# Log the spec file content # Log the spec file content
if ($env:GITHUB_ACTIONS -eq 'true') { if ($env:GITHUB_ACTIONS -eq 'true') {
Write-Host "::group::RPM Spec File Content" Write-Host "::group::RPM Spec File Content"
@@ -1277,7 +1277,7 @@ function New-UnixPackage {
} else { } else {
Write-Verbose "RPM Spec File Content:`n$specContent" -Verbose Write-Verbose "RPM Spec File Content:`n$specContent" -Verbose
} }
# Build RPM package # Build RPM package
try { try {
# Use bash to properly handle rpmbuild arguments # Use bash to properly handle rpmbuild arguments
@@ -1290,16 +1290,16 @@ function New-UnixPackage {
Write-Verbose "Running: $buildCmd" -Verbose Write-Verbose "Running: $buildCmd" -Verbose
$Output = bash -c $buildCmd 2>&1 $Output = bash -c $buildCmd 2>&1
$exitCode = $LASTEXITCODE $exitCode = $LASTEXITCODE
if ($exitCode -ne 0) { if ($exitCode -ne 0) {
throw "rpmbuild failed with exit code $exitCode" throw "rpmbuild failed with exit code $exitCode"
} }
# Find the generated RPM # Find the generated RPM
$rpmFile = Get-ChildItem -Path (Join-Path $rpmsDir $HostArchitecture) -Filter "*.rpm" -ErrorAction Stop | $rpmFile = Get-ChildItem -Path (Join-Path $rpmsDir $HostArchitecture) -Filter "*.rpm" -ErrorAction Stop |
Sort-Object -Property LastWriteTime -Descending | Sort-Object -Property LastWriteTime -Descending |
Select-Object -First 1 Select-Object -First 1
if ($rpmFile) { if ($rpmFile) {
# Copy RPM to current location # Copy RPM to current location
Copy-Item -Path $rpmFile.FullName -Destination $CurrentLocation -Force Copy-Item -Path $rpmFile.FullName -Destination $CurrentLocation -Force
@@ -1337,7 +1337,7 @@ function New-UnixPackage {
-AfterRemoveScript $AfterScriptInfo.AfterRemoveScript ` -AfterRemoveScript $AfterScriptInfo.AfterRemoveScript `
-HostArchitecture $HostArchitecture ` -HostArchitecture $HostArchitecture `
-CurrentLocation $CurrentLocation -CurrentLocation $CurrentLocation
$Output = @("Created package {:path=>""$($result.PackageName)""}") $Output = @("Created package {:path=>""$($result.PackageName)""}")
} }
catch { catch {
@@ -1348,7 +1348,7 @@ function New-UnixPackage {
# Use native macOS packaging tools # Use native macOS packaging tools
if ($PSCmdlet.ShouldProcess("Create macOS package with pkgbuild/productbuild")) { if ($PSCmdlet.ShouldProcess("Create macOS package with pkgbuild/productbuild")) {
Write-Log "Creating macOS package with native tools..." Write-Log "Creating macOS package with native tools..."
$macPkgArgs = @{ $macPkgArgs = @{
Name = $Name Name = $Name
Version = $packageVersion Version = $packageVersion
@@ -1363,7 +1363,7 @@ function New-UnixPackage {
HostArchitecture = $HostArchitecture HostArchitecture = $HostArchitecture
CurrentLocation = $CurrentLocation CurrentLocation = $CurrentLocation
} }
try { try {
$packageFile = New-MacOSPackage @macPkgArgs $packageFile = New-MacOSPackage @macPkgArgs
$Output = @("Created package {:path=>""$($packageFile.Name)""}") $Output = @("Created package {:path=>""$($packageFile.Name)""}")
@@ -1386,7 +1386,7 @@ function New-UnixPackage {
Clear-MacOSLauncher Clear-MacOSLauncher
} }
} }
# Clean up rpmbuild directory if it was created # Clean up rpmbuild directory if it was created
if ($Type -eq 'rpm') { if ($Type -eq 'rpm') {
$rpmBuildRoot = Join-Path $env:HOME "rpmbuild" $rpmBuildRoot = Join-Path $env:HOME "rpmbuild"
@@ -1395,7 +1395,7 @@ function New-UnixPackage {
Remove-Item -Path $rpmBuildRoot -Recurse -Force -ErrorAction SilentlyContinue Remove-Item -Path $rpmBuildRoot -Recurse -Force -ErrorAction SilentlyContinue
} }
} }
if ($AfterScriptInfo.AfterInstallScript) { if ($AfterScriptInfo.AfterInstallScript) {
Remove-Item -ErrorAction 'silentlycontinue' $AfterScriptInfo.AfterInstallScript -Force Remove-Item -ErrorAction 'silentlycontinue' $AfterScriptInfo.AfterInstallScript -Force
} }
@@ -1489,13 +1489,13 @@ function New-MacOsDistributionPackage
$resourcesDir = Join-Path -Path $tempDir -ChildPath 'resources' $resourcesDir = Join-Path -Path $tempDir -ChildPath 'resources'
New-Item -ItemType Directory -Path $resourcesDir -Force > $null New-Item -ItemType Directory -Path $resourcesDir -Force > $null
# Copy background file to temp directory # Copy background file to temp directory
$backgroundFile = "$RepoRoot/assets/macDialog.png" $backgroundFile = "$RepoRoot/assets/macDialog.png"
if (Test-Path $backgroundFile) { if (Test-Path $backgroundFile) {
Copy-Item -Path $backgroundFile -Destination $resourcesDir -Force Copy-Item -Path $backgroundFile -Destination $resourcesDir -Force
} }
# Copy the component package to temp directory # Copy the component package to temp directory
$componentFileName = Split-Path -Leaf -Path $ComponentPackage $componentFileName = Split-Path -Leaf -Path $ComponentPackage
$tempComponentPath = Join-Path -Path $tempDir -ChildPath $componentFileName $tempComponentPath = Join-Path -Path $tempDir -ChildPath $componentFileName
@@ -1511,7 +1511,7 @@ function New-MacOsDistributionPackage
# Minimum OS version # Minimum OS version
$minOSVersion = "11.0" # macOS Big Sur minimum $minOSVersion = "11.0" # macOS Big Sur minimum
# format distribution template with: # format distribution template with:
# 0 - title # 0 - title
# 1 - version # 1 - version
@@ -1522,8 +1522,10 @@ function New-MacOsDistributionPackage
$PackagingStrings.OsxDistributionTemplate -f $PackageName, $Version, $componentFileName, $minOSVersion, $PackageIdentifier, $HostArchitecture | Out-File -Encoding utf8 -FilePath $distributionXmlPath -Force $PackagingStrings.OsxDistributionTemplate -f $PackageName, $Version, $componentFileName, $minOSVersion, $PackageIdentifier, $HostArchitecture | Out-File -Encoding utf8 -FilePath $distributionXmlPath -Force
# Build final package path # Build final package path
$finalPackagePath = Join-Path $OutputDirectory "$PackageName-$Version-osx-$HostArchitecture.pkg" # Rename x86_64 to x64 for compatibility
$packageArchName = if ($HostArchitecture -eq "x86_64") { "x64" } else { $HostArchitecture }
$finalPackagePath = Join-Path $OutputDirectory "$PackageName-$Version-osx-$packageArchName.pkg"
# Remove existing package if it exists # Remove existing package if it exists
if (Test-Path $finalPackagePath) { if (Test-Path $finalPackagePath) {
Write-Warning "Removing existing package: $finalPackagePath" Write-Warning "Removing existing package: $finalPackagePath"
@@ -1542,7 +1544,7 @@ function New-MacOsDistributionPackage
--resources $resourcesDir ` --resources $resourcesDir `
$finalPackagePath $finalPackagePath
} }
if (Test-Path $finalPackagePath) { if (Test-Path $finalPackagePath) {
Write-Log "Successfully created macOS package: $finalPackagePath" Write-Log "Successfully created macOS package: $finalPackagePath"
} }
@@ -1612,7 +1614,7 @@ function New-RpmSpec
# RPM doesn't allow hyphens in version, so convert them to underscores # RPM doesn't allow hyphens in version, so convert them to underscores
# e.g., "7.6.0-preview.6" becomes Version: 7.6.0_preview.6 # e.g., "7.6.0-preview.6" becomes Version: 7.6.0_preview.6
$rpmVersion = $Version -replace '-', '_' $rpmVersion = $Version -replace '-', '_'
# Build Release field with distribution suffix (e.g., "1.cm" or "1.rh") # Build Release field with distribution suffix (e.g., "1.cm" or "1.rh")
# Don't use RPM macros - build the full release string in PowerShell # Don't use RPM macros - build the full release string in PowerShell
$rpmRelease = "$Iteration.$Distribution" $rpmRelease = "$Iteration.$Distribution"
@@ -1638,7 +1640,7 @@ AutoReq: no
} else { } else {
# For cross-architecture builds, don't specify BuildArch in spec # For cross-architecture builds, don't specify BuildArch in spec
# The --target option will handle the architecture # The --target option will handle the architecture
# Disable automatic binary stripping for cross-arch builds # Disable automatic binary stripping for cross-arch builds
# The native /bin/strip on x86_64 cannot process ARM64 binaries and would fail with: # The native /bin/strip on x86_64 cannot process ARM64 binaries and would fail with:
# "Unable to recognise the format of the input file" # "Unable to recognise the format of the input file"
@@ -1646,7 +1648,7 @@ AutoReq: no
# __strip: This macro controls the command used for stripping binaries during the build process. # __strip: This macro controls the command used for stripping binaries during the build process.
# /bin/true: A command that does nothing and always exits successfully, effectively bypassing the stripping process. # /bin/true: A command that does nothing and always exits successfully, effectively bypassing the stripping process.
$specContent += "%define __strip /bin/true`n" $specContent += "%define __strip /bin/true`n"
# Disable debug package generation to prevent strip-related errors # Disable debug package generation to prevent strip-related errors
# Debug packages require binary stripping which fails for cross-arch builds # Debug packages require binary stripping which fails for cross-arch builds
# See: https://rpm-packaging-guide.github.io/#debugging # See: https://rpm-packaging-guide.github.io/#debugging
@@ -1903,11 +1905,11 @@ $(if ($extendedDescription) { $extendedDescription + "`n" })
# Copy DEBIAN directory and data files to build root # Copy DEBIAN directory and data files to build root
$buildDir = Join-Path $debBuildRoot "build" $buildDir = Join-Path $debBuildRoot "build"
New-Item -ItemType Directory -Path $buildDir -Force | Out-Null New-Item -ItemType Directory -Path $buildDir -Force | Out-Null
Write-Verbose "debianDir: $debianDir" -Verbose Write-Verbose "debianDir: $debianDir" -Verbose
Write-Verbose "dataDir: $dataDir" -Verbose Write-Verbose "dataDir: $dataDir" -Verbose
Write-Verbose "buildDir: $buildDir" -Verbose Write-Verbose "buildDir: $buildDir" -Verbose
# Use cp to preserve symlinks # Use cp to preserve symlinks
Start-NativeExecution { cp -a $debianDir "$buildDir/DEBIAN" } Start-NativeExecution { cp -a $debianDir "$buildDir/DEBIAN" }
Start-NativeExecution { cp -a $dataDir/* $buildDir } Start-NativeExecution { cp -a $dataDir/* $buildDir }
@@ -2017,14 +2019,14 @@ function New-MacOSPackage
$linkDestDir = Join-Path $pkgRoot (Split-Path $link.Destination -Parent) $linkDestDir = Join-Path $pkgRoot (Split-Path $link.Destination -Parent)
New-Item -ItemType Directory -Path $linkDestDir -Force | Out-Null New-Item -ItemType Directory -Path $linkDestDir -Force | Out-Null
$finalLinkPath = Join-Path $pkgRoot $link.Destination $finalLinkPath = Join-Path $pkgRoot $link.Destination
Write-Verbose "Creating symlink at $finalLinkPath" -Verbose Write-Verbose "Creating symlink at $finalLinkPath" -Verbose
# Remove if exists # Remove if exists
if (Test-Path $finalLinkPath) { if (Test-Path $finalLinkPath) {
Remove-Item $finalLinkPath -Force Remove-Item $finalLinkPath -Force
} }
# Get the target of the original symlink and recreate it in the package root # Get the target of the original symlink and recreate it in the package root
if (Test-Path $link.Source) { if (Test-Path $link.Source) {
$linkTarget = (Get-Item $link.Source).Target $linkTarget = (Get-Item $link.Source).Target
@@ -2050,10 +2052,10 @@ function New-MacOSPackage
# Build the component package using pkgbuild # Build the component package using pkgbuild
$pkgIdentifier = Get-MacOSPackageId -IsPreview:($Name -like '*-preview') $pkgIdentifier = Get-MacOSPackageId -IsPreview:($Name -like '*-preview')
if ($PSCmdlet.ShouldProcess("Build component package with pkgbuild")) { if ($PSCmdlet.ShouldProcess("Build component package with pkgbuild")) {
Write-Log "Running pkgbuild to create component package..." Write-Log "Running pkgbuild to create component package..."
Start-NativeExecution -VerboseOutputOnError { Start-NativeExecution -VerboseOutputOnError {
pkgbuild --root $pkgRoot ` pkgbuild --root $pkgRoot `
--identifier $pkgIdentifier ` --identifier $pkgIdentifier `
@@ -2062,7 +2064,7 @@ function New-MacOSPackage
--install-location "/" ` --install-location "/" `
$componentPkgPath $componentPkgPath
} }
Write-Verbose "Component package created: $componentPkgPath" -Verbose Write-Verbose "Component package created: $componentPkgPath" -Verbose
} }
@@ -2075,7 +2077,7 @@ function New-MacOSPackage
-HostArchitecture $HostArchitecture ` -HostArchitecture $HostArchitecture `
-PackageIdentifier $pkgIdentifier ` -PackageIdentifier $pkgIdentifier `
-IsPreview:($Name -like '*-preview') -IsPreview:($Name -like '*-preview')
return $distributionPackage return $distributionPackage
} }
finally { finally {