mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Improve ADO package build and validation across platforms (#26398)
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
+52
-29
@@ -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"
|
||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user