@@ -153,6 +153,8 @@ class DscArtifactDirectoryPath {
153153 [string ]$BinRoot
154154 [string ]$Bin
155155 [string ]$RustTarget
156+ [string ]$DebTarget
157+ [string ]$RpmTarget
156158 [string ]$MsixBundle
157159 [string ]$MsixTarget
158160 [string ]$ZipTarget
@@ -1120,6 +1122,8 @@ function Get-ArtifactDirectoryPath {
11201122 BinRoot = Join-Path $PSScriptRoot ' bin'
11211123 Bin = Join-Path $PSScriptRoot ' bin' $Architecture $configuration
11221124 RustTarget = $env: CARGO_TARGET_DIR ?? (Join-Path $PSScriptRoot ' target' $Architecture $configuration )
1125+ DebTarget = Join-Path $PSScriptRoot ' bin' $Architecture ' deb'
1126+ RpmTarget = Join-Path $PSScriptRoot ' bin' $Architecture ' rpm'
11231127 MsixBundle = Join-Path $PSScriptRoot ' bin' ' msix'
11241128 MsixTarget = Join-Path $PSScriptRoot ' bin' $Architecture ' msix'
11251129 ZipTarget = Join-Path $PSScriptRoot ' bin' $Architecture ' zip'
@@ -1779,6 +1783,127 @@ function Test-ProjectWithPester {
17791783# endregion Test project functions
17801784
17811785# region Package project functions
1786+ function Build-DscDebPackage {
1787+ [CmdletBinding ()]
1788+ param (
1789+ [DscProjectBuildData ]$BuildData ,
1790+ [DscArtifactDirectoryPath ]$ArtifactDirectory ,
1791+ [ValidateSet (
1792+ ' current' ,
1793+ ' aarch64-pc-windows-msvc' ,
1794+ ' x86_64-pc-windows-msvc' ,
1795+ ' aarch64-apple-darwin' ,
1796+ ' x86_64-apple-darwin' ,
1797+ ' aarch64-unknown-linux-gnu' ,
1798+ ' aarch64-unknown-linux-musl' ,
1799+ ' x86_64-unknown-linux-gnu' ,
1800+ ' x86_64-unknown-linux-musl'
1801+ )]
1802+ $Architecture = ' current' ,
1803+ [switch ]$Release
1804+ )
1805+
1806+ begin {
1807+ if (! $IsLinux ) {
1808+ throw " DEB package creation is only supported on Linux"
1809+ }
1810+
1811+ # Check if dpkg-deb is available
1812+ if ($null -eq (Get-Command dpkg- deb - ErrorAction Ignore)) {
1813+ throw " dpkg-deb not found. Please install dpkg package (e.g., 'sudo apt install dpkg' or 'sudo dnf install dpkg')"
1814+ }
1815+ }
1816+
1817+ process {
1818+ $debTarget = Join-Path $PSScriptRoot ' bin' $architecture ' deb'
1819+ if (Test-Path $debTarget ) {
1820+ Remove-Item $debTarget - Recurse - ErrorAction Stop - Force
1821+ }
1822+
1823+ New-Item - ItemType Directory $debTarget > $null
1824+
1825+ # Create DEB package structure
1826+ $debBuildRoot = Join-Path $debTarget ' dsc'
1827+ $debDirs = @ (' DEBIAN' , ' opt/dsc' , ' usr/bin' )
1828+ foreach ($dir in $debDirs ) {
1829+ New-Item - ItemType Directory - Path (Join-Path $debBuildRoot $dir ) - Force > $null
1830+ }
1831+
1832+ if ($null -eq $BuildData ) {
1833+ $BuildData = Import-DscBuildData
1834+ }
1835+ $filesForPackage = $BuildData.PackageFiles.Linux
1836+ if ($null -eq $ArtifactDirectory ) {
1837+ $artifactDirectory = Get-ArtifactDirectoryPath - Architecture $Architecture - Release:$Release
1838+ }
1839+ $target = $artifactDirectory.DebTarget
1840+ $stagingDir = Join-Path $debBuildRoot ' opt' ' dsc'
1841+
1842+ foreach ($file in $filesForPackage ) {
1843+ if ((Get-Item " $target \$file " ) -is [System.IO.DirectoryInfo ]) {
1844+ Copy-Item " $target \$file " " $stagingDir \$file " - Recurse - ErrorAction Stop
1845+ } else {
1846+ Copy-Item " $target \$file " $stagingDir - ErrorAction Stop
1847+ }
1848+ }
1849+
1850+ # Create symlinks in usr/bin
1851+ $symlinkPath = Join-Path $debBuildRoot ' usr' ' bin' ' dsc'
1852+ New-Item - ItemType SymbolicLink - Path $symlinkPath - Target ' /opt/dsc/dsc' - Force > $null
1853+
1854+ $symlinkPath = Join-Path $debBuildRoot ' usr' ' bin' ' dsc-bicep-ext'
1855+ New-Item - ItemType SymbolicLink - Path $symlinkPath - Target ' /opt/dsc/dsc-bicep-ext' - Force > $null
1856+
1857+ # Determine DEB architecture
1858+ $debArch = if ($architecture -eq ' current' ) {
1859+ # Detect current system architecture
1860+ $currentArch = uname - m
1861+ if ($currentArch -eq ' x86_64' ) {
1862+ ' amd64'
1863+ } elseif ($currentArch -eq ' aarch64' ) {
1864+ ' arm64'
1865+ } else {
1866+ throw " Unsupported current architecture for DEB: $currentArch "
1867+ }
1868+ } elseif ($architecture -eq ' aarch64-unknown-linux-musl' -or $architecture -eq ' aarch64-unknown-linux-gnu' ) {
1869+ ' arm64'
1870+ } elseif ($architecture -eq ' x86_64-unknown-linux-musl' -or $architecture -eq ' x86_64-unknown-linux-gnu' ) {
1871+ ' amd64'
1872+ } else {
1873+ throw " Unsupported architecture for DEB: $architecture "
1874+ }
1875+
1876+ # Read the control template and replace placeholders
1877+ $controlTemplate = Get-Content " $PSScriptRoot /packaging/deb/control" - Raw
1878+ $productVersion = Get-DscCliVersion
1879+ $controlContent = $controlTemplate.Replace (' VERSION_PLACEHOLDER' , $productVersion ).Replace(' ARCH_PLACEHOLDER' , $debArch )
1880+ $controlFile = Join-Path $debBuildRoot ' DEBIAN' ' control'
1881+ Set-Content - Path $controlFile - Value $controlContent
1882+
1883+ Write-Verbose - Verbose " Building DEB package"
1884+ $debPackageName = " dsc_$productVersion -1_$debArch .deb"
1885+
1886+ # Build the DEB
1887+ dpkg- deb -- build $debBuildRoot 2>&1 > $debTarget / debbuild.log
1888+
1889+ if ($LASTEXITCODE -ne 0 ) {
1890+ Write-Error (Get-Content $debTarget / debbuild.log - Raw)
1891+ throw " Failed to create DEB package"
1892+ }
1893+
1894+ # Move the DEB to the bin directory with the correct name
1895+ $builtDeb = " $debBuildRoot .deb"
1896+ if (! (Test-Path $builtDeb )) {
1897+ throw " DEB package was not created"
1898+ }
1899+
1900+ $finalDebPath = Join-Path $PSScriptRoot ' bin' $debPackageName
1901+ Move-Item $builtDeb $finalDebPath - Force
1902+
1903+ Write-Host - ForegroundColor Green " `n DEB package is created at $finalDebPath "
1904+ }
1905+ }
1906+
17821907function Build-DscMsixPackage {
17831908 [CmdletBinding ()]
17841909 param (
@@ -1980,6 +2105,121 @@ function Build-DscMsixPackage {
19802105 }
19812106}
19822107
2108+ function Build-DscRpmPackage {
2109+ [CmdletBinding ()]
2110+ param (
2111+ [DscProjectBuildData ]$BuildData ,
2112+ [DscArtifactDirectoryPath ]$ArtifactDirectory ,
2113+ [ValidateSet (
2114+ ' current' ,
2115+ ' aarch64-pc-windows-msvc' ,
2116+ ' x86_64-pc-windows-msvc' ,
2117+ ' aarch64-apple-darwin' ,
2118+ ' x86_64-apple-darwin' ,
2119+ ' aarch64-unknown-linux-gnu' ,
2120+ ' aarch64-unknown-linux-musl' ,
2121+ ' x86_64-unknown-linux-gnu' ,
2122+ ' x86_64-unknown-linux-musl'
2123+ )]
2124+ $Architecture = ' current' ,
2125+ [switch ]$Release
2126+ )
2127+
2128+ begin {
2129+ if (! $IsLinux ) {
2130+ throw " RPM package creation is only supported on Linux"
2131+ }
2132+
2133+ # Check if rpmbuild is available
2134+ if ($null -eq (Get-Command rpmbuild - ErrorAction Ignore)) {
2135+ throw " rpmbuild not found. Please install rpm-build package (e.g., 'sudo apt install rpm build-essential' or 'sudo dnf install rpm-build')"
2136+ }
2137+ }
2138+
2139+ process {
2140+ $rpmTarget = Join-Path $PSScriptRoot ' bin' $architecture ' rpm'
2141+ if (Test-Path $rpmTarget ) {
2142+ Remove-Item $rpmTarget - Recurse - ErrorAction Stop - Force
2143+ }
2144+
2145+ New-Item - ItemType Directory $rpmTarget > $null
2146+
2147+ # Create RPM build directories
2148+ $rpmBuildRoot = Join-Path $rpmTarget ' rpmbuild'
2149+ $rpmDirs = @ (' BUILD' , ' RPMS' , ' SOURCES' , ' SPECS' , ' SRPMS' )
2150+ foreach ($dir in $rpmDirs ) {
2151+ New-Item - ItemType Directory - Path (Join-Path $rpmBuildRoot $dir ) - Force > $null
2152+ }
2153+
2154+ # Create a staging directory for the files
2155+ $stagingDir = Join-Path $rpmBuildRoot ' SOURCES' ' dsc_files'
2156+ New-Item - ItemType Directory $stagingDir > $null
2157+
2158+ if ($null -eq $BuildData ) {
2159+ $BuildData = Import-DscBuildData
2160+ }
2161+ $filesForPackage = $BuildData.PackageFiles.Linux
2162+ if ($null -eq $ArtifactDirectory ) {
2163+ $artifactDirectory = Get-ArtifactDirectoryPath - Architecture $Architecture - Release:$Release
2164+ }
2165+ $target = $artifactDirectory.RootTarget
2166+
2167+ foreach ($file in $filesForPackage ) {
2168+ if ((Get-Item " $target \$file " ) -is [System.IO.DirectoryInfo ]) {
2169+ Copy-Item " $target \$file " " $stagingDir \$file " - Recurse - ErrorAction Stop
2170+ } else {
2171+ Copy-Item " $target \$file " $stagingDir - ErrorAction Stop
2172+ }
2173+ }
2174+
2175+ # Determine RPM architecture
2176+ $rpmArch = if ($architecture -eq ' current' ) {
2177+ # Detect current system architecture
2178+ $currentArch = uname - m
2179+ if ($currentArch -eq ' x86_64' ) {
2180+ ' x86_64'
2181+ } elseif ($currentArch -eq ' aarch64' ) {
2182+ ' aarch64'
2183+ } else {
2184+ throw " Unsupported current architecture for RPM: $currentArch "
2185+ }
2186+ } elseif ($architecture -eq ' aarch64-unknown-linux-musl' -or $architecture -eq ' aarch64-unknown-linux-gnu' ) {
2187+ ' aarch64'
2188+ } elseif ($architecture -eq ' x86_64-unknown-linux-musl' -or $architecture -eq ' x86_64-unknown-linux-gnu' ) {
2189+ ' x86_64'
2190+ } else {
2191+ throw " Unsupported architecture for RPM: $architecture "
2192+ }
2193+
2194+ # Read the spec template and replace placeholders
2195+ $specTemplate = Get-Content " $PSScriptRoot /packaging/rpm/dsc.spec" - Raw
2196+ $productVersion = Get-DscCliVersion
2197+ $specContent = $specTemplate.Replace (' VERSION_PLACEHOLDER' , $productVersion.Replace (' -' , ' ~' )).Replace(' ARCH_PLACEHOLDER' , $rpmArch )
2198+ $specFile = Join-Path $rpmBuildRoot ' SPECS' ' dsc.spec'
2199+ Set-Content - Path $specFile - Value $specContent
2200+
2201+ Write-Verbose - Verbose " Building RPM package"
2202+ # Build the RPM
2203+ rpmbuild - v - bb -- define " _topdir $rpmBuildRoot " -- buildroot " $rpmBuildRoot /BUILDROOT" $specFile 2>&1 > $rpmTarget / rpmbuild.log
2204+
2205+ if ($LASTEXITCODE -ne 0 ) {
2206+ Write-Error (Get-Content $rpmTarget / rpmbuild.log - Raw)
2207+ throw " Failed to create RPM package"
2208+ }
2209+
2210+ # Copy the RPM to the bin directory
2211+ $builtRpm = Get-ChildItem - Path (Join-Path $rpmBuildRoot ' RPMS' ) - Recurse - Filter ' *.rpm' | Select-Object - First 1
2212+ if ($null -eq $builtRpm ) {
2213+ throw " RPM package was not created"
2214+ }
2215+
2216+ $finalRpmPath = Join-Path $PSScriptRoot ' bin' $builtRpm.Name
2217+ Copy-Item $builtRpm.FullName $finalRpmPath - Force
2218+
2219+ Write-Host - ForegroundColor Green " `n RPM package is created at $finalRpmPath "
2220+ }
2221+ }
2222+
19832223function Build-DscZipPackage {
19842224 [CmdletBinding ()]
19852225 param (
@@ -2142,9 +2382,11 @@ function Build-DscPackage {
21422382 param (
21432383 [DscProjectBuildData ]$BuildData ,
21442384 [ValidateSet (
2385+ ' deb' ,
21452386 ' msix' ,
21462387 ' msix-private' ,
21472388 ' msixbundle' ,
2389+ ' rpm' ,
21482390 ' tgz' ,
21492391 ' zip'
21502392 )]
@@ -2182,14 +2424,25 @@ function Build-DscPackage {
21822424
21832425 process {
21842426 Write-Verbose " Packaging DSC..."
2185- if ($packageType -match ' msix' ) {
2186- Build-DscMsixPackage @buildParams - PackageType $packageType - UseX64MakeAppx:$UseX64MakeAppx
2187- } elseif ($packageType -eq ' tgz' ) {
2188- Build-DscTgzPackage @buildParams
2189- } elseif ($packageType -eq ' zip' ) {
2190- Build-DscZipPackage @buildParams
2191- } else {
2192- throw " Unhandled package type '$packageType '"
2427+ switch ($packageType ) {
2428+ ' deb' {
2429+ Build-DscDebPackage @buildParams
2430+ }
2431+ {$_ -in @ (' msix' , ' msix-private' , ' msixbundle' )} {
2432+ Build-DscMsixPackage @buildParams - PackageType $packageType - UseX64MakeAppx:$UseX64MakeAppx
2433+ }
2434+ ' rpm' {
2435+ Build-DscRpmPackage @buildParams
2436+ }
2437+ ' tgz' {
2438+ Build-DscTgzPackage @buildParams
2439+ }
2440+ ' zip' {
2441+ Build-DscZipPackage @buildParams
2442+ }
2443+ default {
2444+ throw " Unhandled package type '$packageType '"
2445+ }
21932446 }
21942447 }
21952448}
0 commit comments