diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8b30baf..9829f76 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -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 diff --git a/CHANGELOG.md b/CHANGELOG.md index 331ab36..c4893c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## 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 diff --git a/PowerShellBuild/PowerShellBuild.psd1 b/PowerShellBuild/PowerShellBuild.psd1 index b19fdbf..8b6a039 100644 --- a/PowerShellBuild/PowerShellBuild.psd1 +++ b/PowerShellBuild/PowerShellBuild.psd1 @@ -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' diff --git a/PowerShellBuild/Public/Get-PSBuildCertificate.ps1 b/PowerShellBuild/Public/Get-PSBuildCertificate.ps1 index e6c6db4..c8bdbec 100644 --- a/PowerShellBuild/Public/Get-PSBuildCertificate.ps1 +++ b/PowerShellBuild/Public/Get-PSBuildCertificate.ps1 @@ -122,8 +122,11 @@ function Get-PSBuildCertificate { 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 | @@ -195,6 +198,7 @@ function Get-PSBuildCertificate { 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 } diff --git a/instructions/repository-specific.instructions.md b/instructions/repository-specific.instructions.md index f390059..f805c82 100644 --- a/instructions/repository-specific.instructions.md +++ b/instructions/repository-specific.instructions.md @@ -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`) diff --git a/psakeFile.ps1 b/psakeFile.ps1 index 22a24c4..a0fa013 100644 --- a/psakeFile.ps1 +++ b/psakeFile.ps1 @@ -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 diff --git a/tests/build.tests.ps1 b/tests/build.tests.ps1 index 6022d47..ba218ae 100644 --- a/tests/build.tests.ps1 +++ b/tests/build.tests.ps1 @@ -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 { @@ -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)