Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5e6a80c
Initial plan
Copilot Oct 22, 2025
1ea792d
Add native DEB package builder and remove fpm dependency
Copilot Oct 22, 2025
f7fd1ba
Fix New-NativeDeb function: handle symlinks and control file format
Copilot Oct 22, 2025
85432aa
Add documentation comment to Get-FpmArguments function
Copilot Oct 22, 2025
c2f21df
Address code review feedback: improve control file generation, symlin…
Copilot Oct 22, 2025
7e03559
Address review feedback: use PowerShell commands directly, add dpkg f…
Copilot Oct 27, 2025
f7b1d5c
Install azurelinux-repos-extended before dpkg on Mariner
Copilot Oct 27, 2025
a191190
Merge branch 'master' into copilot/remove-fpm-deb-packaging
daxian-dbw Oct 27, 2025
cc0cfb0
Minor change to trigger CIs
daxian-dbw Oct 28, 2025
d91e9c7
Merge branch 'master' into copilot/remove-fpm-deb-packaging
daxian-dbw Oct 28, 2025
0816e95
Fix DEB packaging errors: control file format, symlink permissions, a…
Copilot Oct 28, 2025
d4b53b5
Simplify code: remove unnecessary else block and improve cp commands …
Copilot Oct 28, 2025
96956af
Fix DEB package name validation: update regex pattern and fail when n…
Copilot Oct 28, 2025
2c0891a
Make RPM and Tar.Gz package validation tests fail when no packages found
Copilot Oct 28, 2025
3bf1cfe
Apply suggestion from @daxian-dbw
daxian-dbw Oct 28, 2025
f514124
Merge branch 'master' into copilot/remove-fpm-deb-packaging
daxian-dbw Oct 28, 2025
98d973e
Use Write-LogGroup function for DEB control file output
Copilot Oct 28, 2025
0bba464
Merge branch 'master' into copilot/remove-fpm-deb-packaging
TravisEz13 Oct 28, 2025
74f4969
Address Copilot's comments
daxian-dbw Oct 28, 2025
1c55a66
Wrap native commands with Start-NativeExecution for proper error hand…
Copilot Oct 28, 2025
75c7795
Use -VerboseOutputOnError switch instead of manual error handling for…
Copilot Oct 28, 2025
97a7c38
Remove fpm installation code - no longer needed after native packagin…
Copilot Oct 28, 2025
089faae
Clean up fpm related code/comments in packaging.psm1
daxian-dbw Oct 28, 2025
95088c5
Remove Install-GlobalGem
daxian-dbw Oct 28, 2025
32d0f53
Remove a comment about fpm
daxian-dbw Oct 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 25 additions & 51 deletions build.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -2234,43 +2234,6 @@ function Get-RedHatPackageManager {
}
}

function Install-GlobalGem {
param(
[Parameter()]
[string]
$Sudo = "",

[Parameter(Mandatory)]
[string]
$GemName,

[Parameter(Mandatory)]
[string]
$GemVersion
)
try {
# We cannot guess if the user wants to run gem install as root on linux and windows,
# but macOs usually requires sudo
$gemsudo = ''
if($environment.IsMacOS -or $env:TF_BUILD -or $env:GITHUB_ACTIONS) {
$gemsudo = $sudo
}

Start-NativeExecution ([ScriptBlock]::Create("$gemsudo gem install $GemName -v $GemVersion --no-document"))

} catch {
Write-Warning "Installation of gem $GemName $GemVersion failed! Must resolve manually."
$logs = Get-ChildItem "/var/lib/gems/*/extensions/x86_64-linux/*/$GemName-*/gem_make.out" | Select-Object -ExpandProperty FullName
foreach ($log in $logs) {
Write-Verbose "Contents of: $log" -Verbose
Get-Content -Raw -Path $log -ErrorAction Ignore | ForEach-Object { Write-Verbose $_ -Verbose }
Write-Verbose "END Contents of: $log" -Verbose
}

throw
}
}

