From f362c8ffe71634526ee4587c39eeaf6422fd50f5 Mon Sep 17 00:00:00 2001 From: Trent Blackburn Date: Sun, 3 May 2026 22:49:50 -0400 Subject: [PATCH 1/3] refactor(build): align coverage config with template pattern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switch the staged-output path computation from a hardcoded module name to the env-var-driven pattern from tablackburn/PowerShellModuleTemplate#19: - Use $Env:BHPSModuleManifest / $Env:BHProjectName (populated by Set-BuildEnvironment before psake runs) instead of a hardcoded $moduleName = 'ReScenePS' and a manual manifest-path computation. - Add an env-var guard so direct Invoke-psake invocations (bypassing build.ps1) fail fast with an actionable message instead of an obscure Import-PowerShellDataFile null-binding error. - Use [IO.Path]::Combine for the staged path to avoid mixed separators on Windows, matching the rest of the properties block. Preserves the existing third coverage path (Classes/) — this module has a Classes/ subdirectory. Functionally equivalent to the prior config (same staged Output path, same coverage targets); this is a cosmetic alignment to the template pattern across the rest of the user's PowerShell modules. Co-Authored-By: Claude Opus 4.7 (1M context) --- build.psake.ps1 | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/build.psake.ps1 b/build.psake.ps1 index 67f184e..3b75192 100644 --- a/build.psake.ps1 +++ b/build.psake.ps1 @@ -14,19 +14,21 @@ properties { $PSBPreference.Test.OutputFile = [IO.Path]::Combine($PSScriptRoot, 'out', 'testResults.xml') $PSBPreference.Test.OutputFormat = 'NUnitXml' - # Code coverage configuration - # Coverage files must point to Output directory where tests actually execute - # (Tests import module from Output/, not source directory) - $moduleName = 'ReScenePS' - $sourceManifest = Join-Path $PSScriptRoot "$moduleName/$moduleName.psd1" - $moduleVersion = (Import-PowerShellDataFile -Path $sourceManifest).ModuleVersion - $moduleOutDir = Join-Path $PSScriptRoot "Output/$moduleName/$moduleVersion" - $PSBPreference.Test.CodeCoverage.Enabled = $true + # Coverage must target the staged build output, not the source tree — tests + # Import-Module from Output//, so Pester only records hits + # against those paths. $Env:BHBuildOutput points at /BuildOutput at + # properties-evaluation time (PowerShellBuild rewrites it later inside its + # tasks), so we compute the staged path from the manifest version here. + if (-not $Env:BHPSModuleManifest -or -not $Env:BHProjectName) { + throw 'Coverage configuration requires BuildHelpers env vars. Run via ./build.ps1 or call Set-BuildEnvironment first.' + } + $_moduleVersion = (Import-PowerShellDataFile -Path $Env:BHPSModuleManifest).ModuleVersion + $_stagedOutput = [IO.Path]::Combine($PSScriptRoot, 'Output', $Env:BHProjectName, $_moduleVersion) $PSBPreference.Test.CodeCoverage.Files = @( - "$moduleOutDir/Public/*.ps1" - "$moduleOutDir/Private/*.ps1" - "$moduleOutDir/Classes/*.ps1" + "$_stagedOutput/Public/*.ps1" + "$_stagedOutput/Private/*.ps1" + "$_stagedOutput/Classes/*.ps1" ) $PSBPreference.Test.CodeCoverage.Threshold = 0 # Threshold enforced by Codecov $PSBPreference.Test.CodeCoverage.OutputFile = [IO.Path]::Combine($PSScriptRoot, 'out', 'coverage.xml') From acd5b32bdb702327c00483d28fe2fd2c3b1f17d8 Mon Sep 17 00:00:00 2001 From: Trent Blackburn Date: Sun, 3 May 2026 23:12:36 -0400 Subject: [PATCH 2/3] test: bootstrap BuildHelpers env vars before invoking psake Help.tests.ps1 and Manifest.tests.ps1 each have a "running outside ./build.ps1" escape hatch that calls Invoke-psake -TaskList Build directly. Until now the bootstrap only set BHBuildOutput later in the file; it relied on PowerShellBuild's Init task to populate the rest of the BHE env vars as a side effect. The new env-var guard in build.psake.ps1's properties block (added in the previous commit on this branch) runs *before* the Build task can do anything, so the isolated-test invocation path now fails fast with a guard error instead of bootstrapping. Add Set-BuildEnvironment to the bootstrap so BHPSModuleManifest and BHProjectName are populated before psake evaluates properties. Verified locally: with BH* env vars cleared, Invoke-Pester ./tests/Help.tests.ps1 now bootstraps cleanly (psake builds, 145 tests pass). Addresses Copilot review feedback on PR #11. Co-Authored-By: Claude Opus 4.7 (1M context) --- tests/Help.tests.ps1 | 10 ++++++++++ tests/Manifest.tests.ps1 | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/tests/Help.tests.ps1 b/tests/Help.tests.ps1 index 4437b86..859d5c9 100644 --- a/tests/Help.tests.ps1 +++ b/tests/Help.tests.ps1 @@ -68,6 +68,11 @@ BeforeDiscovery { If the BHBuildOutput environment variable exists, it is running in a psake build, so do not build the module. #> if ($null -eq $Env:BHBuildOutput) { + # Populate BuildHelpers env vars so build.psake.ps1's properties block has + # the values it needs (BHPSModuleManifest, BHProjectName) — when running + # via ./build.ps1 this happens before psake; running tests in isolation + # bypasses that, so we do it here. + Set-BuildEnvironment -Path (Split-Path -Parent $PSScriptRoot) -Force $buildFilePath = Join-Path -Path $PSScriptRoot -ChildPath '..\build.psake.ps1' $invokePsakeParameters = @{ TaskList = 'Build' @@ -121,6 +126,11 @@ BeforeAll { If the BHBuildOutput environment variable exists, it is running in a psake build, so do not build the module. #> if ($null -eq $Env:BHBuildOutput) { + # Populate BuildHelpers env vars so build.psake.ps1's properties block has + # the values it needs (BHPSModuleManifest, BHProjectName) — when running + # via ./build.ps1 this happens before psake; running tests in isolation + # bypasses that, so we do it here. + Set-BuildEnvironment -Path (Split-Path -Parent $PSScriptRoot) -Force $buildFilePath = Join-Path -Path $PSScriptRoot -ChildPath '..\build.psake.ps1' $invokePsakeParameters = @{ TaskList = 'Build' diff --git a/tests/Manifest.tests.ps1 b/tests/Manifest.tests.ps1 index b27b8ab..45813e8 100644 --- a/tests/Manifest.tests.ps1 +++ b/tests/Manifest.tests.ps1 @@ -26,6 +26,11 @@ BeforeDiscovery { If the BHBuildOutput environment variable exists, it is running in a psake build, so do not build the module. #> if ($null -eq $Env:BHBuildOutput) { + # Populate BuildHelpers env vars so build.psake.ps1's properties block has + # the values it needs (BHPSModuleManifest, BHProjectName) — when running + # via ./build.ps1 this happens before psake; running tests in isolation + # bypasses that, so we do it here. + Set-BuildEnvironment -Path (Split-Path -Parent $PSScriptRoot) -Force $buildFilePath = Join-Path -Path $PSScriptRoot -ChildPath '..\build.psake.ps1' $invokePsakeParameters = @{ TaskList = 'Build' @@ -59,6 +64,11 @@ BeforeAll { If the BHBuildOutput environment variable exists, it is running in a psake build, so do not build the module. #> if ($null -eq $Env:BHBuildOutput) { + # Populate BuildHelpers env vars so build.psake.ps1's properties block has + # the values it needs (BHPSModuleManifest, BHProjectName) — when running + # via ./build.ps1 this happens before psake; running tests in isolation + # bypasses that, so we do it here. + Set-BuildEnvironment -Path (Split-Path -Parent $PSScriptRoot) -Force $buildFilePath = Join-Path -Path $PSScriptRoot -ChildPath '..\build.psake.ps1' $invokePsakeParameters = @{ TaskList = 'Build' From c5364a7e006c5e80c9650b1ef059cdc25dd572a6 Mon Sep 17 00:00:00 2001 From: Trent Blackburn Date: Sun, 3 May 2026 23:17:51 -0400 Subject: [PATCH 3/3] refactor(build): drop $_ prefix from helper variable names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename $_moduleVersion → $moduleVersion and $_stagedOutput → $stagedOutput per Copilot review feedback on PR #11. Pure rename, no behavior change. Same rename applied across PowerShellModuleTemplate, JsmOperations, and PlexAutomationToolkit so the user's modules stay in sync. Co-Authored-By: Claude Opus 4.7 (1M context) --- build.psake.ps1 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build.psake.ps1 b/build.psake.ps1 index 3b75192..e7cb8ea 100644 --- a/build.psake.ps1 +++ b/build.psake.ps1 @@ -23,12 +23,12 @@ properties { if (-not $Env:BHPSModuleManifest -or -not $Env:BHProjectName) { throw 'Coverage configuration requires BuildHelpers env vars. Run via ./build.ps1 or call Set-BuildEnvironment first.' } - $_moduleVersion = (Import-PowerShellDataFile -Path $Env:BHPSModuleManifest).ModuleVersion - $_stagedOutput = [IO.Path]::Combine($PSScriptRoot, 'Output', $Env:BHProjectName, $_moduleVersion) + $moduleVersion = (Import-PowerShellDataFile -Path $Env:BHPSModuleManifest).ModuleVersion + $stagedOutput = [IO.Path]::Combine($PSScriptRoot, 'Output', $Env:BHProjectName, $moduleVersion) $PSBPreference.Test.CodeCoverage.Files = @( - "$_stagedOutput/Public/*.ps1" - "$_stagedOutput/Private/*.ps1" - "$_stagedOutput/Classes/*.ps1" + "$stagedOutput/Public/*.ps1" + "$stagedOutput/Private/*.ps1" + "$stagedOutput/Classes/*.ps1" ) $PSBPreference.Test.CodeCoverage.Threshold = 0 # Threshold enforced by Codecov $PSBPreference.Test.CodeCoverage.OutputFile = [IO.Path]::Combine($PSScriptRoot, 'out', 'coverage.xml')