Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
57 changes: 30 additions & 27 deletions tools/Build-Installer.ps1
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
<#
.SYNOPSIS
Builds the SoundSwitch installer from a local build or downloaded release.
Builds the SoundSwitch installer from a local build or pre-populated Final\ directory.

.DESCRIPTION
This script automates the full installer build process:

1. If -DownloadRelease is set, downloads the latest release artifact using
tools\Download-Release.ps1 into the Final\ directory.
2. Otherwise, builds the SoundSwitch binaries from source using dotnet publish.
3. Generates HTML documentation from Markdown sources (Changelog, README, Terms).
4. Bundles additional assets (images, licenses).
5. Optionally signs binaries and the final installer with tools\Sign-Binary.ps1.
6. Compiles the Inno Setup installer.
1. Builds the SoundSwitch binaries from source using dotnet publish (or
skips this step when -SkipBuild is set, assuming Final\ is already
populated — e.g. by Publish-Release.ps1).
2. Generates HTML documentation from Markdown sources (Changelog, README, Terms).
3. Bundles additional assets (images, licenses).
4. Optionally signs binaries and the final installer with tools\Sign-Binary.ps1.
5. Compiles the Inno Setup installer.

This is the PowerShell replacement for the local build workflow. It requires
the tools from Install-BuildTools.ps1 (Inno Setup, Python with markdown, and
optionally signtool + Certum SimplySign for code signing).
This script is focused exclusively on building and code signing. It does
not interact with GitHub releases — use Publish-Release.ps1 for the full
release workflow (download draft, build installer, upload, publish).

Requires PowerShell 7+ (ships with Windows 11).

.PARAMETER Configuration
Build configuration: Release (default) or Debug.

.PARAMETER DownloadRelease
When set, downloads a pre-built release instead of building from source.

.PARAMETER Channel
Release channel when downloading: 'release' (default) or 'beta'.
Only used when -DownloadRelease is set.
.PARAMETER SkipBuild
When set, skips the dotnet build/publish step and assumes the Final\
directory is already populated with binaries (e.g. extracted from a
downloaded release artifact).

.PARAMETER SkipSigning
Skip code signing even when signtool is available.
Expand All @@ -44,23 +42,22 @@
Builds from source (Release config) and creates the installer.

.EXAMPLE
.\tools\Build-Installer.ps1 -DownloadRelease -Channel beta
Downloads the latest beta release and builds the installer from it.
.\tools\Build-Installer.ps1 -SkipBuild
Builds the installer from an already-populated Final\ directory.

.EXAMPLE
.\tools\Build-Installer.ps1 -SkipSigning -InstallerReleaseState Nightly
Builds from source without signing, using "Nightly" label for installer.
#>

#Requires -Version 7.0

