From cd59cfbacf171ec8afbf0df50636eca9f17f9914 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 18:08:44 +0000 Subject: [PATCH 1/9] Initial plan From b23263ec491454ec118aed827e6cbf4561a38a9d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 18:13:27 +0000 Subject: [PATCH 2/9] Add RPM package support to build.ps1 and create spec file Co-authored-by: SteveL-MSFT <11859881+SteveL-MSFT@users.noreply.github.com> --- build.ps1 | 75 +++++++++++++++++++++++++++++++++++++++++- packaging/rpm/dsc.spec | 38 +++++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 packaging/rpm/dsc.spec diff --git a/build.ps1 b/build.ps1 index bb22c7420..cd51cac81 100755 --- a/build.ps1 +++ b/build.ps1 @@ -9,7 +9,7 @@ param( $architecture = 'current', [switch]$Clippy, [switch]$SkipBuild, - [ValidateSet('msix','msix-private','msixbundle','tgz','zip')] + [ValidateSet('msix','msix-private','msixbundle','tgz','zip','rpm')] $packageType, [switch]$Test, [switch]$GetPackageVersion, @@ -863,6 +863,79 @@ if ($packageType -eq 'msixbundle') { } Write-Host -ForegroundColor Green "`ntar.gz file is created at $tarFile" +} elseif ($packageType -eq 'rpm') { + if (!$IsLinux) { + throw "RPM package creation is only supported on Linux" + } + + # Check if rpmbuild is available + if ($null -eq (Get-Command rpmbuild -ErrorAction Ignore)) { + throw "rpmbuild not found. Please install rpm-build package (e.g., 'sudo apt-get install rpm' or 'sudo dnf install rpm-build')" + } + + $rpmTarget = Join-Path $PSScriptRoot 'bin' $architecture 'rpm' + if (Test-Path $rpmTarget) { + Remove-Item $rpmTarget -Recurse -ErrorAction Stop -Force + } + + New-Item -ItemType Directory $rpmTarget > $null + + # Create RPM build directories + $rpmBuildRoot = Join-Path $rpmTarget 'rpmbuild' + $rpmDirs = @('BUILD', 'RPMS', 'SOURCES', 'SPECS', 'SRPMS') + foreach ($dir in $rpmDirs) { + New-Item -ItemType Directory -Path (Join-Path $rpmBuildRoot $dir) -Force > $null + } + + # Create a staging directory for the files + $stagingDir = Join-Path $rpmBuildRoot 'SOURCES' 'dsc_files' + New-Item -ItemType Directory $stagingDir > $null + + $filesForPackage = $filesForLinuxPackage + + foreach ($file in $filesForPackage) { + if ((Get-Item "$target\$file") -is [System.IO.DirectoryInfo]) { + Copy-Item "$target\$file" "$stagingDir\$file" -Recurse -ErrorAction Stop + } else { + Copy-Item "$target\$file" $stagingDir -ErrorAction Stop + } + } + + # Determine RPM architecture + $rpmArch = if ($architecture -eq 'aarch64-unknown-linux-musl' -or $architecture -eq 'aarch64-unknown-linux-gnu') { + 'aarch64' + } elseif ($architecture -eq 'x86_64-unknown-linux-musl' -or $architecture -eq 'x86_64-unknown-linux-gnu') { + 'x86_64' + } else { + throw "Unsupported architecture for RPM: $architecture" + } + + # Read the spec template and replace placeholders + $specTemplate = Get-Content "$PSScriptRoot/packaging/rpm/dsc.spec" -Raw + $specContent = $specTemplate.Replace('VERSION_PLACEHOLDER', $productVersion).Replace('ARCH_PLACEHOLDER', $rpmArch) + $specFile = Join-Path $rpmBuildRoot 'SPECS' 'dsc.spec' + Set-Content -Path $specFile -Value $specContent + + Write-Verbose -Verbose "Building RPM package" + $rpmPackageName = "dsc-$productVersion-1.$rpmArch.rpm" + + # Build the RPM + rpmbuild -bb --define "_topdir $rpmBuildRoot" $specFile + + if ($LASTEXITCODE -ne 0) { + throw "Failed to create RPM package" + } + + # Copy the RPM to the bin directory + $builtRpm = Get-ChildItem -Path (Join-Path $rpmBuildRoot 'RPMS') -Recurse -Filter '*.rpm' | Select-Object -First 1 + if ($null -eq $builtRpm) { + throw "RPM package was not created" + } + + $finalRpmPath = Join-Path $PSScriptRoot 'bin' $builtRpm.Name + Copy-Item $builtRpm.FullName $finalRpmPath -Force + + Write-Host -ForegroundColor Green "`nRPM package is created at $finalRpmPath" } $env:RUST_BACKTRACE=1 diff --git a/packaging/rpm/dsc.spec b/packaging/rpm/dsc.spec new file mode 100644 index 000000000..97774c7de --- /dev/null +++ b/packaging/rpm/dsc.spec @@ -0,0 +1,38 @@ +Name: dsc +Version: VERSION_PLACEHOLDER +Release: 1 +Summary: Desired State Configuration v3 +License: MIT +URL: https://github.com/PowerShell/DSC +BuildArch: ARCH_PLACEHOLDER + +%description +DSCv3 is the latest iteration of Microsoft's Desired State Configuration platform. +DSCv3 is an open source command line application that abstracts the management of +software components declaratively and idempotently. DSCv3 runs on Linux, macOS, +and Windows without any external dependencies. + +%prep +# No prep needed - files are already built + +%build +# No build needed - binary is already compiled + +%install +# Create installation directories +mkdir -p %{buildroot}/opt/dsc +mkdir -p %{buildroot}/usr/bin + +# Copy all files from the source directory +cp -r %{_sourcedir}/dsc_files/* %{buildroot}/opt/dsc/ + +# Create symlink to make dsc available in PATH +ln -s /opt/dsc/dsc %{buildroot}/usr/bin/dsc + +%files +/opt/dsc/* +/usr/bin/dsc + +%changelog +* Thu Oct 22 2025 Microsoft Corporation +- Initial RPM package release From a3d7cff7ee18cef6596eae0258575e391e88f9b3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 18:15:05 +0000 Subject: [PATCH 3/9] Replace RPM macros with environment variables to avoid RedHat-specific dependencies Co-authored-by: SteveL-MSFT <11859881+SteveL-MSFT@users.noreply.github.com> --- packaging/rpm/dsc.spec | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packaging/rpm/dsc.spec b/packaging/rpm/dsc.spec index 97774c7de..e0395e4cf 100644 --- a/packaging/rpm/dsc.spec +++ b/packaging/rpm/dsc.spec @@ -20,14 +20,14 @@ and Windows without any external dependencies. %install # Create installation directories -mkdir -p %{buildroot}/opt/dsc -mkdir -p %{buildroot}/usr/bin +mkdir -p $RPM_BUILD_ROOT/opt/dsc +mkdir -p $RPM_BUILD_ROOT/usr/bin # Copy all files from the source directory -cp -r %{_sourcedir}/dsc_files/* %{buildroot}/opt/dsc/ +cp -r $RPM_SOURCE_DIR/dsc_files/* $RPM_BUILD_ROOT/opt/dsc/ # Create symlink to make dsc available in PATH -ln -s /opt/dsc/dsc %{buildroot}/usr/bin/dsc +ln -s /opt/dsc/dsc $RPM_BUILD_ROOT/usr/bin/dsc %files /opt/dsc/* From 4b5d5028b8c1b95bc160649f3354cae5ffa1911e Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Wed, 22 Oct 2025 11:22:15 -0700 Subject: [PATCH 4/9] Update packaging/rpm/dsc.spec Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- packaging/rpm/dsc.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/rpm/dsc.spec b/packaging/rpm/dsc.spec index e0395e4cf..d2325b9c5 100644 --- a/packaging/rpm/dsc.spec +++ b/packaging/rpm/dsc.spec @@ -34,5 +34,5 @@ ln -s /opt/dsc/dsc $RPM_BUILD_ROOT/usr/bin/dsc /usr/bin/dsc %changelog -* Thu Oct 22 2025 Microsoft Corporation +* Wed Oct 22 2025 Microsoft Corporation - Initial RPM package release From 16de94306f8c0f28b25f997764ee468a53b8a076 Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Wed, 22 Oct 2025 11:22:22 -0700 Subject: [PATCH 5/9] Update packaging/rpm/dsc.spec --- packaging/rpm/dsc.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/rpm/dsc.spec b/packaging/rpm/dsc.spec index d2325b9c5..06fde7bc7 100644 --- a/packaging/rpm/dsc.spec +++ b/packaging/rpm/dsc.spec @@ -1,7 +1,7 @@ Name: dsc Version: VERSION_PLACEHOLDER Release: 1 -Summary: Desired State Configuration v3 +Summary: DesiredStateConfiguration v3 License: MIT URL: https://github.com/PowerShell/DSC BuildArch: ARCH_PLACEHOLDER From f55bb83f95bed2f24d9e2c25e88ced132352ec9c Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Wed, 22 Oct 2025 11:37:06 -0700 Subject: [PATCH 6/9] Update build.ps1 --- build.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.ps1 b/build.ps1 index cd51cac81..19a7766db 100755 --- a/build.ps1 +++ b/build.ps1 @@ -870,7 +870,7 @@ if ($packageType -eq 'msixbundle') { # Check if rpmbuild is available if ($null -eq (Get-Command rpmbuild -ErrorAction Ignore)) { - throw "rpmbuild not found. Please install rpm-build package (e.g., 'sudo apt-get install rpm' or 'sudo dnf install rpm-build')" + throw "rpmbuild not found. Please install rpm-build package (e.g., 'sudo apt install rpm build-essential' or 'sudo dnf install rpm-build')" } $rpmTarget = Join-Path $PSScriptRoot 'bin' $architecture 'rpm' From 03a0eb09256045efc5ed21ad06904f8164f402bb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 22:26:16 +0000 Subject: [PATCH 7/9] Add DEB package support to build system Co-authored-by: SteveL-MSFT <11859881+SteveL-MSFT@users.noreply.github.com> --- build.ps1 | 77 ++++++++++++++++++++++++++++++++++++++++++- packaging/deb/control | 12 +++++++ 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 packaging/deb/control diff --git a/build.ps1 b/build.ps1 index 19a7766db..dfdca2b96 100755 --- a/build.ps1 +++ b/build.ps1 @@ -9,7 +9,7 @@ param( $architecture = 'current', [switch]$Clippy, [switch]$SkipBuild, - [ValidateSet('msix','msix-private','msixbundle','tgz','zip','rpm')] + [ValidateSet('msix','msix-private','msixbundle','tgz','zip','rpm','deb')] $packageType, [switch]$Test, [switch]$GetPackageVersion, @@ -936,6 +936,81 @@ if ($packageType -eq 'msixbundle') { Copy-Item $builtRpm.FullName $finalRpmPath -Force Write-Host -ForegroundColor Green "`nRPM package is created at $finalRpmPath" +} elseif ($packageType -eq 'deb') { + if (!$IsLinux) { + throw "DEB package creation is only supported on Linux" + } + + # Check if dpkg-deb is available + if ($null -eq (Get-Command dpkg-deb -ErrorAction Ignore)) { + throw "dpkg-deb not found. Please install dpkg package (e.g., 'sudo apt install dpkg' or 'sudo dnf install dpkg')" + } + + $debTarget = Join-Path $PSScriptRoot 'bin' $architecture 'deb' + if (Test-Path $debTarget) { + Remove-Item $debTarget -Recurse -ErrorAction Stop -Force + } + + New-Item -ItemType Directory $debTarget > $null + + # Create DEB package structure + $debBuildRoot = Join-Path $debTarget 'dsc' + $debDirs = @('DEBIAN', 'opt/dsc', 'usr/bin') + foreach ($dir in $debDirs) { + New-Item -ItemType Directory -Path (Join-Path $debBuildRoot $dir) -Force > $null + } + + # Copy files to the package directory + $filesForPackage = $filesForLinuxPackage + $stagingDir = Join-Path $debBuildRoot 'opt' 'dsc' + + foreach ($file in $filesForPackage) { + if ((Get-Item "$target\$file") -is [System.IO.DirectoryInfo]) { + Copy-Item "$target\$file" "$stagingDir\$file" -Recurse -ErrorAction Stop + } else { + Copy-Item "$target\$file" $stagingDir -ErrorAction Stop + } + } + + # Create symlink in usr/bin + $symlinkPath = Join-Path $debBuildRoot 'usr' 'bin' 'dsc' + New-Item -ItemType SymbolicLink -Path $symlinkPath -Target '/opt/dsc/dsc' -Force > $null + + # Determine DEB architecture + $debArch = if ($architecture -eq 'aarch64-unknown-linux-musl' -or $architecture -eq 'aarch64-unknown-linux-gnu') { + 'arm64' + } elseif ($architecture -eq 'x86_64-unknown-linux-musl' -or $architecture -eq 'x86_64-unknown-linux-gnu') { + 'amd64' + } else { + throw "Unsupported architecture for DEB: $architecture" + } + + # Read the control template and replace placeholders + $controlTemplate = Get-Content "$PSScriptRoot/packaging/deb/control" -Raw + $controlContent = $controlTemplate.Replace('VERSION_PLACEHOLDER', $productVersion).Replace('ARCH_PLACEHOLDER', $debArch) + $controlFile = Join-Path $debBuildRoot 'DEBIAN' 'control' + Set-Content -Path $controlFile -Value $controlContent + + Write-Verbose -Verbose "Building DEB package" + $debPackageName = "dsc_$productVersion-1_$debArch.deb" + + # Build the DEB + dpkg-deb --build $debBuildRoot + + if ($LASTEXITCODE -ne 0) { + throw "Failed to create DEB package" + } + + # Move the DEB to the bin directory with the correct name + $builtDeb = "$debBuildRoot.deb" + if (!(Test-Path $builtDeb)) { + throw "DEB package was not created" + } + + $finalDebPath = Join-Path $PSScriptRoot 'bin' $debPackageName + Move-Item $builtDeb $finalDebPath -Force + + Write-Host -ForegroundColor Green "`nDEB package is created at $finalDebPath" } $env:RUST_BACKTRACE=1 diff --git a/packaging/deb/control b/packaging/deb/control new file mode 100644 index 000000000..fd36329bc --- /dev/null +++ b/packaging/deb/control @@ -0,0 +1,12 @@ +Package: dsc +Version: VERSION_PLACEHOLDER +Section: utils +Priority: optional +Architecture: ARCH_PLACEHOLDER +Maintainer: Microsoft Corporation +Homepage: https://github.com/PowerShell/DSC +Description: DesiredStateConfiguration v3 + DSCv3 is the latest iteration of Microsoft's Desired State Configuration + platform. DSCv3 is an open source command line application that abstracts + the management of software components declaratively and idempotently. + DSCv3 runs on Linux, macOS, and Windows without any external dependencies. From 9833157f657e4226df7a5e812bc5ac710085defa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Oct 2025 22:31:11 +0000 Subject: [PATCH 8/9] Add support for 'current' architecture in RPM and DEB packaging Co-authored-by: SteveL-MSFT <11859881+SteveL-MSFT@users.noreply.github.com> --- build.ps1 | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/build.ps1 b/build.ps1 index dfdca2b96..0b36debd6 100755 --- a/build.ps1 +++ b/build.ps1 @@ -902,7 +902,17 @@ if ($packageType -eq 'msixbundle') { } # Determine RPM architecture - $rpmArch = if ($architecture -eq 'aarch64-unknown-linux-musl' -or $architecture -eq 'aarch64-unknown-linux-gnu') { + $rpmArch = if ($architecture -eq 'current') { + # Detect current system architecture + $currentArch = uname -m + if ($currentArch -eq 'x86_64') { + 'x86_64' + } elseif ($currentArch -eq 'aarch64') { + 'aarch64' + } else { + throw "Unsupported current architecture for RPM: $currentArch" + } + } elseif ($architecture -eq 'aarch64-unknown-linux-musl' -or $architecture -eq 'aarch64-unknown-linux-gnu') { 'aarch64' } elseif ($architecture -eq 'x86_64-unknown-linux-musl' -or $architecture -eq 'x86_64-unknown-linux-gnu') { 'x86_64' @@ -977,7 +987,17 @@ if ($packageType -eq 'msixbundle') { New-Item -ItemType SymbolicLink -Path $symlinkPath -Target '/opt/dsc/dsc' -Force > $null # Determine DEB architecture - $debArch = if ($architecture -eq 'aarch64-unknown-linux-musl' -or $architecture -eq 'aarch64-unknown-linux-gnu') { + $debArch = if ($architecture -eq 'current') { + # Detect current system architecture + $currentArch = uname -m + if ($currentArch -eq 'x86_64') { + 'amd64' + } elseif ($currentArch -eq 'aarch64') { + 'arm64' + } else { + throw "Unsupported current architecture for DEB: $currentArch" + } + } elseif ($architecture -eq 'aarch64-unknown-linux-musl' -or $architecture -eq 'aarch64-unknown-linux-gnu') { 'arm64' } elseif ($architecture -eq 'x86_64-unknown-linux-musl' -or $architecture -eq 'x86_64-unknown-linux-gnu') { 'amd64' From 969ba763d320295a906bd42fe3e47ef06812c4da Mon Sep 17 00:00:00 2001 From: "Steve Lee (POWERSHELL HE/HIM) (from Dev Box)" Date: Wed, 22 Oct 2025 16:24:27 -0700 Subject: [PATCH 9/9] add error handling --- build.ps1 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/build.ps1 b/build.ps1 index 0b36debd6..befa29de3 100755 --- a/build.ps1 +++ b/build.ps1 @@ -922,7 +922,7 @@ if ($packageType -eq 'msixbundle') { # Read the spec template and replace placeholders $specTemplate = Get-Content "$PSScriptRoot/packaging/rpm/dsc.spec" -Raw - $specContent = $specTemplate.Replace('VERSION_PLACEHOLDER', $productVersion).Replace('ARCH_PLACEHOLDER', $rpmArch) + $specContent = $specTemplate.Replace('VERSION_PLACEHOLDER', $productVersion.Replace('-','~')).Replace('ARCH_PLACEHOLDER', $rpmArch) $specFile = Join-Path $rpmBuildRoot 'SPECS' 'dsc.spec' Set-Content -Path $specFile -Value $specContent @@ -930,9 +930,10 @@ if ($packageType -eq 'msixbundle') { $rpmPackageName = "dsc-$productVersion-1.$rpmArch.rpm" # Build the RPM - rpmbuild -bb --define "_topdir $rpmBuildRoot" $specFile + rpmbuild -v -bb --define "_topdir $rpmBuildRoot" --buildroot "$rpmBuildRoot/BUILDROOT" $specFile 2>&1 > $rpmTarget/rpmbuild.log if ($LASTEXITCODE -ne 0) { + Write-Error (Get-Content $rpmTarget/rpmbuild.log -Raw) throw "Failed to create RPM package" } @@ -1015,9 +1016,10 @@ if ($packageType -eq 'msixbundle') { $debPackageName = "dsc_$productVersion-1_$debArch.deb" # Build the DEB - dpkg-deb --build $debBuildRoot + dpkg-deb --build $debBuildRoot 2>&1 > $debTarget/debbuild.log if ($LASTEXITCODE -ne 0) { + Write-Error (Get-Content $debTarget/debbuild.log -Raw) throw "Failed to create DEB package" }