Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
81 changes: 81 additions & 0 deletions tools/build/build-installer.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
param (
[string]$Platform = 'arm64',
[string]$Configuration = 'Release'
)

$repoRoot = Resolve-Path "$PSScriptRoot\..\.."
Set-Location $repoRoot

function RunMSBuild {
param (
[string]$Solution,
[string]$ExtraArgs
)

$base = @(
$Solution
"/p:Platform=`"$Platform`""
"/p:Configuration=$Configuration"
'/verbosity:normal'
'/clp:Summary;PerformanceSummary;ErrorsOnly;WarningsOnly'
Comment thread Fixed
'/nologo'
Comment thread Fixed
)

$cmd = $base + ($ExtraArgs -split ' ')
Write-Host ("[MSBUILD] {0} {1}" -f $Solution, ($cmd -join ' '))
& msbuild.exe @cmd

if ($LASTEXITCODE -ne 0) {
Write-Error ("Build failed: {0} {1}" -f $Solution, $ExtraArgs)
exit $LASTEXITCODE
}

}

function RestoreThenBuild {
param ([string]$Solution)

# 1) restore
RunMSBuild $Solution '/t:restore /p:RestorePackagesConfig=true'
# 2) build -------------------------------------------------
RunMSBuild $Solution '/m'
}

Write-Host ("[PIPELINE] Start | Platform={0} Configuration={1}" -f $Platform, $Configuration)
Write-Host ''

$cmdpalOutputPath = Join-Path $repoRoot "$Platform\$Configuration\WinUI3Apps\CmdPal"

if (Test-Path $cmdpalOutputPath) {
Write-Host "[CLEAN] Removing previous output: $cmdpalOutputPath"
Remove-Item $cmdpalOutputPath -Recurse -Force -ErrorAction Ignore
}

RestoreThenBuild '.\PowerToys.sln'

$msixSearchRoot = Join-Path $repoRoot "$Platform\$Configuration"
$msixFiles = Get-ChildItem -Path $msixSearchRoot -Recurse -Filter *.msix |
Select-Object -ExpandProperty FullName

if ($msixFiles.Count) {
Write-Host ("[SIGN] {0} .msix file(s)" -f $msixFiles.Count)
& "$PSScriptRoot\cert-sign-package.ps1" -TargetPaths $msixFiles
}
else {
Write-Warning "[SIGN] No .msix files found in $msixSearchRoot"
}


RestoreThenBuild '.\tools\BugReportTool\BugReportTool.sln'
RestoreThenBuild '.\tools\StylesReportTool\StylesReportTool.sln'

Write-Host '[CLEAN] installer (keep *.exe)'
git clean -xfd -e '*.exe' -- .\installer\ | Out-Null

RestoreThenBuild '.\installer\PowerToysSetup.sln'

RunMSBuild '.\installer\PowerToysSetup.sln' '/m /t:PowerToysInstaller'

RunMSBuild '.\installer\PowerToysSetup.sln' '/m /t:PowerToysBootstrapper'

Write-Host '[PIPELINE] Completed'
36 changes: 36 additions & 0 deletions tools/build/cert-management.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
param (
[string]$certSubject = "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
[string[]]$TargetPaths
)

. "$PSScriptRoot\cert-management.ps1"
$cert = EnsureCertificate -certSubject $certSubject

if (-not $cert) {
Write-Error "❌ Failed to prepare certificate."
exit 1
}

Write-Host "✔️ Certificate ready: $($cert.Thumbprint)"

if (-not $TargetPaths -or $TargetPaths.Count -eq 0) {
Write-Error "❌ No target files provided to sign."
exit 1
}

foreach ($filePath in $TargetPaths) {
if (-not (Test-Path $filePath)) {
Write-Warning "⚠️ Skipping: File does not exist - $filePath"
continue
}

Write-Host "🔏 Signing: $filePath"
try {
& signtool sign /sha1 $($cert.Thumbprint) /fd SHA256 /t http://timestamp.digicert.com "$filePath"
}
catch {
Write-Host "Signing file: $($file.FullName)"
}
}

Write-Host "`n✅ Signing process completed."
36 changes: 36 additions & 0 deletions tools/build/cert-sign-package.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
param (
[string]$certSubject = "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US",
[string[]]$TargetPaths
)

. "$PSScriptRoot\cert-management.ps1"
$cert = EnsureCertificate -certSubject $certSubject

if (-not $cert) {
Write-Error "❌ Failed to prepare certificate."
exit 1
}

Write-Host "✔️ Certificate ready: $($cert.Thumbprint)"

if (-not $TargetPaths -or $TargetPaths.Count -eq 0) {
Write-Error "❌ No target files provided to sign."
exit 1
}

foreach ($filePath in $TargetPaths) {
if (-not (Test-Path $filePath)) {
Write-Warning "⚠️ Skipping: File does not exist - $filePath"
continue
}

Write-Host "🔏 Signing: $filePath"
try {
& signtool sign /sha1 $($cert.Thumbprint) /fd SHA256 /t http://timestamp.digicert.com "$filePath"
}
catch {
Write-Host "Signing file: $($file.FullName)"
}
}

Write-Host "`n✅ Signing process completed."