Skip to content
Merged
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
30 changes: 11 additions & 19 deletions .github/workflows/test.yml
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,19 @@
name: Test
permissions:
contents: read
checks: write
pull-requests: write
issues: write
on:
push:
branches: [ $default-branch ]
branches: [ main ]
pull_request:
workflow_dispatch:
jobs:
test:
name: Test
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- uses: actions/checkout@v4
- name: Test
shell: pwsh
env:
DEBUG: ${{ runner.debug == '1' }}
run: |
if($env:DEBUG -eq 'true' -or $env:DEBUG -eq '1') {
$DebugPreference = 'Continue'
}
./build.ps1 -Task Test -Bootstrap
# Delegate to the psake org's shared module CI workflow. It runs the full build/test suite
# (Build + Analyze + Pester) on PowerShell 7+ across Linux/Windows/macOS and on the real
# Windows PowerShell 5.1 (Desktop) engine, so regressions like the 0.8.0 ternary that broke
# module import on 5.1 are caught by the standard test run rather than a separate smoke test.
ci:
name: CI
uses: psake/.github/.github/workflows/ModuleCI.yml@main
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,17 +7,37 @@

## Unreleased

## [0.8.1] 2026-06-03

### Fixed

- Restore Windows PowerShell 5.1 (Desktop edition) compatibility, which regressed
in 0.8.0. `Get-PSBuildCertificate` used the PowerShell 7+-only ternary operator,
causing the file to fail to parse and the whole module to fail to import under
Windows PowerShell 5.1 — even though the manifest still declares support for it.
The ternary is replaced with an `if`/`else` expression, and the `$IsWindows`
platform guard now treats the absent automatic variable on Desktop edition as
Windows (matching the existing pattern in `Build-PSBuildUpdatableHelp`). Behavior
on PowerShell 7+ is unchanged.

### Added

- An `Import smoke (Windows PowerShell 5.1)` CI job that parses and imports the
module on the real lowest-supported engine, so a construct that breaks import on
Windows PowerShell 5.1 (such as a PowerShell 7+-only ternary operator) fails CI
deterministically.

## [0.8.0] 2026-02-20

### Added

