Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 25 additions & 6 deletions .pipelines/DSC-Official.yml
Original file line number Diff line number Diff line change
Expand Up @@ -236,13 +236,17 @@ extends:
ob_restore_phase: true
- pwsh: |
apt update
apt -y install musl-tools
apt -y install musl-tools rpm dpkg build-essential
$header = "Bearer $(AzToken)"
$env:CARGO_REGISTRIES_POWERSHELL_TOKEN = $header
$env:CARGO_REGISTRIES_POWERSHELL_CREDENTIAL_PROVIDER = 'cargo:token'
./build.ps1 -Release -Architecture x86_64-unknown-linux-musl
./build.ps1 -PackageType tgz -Architecture x86_64-unknown-linux-musl -Release
./build.ps1 -PackageType rpm -Architecture x86_64-unknown-linux-musl -Release
./build.ps1 -PackageType deb -Architecture x86_64-unknown-linux-musl -Release
Copy-Item ./bin/*.tar.gz "$(ob_outputDirectory)"
Copy-Item ./bin/*.rpm "$(ob_outputDirectory)"
Copy-Item ./bin/*.deb "$(ob_outputDirectory)"
displayName: 'Build x86_64-unknown-linux-musl'
condition: succeeded()

Expand Down Expand Up @@ -289,6 +293,9 @@ extends:
#apt -y install gcc-multilib
apt -y install libssl-dev
apt -y install pkg-config
apt -y install rpm
apt -y install dpkg
apt -y install build-essential
msrustup default stable-aarch64-unknown-linux-musl
if ((openssl version -d) -match 'OPENSSLDIR: "(?<dir>.*?)"') {
$env:OPENSSL_LIB_DIR = $matches['dir']
Expand All @@ -298,7 +305,11 @@ extends:
$env:CARGO_REGISTRIES_POWERSHELL_CREDENTIAL_PROVIDER = 'cargo:token'
./build.ps1 -Release -Architecture aarch64-unknown-linux-musl
./build.ps1 -PackageType tgz -Architecture aarch64-unknown-linux-musl -Release
./build.ps1 -PackageType rpm -Architecture aarch64-unknown-linux-musl -Release
./build.ps1 -PackageType deb -Architecture aarch64-unknown-linux-musl -Release
Copy-Item ./bin/*.tar.gz "$(ob_outputDirectory)"
Copy-Item ./bin/*.rpm "$(ob_outputDirectory)"
Copy-Item ./bin/*.deb "$(ob_outputDirectory)"
displayName: 'Build aarch64-unknown-linux-musl'
condition: succeeded()

Expand Down Expand Up @@ -370,11 +381,17 @@ extends:

- download: current
artifact: drop_BuildAndSign_BuildLinuxArm64Musl
patterns: '*.tar.gz'
patterns: |
*.tar.gz
*.rpm
*.deb

- download: current
artifact: drop_BuildAndSign_BuildLinuxMusl
patterns: '*.tar.gz'
patterns: |
*.tar.gz
*.rpm
*.deb

- download: current
artifact: release ## this includes artifacts for macOS
Expand All @@ -385,7 +402,7 @@ extends:
patterns: '*.msixbundle'

- pwsh: |
Get-ChildItem "$(Pipeline.Workspace)" -Recurse -Include '*.zip', '*.tar.gz', '*.msixbundle' | ForEach-Object {
Get-ChildItem "$(Pipeline.Workspace)" -Recurse -Include '*.zip', '*.tar.gz', '*.msixbundle', '*.rpm', '*.deb' | ForEach-Object {
Write-Host "Found artifact: $($_.FullName)"
}
displayName: List downloaded artifacts
Expand All @@ -398,7 +415,7 @@ extends:

Write-Verbose -Verbose "Starting to copy"

Get-ChildItem "$(Pipeline.Workspace)" -Recurse -Include '*.zip', '*.tar.gz', '*.msixbundle' | ForEach-Object {
Get-ChildItem "$(Pipeline.Workspace)" -Recurse -Include '*.zip', '*.tar.gz', '*.msixbundle', '*.rpm', '*.deb' | ForEach-Object {
Copy-Item -Path $_.FullName -Destination $outputDir -Force -Verbose
}

Expand Down Expand Up @@ -448,7 +465,7 @@ extends:
script: |
Write-Verbose -Verbose "Release version: $(PackageVersion)"

$artifacts = Get-ChildItem "$(Pipeline.Workspace)" -Recurse -Include '*.zip', '*.tar.gz', '*.msixbundle'
$artifacts = Get-ChildItem "$(Pipeline.Workspace)" -Recurse -Include '*.zip', '*.tar.gz', '*.msixbundle', '*.rpm', '*.deb'

$artifacts | ForEach-Object {
Write-Verbose -Verbose "Found artifact: $($_.FullName)"
Expand Down Expand Up @@ -489,6 +506,8 @@ extends:
$(GitHubReleaseDirectory)\*.zip
$(GitHubReleaseDirectory)\*.tar.gz
$(GitHubReleaseDirectory)\*.msixbundle
$(GitHubReleaseDirectory)\*.rpm
$(GitHubReleaseDirectory)\*.deb
addChangeLog: false
tagSource: 'userSpecifiedTag'
tag: '$(GitHubReleaseVersion)'
Expand Down
172 changes: 171 additions & 1 deletion build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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','deb')]
$packageType,
[switch]$Test,
[switch]$GetPackageVersion,
Expand Down Expand Up @@ -857,6 +857,176 @@ 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 install rpm build-essential' 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 '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'
} 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('-','~')).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 -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"
}

# 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"
} 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 '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'
} 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 2>&1 > $debTarget/debbuild.log

if ($LASTEXITCODE -ne 0) {
Write-Error (Get-Content $debTarget/debbuild.log -Raw)
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
12 changes: 12 additions & 0 deletions packaging/deb/control
Original file line number Diff line number Diff line change
@@ -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.
38 changes: 38 additions & 0 deletions packaging/rpm/dsc.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
Name: dsc
Version: VERSION_PLACEHOLDER
Release: 1
Summary: DesiredStateConfiguration 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 $RPM_BUILD_ROOT/opt/dsc
mkdir -p $RPM_BUILD_ROOT/usr/bin

# Copy all files from the source directory
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 $RPM_BUILD_ROOT/usr/bin/dsc

%files
/opt/dsc/*
/usr/bin/dsc

%changelog
* Wed Oct 22 2025 Microsoft Corporation
- Initial RPM package release