function Start-PSBootstrap {
[CmdletBinding()]
param(
Expand All @@ -2282,7 +2245,7 @@ function Start-PSBootstrap {
[switch]$BuildLinuxArm,
[switch]$Force,
[Parameter(Mandatory = $true)]
# Package: Install dependencies for packaging tools (fpm, rpmbuild, WiX)
# Package: Install dependencies for packaging tools (rpmbuild, dpkg-deb, pkgbuild, WiX)
# DotNet: Install the .NET SDK
# Both: Package and DotNet scenarios
# Tools: Install .NET global tools (e.g., dotnet-format)
Expand Down Expand Up @@ -2321,7 +2284,9 @@ function Start-PSBootstrap {
elseif ($environment.IsUbuntu18) { $Deps += "libicu60"}

# Packaging tools
if ($Scenario -eq 'Both' -or $Scenario -eq 'Package') { $Deps += "ruby-dev", "groff", "libffi-dev", "rpm", "g++", "make" }
# Note: ruby-dev, libffi-dev, g++, and make are no longer needed for DEB packaging
# DEB packages now use native dpkg-deb (pre-installed)
if ($Scenario -eq 'Both' -or $Scenario -eq 'Package') { $Deps += "groff", "rpm" }

# Install dependencies
# change the fontend from apt-get to noninteractive
Expand All @@ -2345,7 +2310,9 @@ function Start-PSBootstrap {
$Deps += "libicu", "openssl-libs"

# Packaging tools
if ($Scenario -eq 'Both' -or $Scenario -eq 'Package') { $Deps += "ruby-devel", "rpm-build", "groff", 'libffi-devel', "gcc-c++" }
# Note: ruby-devel and libffi-devel are no longer needed
# RPM packages use rpmbuild, DEB packages use dpkg-deb
if ($Scenario -eq 'Both' -or $Scenario -eq 'Package') { $Deps += "rpm-build", "groff" }

$PackageManager = Get-RedHatPackageManager

Expand All @@ -2366,7 +2333,8 @@ function Start-PSBootstrap {
$Deps += "wget"

# Packaging tools
if ($Scenario -eq 'Both' -or $Scenario -eq 'Package') { $Deps += "ruby-devel", "rpmbuild", "groff", 'libffi-devel', "gcc" }
# Note: ruby-devel and libffi-devel are no longer needed for packaging
if ($Scenario -eq 'Both' -or $Scenario -eq 'Package') { $Deps += "rpmbuild", "groff" }

$PackageManager = "zypper --non-interactive install"
$baseCommand = "$sudo $PackageManager"
Expand Down Expand Up @@ -2405,17 +2373,7 @@ function Start-PSBootstrap {
}
}

# Install [fpm](https://github.com/jordansissel/fpm)
# Note: fpm is now only needed for DEB and macOS packages; RPM packages use rpmbuild directly
if ($Scenario -in 'All', 'Both', 'Package') {
# Install fpm on Debian-based systems, macOS, and Mariner (where DEB packages are built)
if (($environment.IsLinux -and ($environment.IsDebianFamily -or $environment.IsMariner)) -or $environment.IsMacOS) {
Install-GlobalGem -Sudo $sudo -GemName "dotenv" -GemVersion "2.8.1"
Comment thread
daxian-dbw marked this conversation as resolved.
Install-GlobalGem -Sudo $sudo -GemName "ffi" -GemVersion "1.16.3"
Install-GlobalGem -Sudo $sudo -GemName "fpm" -GemVersion "1.15.1"
Install-GlobalGem -Sudo $sudo -GemName "rexml" -GemVersion "3.2.5"
}

# For RPM-based systems, ensure rpmbuild is available
if ($environment.IsLinux -and ($environment.IsRedHatFamily -or $environment.IsSUSEFamily -or $environment.IsMariner)) {
Write-Verbose -Verbose "Checking for rpmbuild..."
Expand All @@ -2424,6 +2382,22 @@ function Start-PSBootstrap {
Start-NativeExecution -sb ([ScriptBlock]::Create("$sudo $PackageManager install -y rpm-build")) -IgnoreExitcode
}
}

# For Debian-based systems and Mariner, ensure dpkg-deb is available
if ($environment.IsLinux -and ($environment.IsDebianFamily -or $environment.IsMariner)) {
Write-Verbose -Verbose "Checking for dpkg-deb..."
if (!(Get-Command dpkg-deb -ErrorAction SilentlyContinue)) {
Write-Warning "dpkg-deb not found. Installing dpkg package..."
if ($environment.IsMariner) {
# For Mariner (Azure Linux), install the extended repo first to access dpkg.
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
Comment thread
daxian-dbw marked this conversation as resolved.
} else {
Start-NativeExecution -sb ([ScriptBlock]::Create("$sudo apt-get install -y dpkg")) -IgnoreExitcode
}
}
}
}
}

Expand Down
48 changes: 37 additions & 11 deletions test/packaging/linux/package-validation.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@ Describe "Linux Package Name Validation" {
It "Should have valid RPM package names" {
$rpmPackages = Get-ChildItem -Path $artifactsDir -Recurse -Filter *.rpm -ErrorAction SilentlyContinue

if ($rpmPackages.Count -eq 0) {
Set-ItResult -Skipped -Because "No RPM packages found in artifacts directory"
return
}
$rpmPackages.Count | Should -BeGreaterThan 0 -Because "At least one RPM package should exist in the artifacts directory"

$invalidPackages = @()
# Regex pattern for valid RPM package names.
Expand All @@ -49,19 +46,50 @@ Describe "Linux Package Name Validation" {
if ($invalidPackages.Count -gt 0) {
throw ($invalidPackages | Out-String)
}
}
}

Context "DEB Package Names" {
It "Should have valid DEB package names" {
$debPackages = Get-ChildItem -Path $artifactsDir -Recurse -Filter *.deb -ErrorAction SilentlyContinue

$debPackages.Count | Should -BeGreaterThan 0 -Because "At least one DEB package should exist in the artifacts directory"

$invalidPackages = @()
# Regex pattern for valid DEB package names.
# Valid examples:
# - powershell-preview_7.6.0-preview.6-1.deb_amd64.deb
# - powershell-lts_7.4.13-1.deb_amd64.deb
# - powershell_7.4.13-1.deb_amd64.deb
# Breakdown:
# ^powershell : Starts with 'powershell'
# (-preview|-lts)? : Optionally '-preview' or '-lts'
# _\d+\.\d+\.\d+ : Underscore followed by version number (e.g., _7.6.0)
# (-[a-z]+\.\d+)? : Optional dash, letters, dot, and digits (e.g., -preview.6)
# -1 : Literal '-1'
# \.deb_ : Literal '.deb_'
# (amd64|arm64) : Architecture
# \.deb$ : File extension
$debPackageNamePattern = '^powershell(-preview|-lts)?_\d+\.\d+\.\d+(-[a-z]+\.\d+)?-1\.deb_(amd64|arm64)\.deb$'

foreach ($package in $debPackages) {
if ($package.Name -notmatch $debPackageNamePattern) {
$invalidPackages += "$($package.Name) is not a valid DEB package name"
Write-Warning "$($package.Name) is not a valid DEB package name"
}
}

$rpmPackages.Count | Should -BeGreaterThan 0
if ($invalidPackages.Count -gt 0) {
throw ($invalidPackages | Out-String)
}
}
}

Context "Tar.Gz Package Names" {
It "Should have valid tar.gz package names" {
$tarPackages = Get-ChildItem -Path $artifactsDir -Recurse -Filter *.tar.gz -ErrorAction SilentlyContinue

if ($tarPackages.Count -eq 0) {
Set-ItResult -Skipped -Because "No tar.gz packages found in artifacts directory"
return
}
$tarPackages.Count | Should -BeGreaterThan 0 -Because "At least one tar.gz package should exist in the artifacts directory"

$invalidPackages = @()
foreach ($package in $tarPackages) {
Expand All @@ -76,8 +104,6 @@ Describe "Linux Package Name Validation" {
if ($invalidPackages.Count -gt 0) {
throw ($invalidPackages | Out-String)
}

$tarPackages.Count | Should -BeGreaterThan 0
}
}

Expand Down
Loading