[CmdletBinding()]
param(
[ValidateSet('Release', 'Debug')]
[string]$Configuration = 'Release',

[switch]$DownloadRelease,

[ValidateSet('release', 'beta')]
[string]$Channel = 'release',
[switch]$SkipBuild,

[switch]$SkipSigning,

Expand Down Expand Up @@ -93,10 +90,16 @@ Write-Host "Detected target framework: $framework" -ForegroundColor Cyan

# ── Step 1: Populate Final\ ─────────────────────────────────────────────────

if ($DownloadRelease) {
Write-Host "`n=== Downloading release artifact ($Channel) ===" -ForegroundColor White
$downloadScript = Join-Path $PSScriptRoot 'Download-Release.ps1'
& $downloadScript -Channel $Channel -OutputDir $finalDir
if ($SkipBuild) {
Write-Host "`n=== Using pre-populated Final\ directory ===" -ForegroundColor White
if (-not (Test-Path $finalDir)) {
throw "Final\ directory not found at $finalDir. Use -SkipBuild only when binaries are already extracted there (e.g. by Publish-Release.ps1)."
}
$fileCount = (Get-ChildItem $finalDir -File -ErrorAction SilentlyContinue).Count
if ($fileCount -eq 0) {
throw "Final\ directory at $finalDir is empty. Populate it with binaries before using -SkipBuild."
Comment thread
Belphemur marked this conversation as resolved.
Outdated
}
Write-Host " Found $fileCount files in $finalDir"
}
else {
Write-Host "`n=== Building from source ($Configuration) ===" -ForegroundColor White
Expand Down
166 changes: 0 additions & 166 deletions tools/Download-Release.ps1

This file was deleted.

54 changes: 54 additions & 0 deletions tools/Install-BuildTools.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -461,4 +461,58 @@ Describe 'Install-BuildTools.ps1 script' {
Get-Command Install-SignToolFromGitHub -ErrorAction SilentlyContinue | Should -Not -BeNullOrEmpty
Get-Command Install-SignTool -ErrorAction SilentlyContinue | Should -Not -BeNullOrEmpty
}

It 'installs GitHub CLI as the first package' {
$scriptPath = Join-Path $PSScriptRoot 'Install-BuildTools.ps1'
$content = Get-Content $scriptPath -Raw
# GitHub CLI should be installed before Inno Setup
$ghIndex = $content.IndexOf("'GitHub.cli'")
$innoIndex = $content.IndexOf("'JRSoftware.InnoSetup'")
$ghIndex | Should -BeGreaterThan -1
$innoIndex | Should -BeGreaterThan -1
$ghIndex | Should -BeLessThan $innoIndex
Comment thread
Belphemur marked this conversation as resolved.
Outdated
}
}

# ─────────────────────────────────────────────────────────────────────────────
# Publish-Release.ps1 parse validation
# ─────────────────────────────────────────────────────────────────────────────
Describe 'Publish-Release.ps1 script' {
It 'has no parse errors' {
$scriptPath = Join-Path $PSScriptRoot 'Publish-Release.ps1'
$tokens = $null
$errors = $null
$null = [System.Management.Automation.Language.Parser]::ParseFile(
$scriptPath, [ref]$tokens, [ref]$errors
)
$errors.Count | Should -Be 0
}

It 'contains a #Requires -Version 7.0 directive' {
$scriptPath = Join-Path $PSScriptRoot 'Publish-Release.ps1'
$content = Get-Content $scriptPath -Raw
$content | Should -Match '#Requires\s+-Version\s+7\.0'
}
}

# ─────────────────────────────────────────────────────────────────────────────
# Build-Installer.ps1 parse validation
# ─────────────────────────────────────────────────────────────────────────────
Describe 'Build-Installer.ps1 script' {
It 'has no parse errors' {
$scriptPath = Join-Path $PSScriptRoot 'Build-Installer.ps1'
$tokens = $null
$errors = $null
$null = [System.Management.Automation.Language.Parser]::ParseFile(
$scriptPath, [ref]$tokens, [ref]$errors
)
$errors.Count | Should -Be 0
}

It 'has -SkipBuild parameter instead of -DownloadRelease' {
$scriptPath = Join-Path $PSScriptRoot 'Build-Installer.ps1'
$content = Get-Content $scriptPath -Raw
$content | Should -Match '\$SkipBuild'
$content | Should -Not -Match '\$DownloadRelease'
}
}
12 changes: 8 additions & 4 deletions tools/Install-BuildTools.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -276,20 +276,23 @@ if (-not (Test-CommandExists 'winget')) {

# ── Install packages ─────────────────────────────────────────────────────────

# 1. Inno Setup 6 — installer compiler
# 1. GitHub CLI — used by Publish-Release.ps1 to interact with GitHub releases
Install-WingetPackage -Id 'GitHub.cli' -Name 'GitHub CLI' -Scope $Scope

# 2. Inno Setup 6 — installer compiler
Install-WingetPackage -Id 'JRSoftware.InnoSetup' -Name 'Inno Setup 6' -Scope $Scope

# 2. Certum SimplySign Desktop — cloud certificate provider used for code signing
# 3. Certum SimplySign Desktop — cloud certificate provider used for code signing
Install-WingetPackage -Id 'Certum.SmartSignSimplySignDesktop' -Name 'Certum SimplySign Desktop' -Scope $Scope

# 3. signtool.exe — used by Sign-Binary.ps1/Build-Installer.ps1 (with the
# 4. signtool.exe — used by Sign-Binary.ps1/Build-Installer.ps1 (with the
# Certum certificate) to sign executables and the installer.
# Located from an existing Windows Kits installation, downloaded from
# Delphier/SignTool on GitHub, or the full Windows SDK is installed
# via winget as a last resort.
Install-SignTool

# 4. Python 3 — used for markdown-to-HTML documentation generation
# 5. Python 3 — used for markdown-to-HTML documentation generation
Install-WingetPackage -Id 'Python.Python.3.14' -Name 'Python 3.14' -Scope $Scope

# ── Post-install: Python markdown package ────────────────────────────────────
Expand Down Expand Up @@ -322,6 +325,7 @@ Write-Host "`n=================================" -ForegroundColor White
Write-Host "All build tools installed successfully!" -ForegroundColor Green
Write-Host ""
Write-Host "Installed tools:"
Write-Host " - GitHub CLI (used by Publish-Release.ps1 for release management)"
Write-Host " - Inno Setup 6 (installer compiler)"
Write-Host " - Certum SimplySign Desktop (cloud certificate provider for code signing)"
Write-Host " - signtool.exe (used by Sign-Binary.ps1 for signing)"
Expand Down
Loading
Loading