- [**#92**](https://github.com/psake/PowerShellBuild/pull/92) Add Authenticode

Check warning on line 34 in CHANGELOG.md

View workflow job for this annotation

GitHub Actions/ CI / Run Linters

Unknown word (Authenticode) Suggestions: (authnetcode, Authnetcode, authnetCode, AuthnetCode, authenticate)
code-signing support for PowerShell modules with three new public functions:
- `Get-PSBuildCertificate` - Resolves code-signing X509Certificate2 objects
from certificate store, PFX files, Base64-encoded environment variables,
or pre-resolved certificate objects
- `Invoke-PSBuildModuleSigning` - Signs PowerShell module files (*.psd1,
*.psm1, *.ps1) with Authenticode signatures supporting configurable

Check warning on line 40 in CHANGELOG.md

View workflow job for this annotation

GitHub Actions/ CI / Run Linters

Unknown word (Authenticode) Suggestions: (authnetcode, Authnetcode, authnetCode, AuthnetCode, authenticate)
timestamp servers and hash algorithms
- `New-PSBuildFileCatalog` - Creates Windows catalog (.cat) files for
tamper detection
Expand DownExpand Up@@ -46,7 +66,7 @@
- The `$PSBPreference` variable now supports the following PlatyPS
`New-MarkdownHelp` and `Update-MarkdownHelp` boolean options:
- `$PSBPreference.Docs.AlphabeticParamsOrder`
- `$PSBPreference.Docs.ExcludeDontShow`

Check warning on line 69 in CHANGELOG.md

View workflow job for this annotation

GitHub Actions/ CI / Run Linters

Unknown word (Dont) Suggestions: (dent, dint, doit, dolt, dona)
- `$PSBPreference.Docs.UseFullTypeName`
- The `$PSBPreference` variable now supports the following Pester test
configuration options:
Expand Down
2 changes: 1 addition & 1 deletion PowerShellBuild/PowerShellBuild.psd1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
@{
RootModule = 'PowerShellBuild.psm1'
ModuleVersion = '0.8.0'
ModuleVersion = '0.8.1'
GUID = '15431eb8-be2d-4154-b8ad-4cb68a488e3d'
Author = 'Brandon Olin'
CompanyName = 'Community'
Expand Down
10 changes: 7 additions & 3 deletions PowerShellBuild/Public/Get-PSBuildCertificate.ps1
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,7 +3,7 @@
.SYNOPSIS
Resolves a code-signing X509Certificate2 from one of several common sources.
.DESCRIPTION
Resolves a code-signing certificate suitable for use with Set-AuthenticodeSignature.

Check warning on line 6 in PowerShellBuild/Public/Get-PSBuildCertificate.ps1

View workflow job for this annotation

GitHub Actions/ CI / Run Linters

Unknown word (Authenticode) Suggestions: (authnetcode, Authnetcode, authnetCode, AuthnetCode, authenticate)
Supports five certificate sources to accommodate local development, CI/CD pipelines,
and custom signing infrastructure:

Expand All@@ -29,7 +29,7 @@
Useful for local scripts, containers, and environments where a
certificate file is mounted or distributed via a secrets manager.

Note: Authenticode signing is a Windows-only capability. This function will fail

Check warning on line 32 in PowerShellBuild/Public/Get-PSBuildCertificate.ps1

View workflow job for this annotation

GitHub Actions/ CI / Run Linters

Unknown word (Authenticode) Suggestions: (authnetcode, Authnetcode, authnetCode, AuthnetCode, authenticate)
on non-Windows platforms when using Store or Thumbprint sources.
.PARAMETER CertificateSource
The source from which to resolve the code-signing certificate.
Expand All@@ -42,10 +42,10 @@
.PARAMETER CertificateEnvVar
Name of the environment variable holding the Base64-encoded PFX certificate.
Used by the EnvVar source and by Auto as the presence-detection key.
Default: SIGNCERTIFICATE.

Check warning on line 45 in PowerShellBuild/Public/Get-PSBuildCertificate.ps1

View workflow job for this annotation

GitHub Actions/ CI / Run Linters

Unknown word (SIGNCERTIFICATE)
.PARAMETER CertificatePasswordEnvVar
Name of the environment variable holding the PFX password. Used by EnvVar source.
Default: CERTIFICATEPASSWORD.

Check warning on line 48 in PowerShellBuild/Public/Get-PSBuildCertificate.ps1

View workflow job for this annotation

GitHub Actions/ CI / Run Linters

Unknown word (CERTIFICATEPASSWORD)
.PARAMETER PfxFilePath
File system path to a PFX/P12 certificate file. Required when CertificateSource is PfxFile.
.PARAMETER PfxFilePassword
Expand All@@ -60,7 +60,7 @@
.EXAMPLE
PS> $cert = Get-PSBuildCertificate

Resolve automatically: use the SIGNCERTIFICATE env var when present, otherwise search

Check warning on line 63 in PowerShellBuild/Public/Get-PSBuildCertificate.ps1

View workflow job for this annotation

GitHub Actions/ CI / Run Linters

Unknown word (SIGNCERTIFICATE)
the current user's certificate store.
.EXAMPLE
PS> $cert = Get-PSBuildCertificate -CertificateSource Store
Expand All@@ -77,7 +77,7 @@
Decode a PFX certificate stored in a CI/CD secret environment variable.
.EXAMPLE
PS> $pass = Read-Host -Prompt 'Certificate password' -AsSecureString
PS> $cert = Get-PSBuildCertificate -CertificateSource PfxFile -PfxFilePath './codesign.pfx' -PfxFilePassword $pass

Check warning on line 80 in PowerShellBuild/Public/Get-PSBuildCertificate.ps1

View workflow job for this annotation

GitHub Actions/ CI / Run Linters

Unknown word (codesign) Suggestions: (codein, cosign, consign, cohesion, codebig)

Load a code-signing certificate from a PFX file on disk.
#>
Expand All@@ -96,7 +96,7 @@

[string]$Thumbprint,

[string]$CertificateEnvVar = 'SIGNCERTIFICATE',

Check warning on line 99 in PowerShellBuild/Public/Get-PSBuildCertificate.ps1

View workflow job for this annotation

GitHub Actions/ CI / Run Linters

Unknown word (SIGNCERTIFICATE)

[string]$CertificatePasswordEnvVar = 'CERTIFICATEPASSWORD',

Expand All@@ -122,8 +122,11 @@

switch ($resolvedSource) {
'Store' {
# Throw if running on a non-Windows platform since the certificate store is not supported
if (-not $IsWindows) {
# Throw if running on a non-Windows platform since the certificate store is not supported.
# $IsWindows does not exist on Windows PowerShell 5.1 (Desktop edition), where it is $null
# and the platform is always Windows; only treat the platform as non-Windows when $IsWindows
# is explicitly $false (PowerShell 7+ on Linux/macOS).
if ($null -ne $IsWindows -and -not $IsWindows) {
throw $LocalizedData.CertificateSourceStoreNotSupported
}
$cert = Get-ChildItem -Path $CertStoreLocation -CodeSigningCert |
Expand DownExpand Up@@ -195,6 +198,7 @@
Write-Verbose "Certificate validation passed: HasPrivateKey=$($cert.HasPrivateKey), NotAfter=$($cert.NotAfter), CodeSigningEKU=Present"
}

Write-Verbose ('Certificate resolution complete: ' + ($cert ? $cert.Subject : 'No certificate found'))
$certSubject = if ($cert) { $cert.Subject } else { 'No certificate found' }
Write-Verbose ('Certificate resolution complete: ' + $certSubject)
$cert
}
2 changes: 1 addition & 1 deletion instructions/repository-specific.instructions.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@ tasks for other PowerShell module projects. It supports two task-runner framewor
- **psake** (4.9.0+)
- **Invoke-Build** (5.8.1+)

- Current version: **0.8.0** (see `PowerShellBuild/PowerShellBuild.psd1`)
- Current version: **0.8.1** (see `PowerShellBuild/PowerShellBuild.psd1`)
- `PowerShellVersion` in the manifest is currently `'3.0'` — almost certainly wrong; under
review in the v1.0.0 roadmap (psake/PowerShellBuild#120)
- Cross-platform: Windows, Linux, macOS (CI matrix in `.github/workflows/test.yml`)
Expand Down
19 changes: 17 additions & 2 deletions psakeFile.ps1
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,8 +33,23 @@ task Analyze -depends Build {
task Pester -depends Build {
Remove-Module $settings.ProjectName -ErrorAction SilentlyContinue -Verbose:$false

$testResultsXml = [IO.Path]::Combine($settings.OutputDir, 'testResults.xml')
$testResults = Invoke-Pester -Path $settings.Tests -Output Detailed -PassThru
# Write the NUnit results to tests/out/testResults.xml so the shared CI workflow can
# upload and publish them (its artifact step looks for ./tests/out/testResults.xml).
$testResultsDir = [IO.Path]::Combine($settings.ProjectRoot, 'tests', 'out')
if (-not (Test-Path -Path $testResultsDir)) {
New-Item -Path $testResultsDir -ItemType Directory -Force > $null
}
$testResultsXml = [IO.Path]::Combine($testResultsDir, 'testResults.xml')

$pesterConfiguration = New-PesterConfiguration
$pesterConfiguration.Run.Path = $settings.Tests.FullName
$pesterConfiguration.Run.PassThru = $true
$pesterConfiguration.Output.Verbosity = 'Detailed'
$pesterConfiguration.TestResult.Enabled = $true
$pesterConfiguration.TestResult.OutputPath = $testResultsXml
$pesterConfiguration.TestResult.OutputFormat = 'NUnitXml'

$testResults = Invoke-Pester -Configuration $pesterConfiguration

if ($testResults.FailedCount -gt 0) {
$testResults | Format-List
Expand Down
8 changes: 6 additions & 2 deletions tests/build.tests.ps1
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,11 +21,13 @@ Describe 'Build' {
Write-Host "OutputPath: $script:testModuleOutputPath"

# build is PS job so psake doesn't freak out because it's nested
# NOTE: the scriptblock Set-Location handles the working directory;
# Start-Job -WorkingDirectory is PS 6+ only and breaks on Windows PowerShell 5.1.
Start-Job -Scriptblock {
Set-Location -Path $using:testModuleSource
$global:PSBuildCompile = $true
./build.ps1 -Task Build
} -WorkingDirectory $script:testModuleSource | Wait-Job
} | Wait-Job
}

AfterAll {
Expand DownExpand Up@@ -73,11 +75,13 @@ Describe 'Build' {
Context 'Dot-sourced module' {
BeforeAll {
# build is PS job so psake doesn't freak out because it's nested
# NOTE: the scriptblock Set-Location handles the working directory;
# Start-Job -WorkingDirectory is PS 6+ only and breaks on Windows PowerShell 5.1.
Start-Job -Scriptblock {
Set-Location -Path $using:testModuleSource
$global:PSBuildCompile = $false
./build.ps1 -Task Build
} -WorkingDirectory $script:testModuleSource | Wait-Job
} | Wait-Job
Write-Debug "TestModule output path: $script:testModuleSource"
$items = Get-ChildItem -Path $script:testModuleSource -Recurse -File
Write-Debug ($items | Format-Table FullName | Out-String)
Expand Down
Loading