[release/v7.5] Remove usage of fpm for DEB package generation#26809
Conversation
There was a problem hiding this comment.
Pull request overview
This pull request is a backport of #26281 to release/v7.5 that removes the dependency on the fpm Ruby gem for DEB package generation and implements native DEB packaging using dpkg-deb directly. This change aligns DEB packaging with the approach already taken for RPM (using rpmbuild) and macOS (using pkgbuild/productbuild) packages.
Changes:
- Implemented New-NativeDeb function to create DEB packages natively using dpkg-deb
- Removed fpm-related code including Get-FpmArguments and Install-GlobalGem functions
- Updated dependency installation logic in Start-PSBootstrap to install dpkg-deb instead of fpm and Ruby gems
- Added DEB package name validation tests
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| tools/packaging/packaging.psm1 | Implements New-NativeDeb function for native DEB packaging; removes Get-FpmArguments and all fpm-related code; updates comments to reflect dpkg-deb usage |
| build.psm1 | Removes Install-GlobalGem function and fpm installation code; adds dpkg-deb installation logic for Debian-based systems and Mariner; removes Ruby and related dependency installation |
| test/packaging/linux/package-validation.tests.ps1 | Adds DEB package name validation tests; changes test behavior to fail instead of skip when no packages found |
| # - 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$' |
There was a problem hiding this comment.
The DEB package name pattern is incorrect and doesn't match the actual filenames generated by New-NativeDeb. The pattern expects -1\.deb_ (line 70, 73), but the actual iteration can be "1.deb" OR distribution-specific like "1.ubuntu.20.04" (see packaging.psm1:1125 where Iteration is appended with distribution). The generated filename format is ${Name}_${Version}-${Iteration}_${HostArchitecture}.deb (packaging.psm1:1898), which produces names like powershell_7.4.13-1.ubuntu.20.04_amd64.deb, not powershell_7.4.13-1.deb_amd64.deb. The pattern should be: ^powershell(-preview|-lts)?_\d+\.\d+\.\d+(-[a-z]+\.\d+)?-\d+(\.[a-z]+\.\d+(\.\d+)?)?_(amd64|arm64)\.deb$ to match both "1.deb" and "1.ubuntu.20.04" style iterations.
| # - 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$' | |
| # - powershell-preview_7.6.0-preview.6-1.ubuntu.20.04_amd64.deb | |
| # - powershell-lts_7.4.13-1_amd64.deb | |
| # - powershell_7.4.13-1.ubuntu.20.04_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) | |
| # -\d+ : Dash followed by numeric iteration (e.g., -1) | |
| # (\.[a-z]+\.\d+(\.\d+)?)? : Optional distribution suffix (e.g., .ubuntu.20.04) | |
| # _(amd64|arm64) : Underscore followed by architecture | |
| # \.deb$ : File extension | |
| $debPackageNamePattern = '^powershell(-preview|-lts)?_\d+\.\d+\.\d+(-[a-z]+\.\d+)?-\d+(\.[a-z]+\.\d+(\.\d+)?)?_(amd64|arm64)\.deb$' |
| # - 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$' |
There was a problem hiding this comment.
The example filenames in the comments are incorrect and inconsistent with the actual DEB package naming format. The examples show filenames like powershell-preview_7.6.0-preview.6-1.deb_amd64.deb, but based on the New-NativeDeb implementation (packaging.psm1:1898), the actual format is powershell-preview_7.6.0-preview.6-1_amd64.deb. The examples should be updated to reflect the correct format.
| # - 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$' | |
| # - powershell-preview_7.6.0-preview.6-1_amd64.deb | |
| # - powershell-lts_7.4.13-1_amd64.deb | |
| # - powershell_7.4.13-1_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' | |
| # _ : Underscore separating version/build from architecture | |
| # (amd64|arm64) : Architecture | |
| # \.deb$ : File extension | |
| $debPackageNamePattern = '^powershell(-preview|-lts)?_\d+\.\d+\.\d+(-[a-z]+\.\d+)?-1_(amd64|arm64)\.deb$' |
| $Output = @("Created package {:path=>""$($result.PackageName)""}") | ||
| } | ||
| catch { | ||
| Write-Verbose -Message "!!!Handling error in native DEB creation!!!" -Verbose -ErrorAction SilentlyContinue |
There was a problem hiding this comment.
The error handling in the catch block is incomplete and inconsistent with the RPM (lines 1311-1318) and macOS (lines 1371-1375) code paths. The DEB error handling only logs a verbose message but does not call Get-Error to display detailed error information, and does not re-throw the exception. This means that if New-NativeDeb fails, the error will be silently swallowed and execution will continue, potentially leading to confusing downstream errors when trying to access $Output or $createdPackage. The catch block should include Get-Error -InputObject $_ and throw to ensure proper error handling consistency.
| Write-Verbose -Message "!!!Handling error in native DEB creation!!!" -Verbose -ErrorAction SilentlyContinue | |
| Write-Verbose -Message "!!!Handling error in native DEB creation!!!" -Verbose -ErrorAction SilentlyContinue | |
| Get-Error -InputObject $_ | |
| throw |
| Priority: optional | ||
| Section: shells | ||
| Homepage: https://microsoft.com/powershell | ||
| Depends: $(if ($Dependencies) { $Dependencies -join ', ' }) |
There was a problem hiding this comment.
The Depends field in the control file will have an empty value if $Dependencies is null or empty. According to Debian control file format specifications, a field with an empty value (e.g., "Depends: ") is not valid. When there are no dependencies, the Depends field should be omitted entirely from the control file. The control file generation should conditionally include the Depends line only when $Dependencies has values.
Backport of #26281 to release/v7.5
Triggered by @daxian-dbw on behalf of @app/copilot-swe-agent
Original CL Label: CL-BuildPackaging
/cc @PowerShell/powershell-maintainers
Impact
REQUIRED: Choose either Tooling Impact or Customer Impact (or both). At least one checkbox must be selected.
Tooling Impact
Removes fpm (Ruby gem) dependency for DEB package generation and implements native DEB packaging using dpkg-deb directly
Customer Impact
Regression
REQUIRED: Check exactly one box.
This is not a regression.
Testing
DEB package validation tests added to test/packaging/linux/package-validation.tests.ps1. Successfully built and validated DEB packages on multiple Linux distributions in CI.
Risk
REQUIRED: Check exactly one box.
Changes core packaging infrastructure for DEB packages. However, the change has been validated with comprehensive tests and successful CI builds. The new native implementation is more maintainable and removes external Ruby dependency.