Skip to content

Commit 2193328

Browse files
committed
feat(#194): enhance NovaModule test workflow with code coverage validation
- Add coverage target checks in Invoke-NovaTestWorkflow - Introduce functions for retrieving coverage settings from project configuration - Update project templates to include default Pester code coverage settings
1 parent 0147a13 commit 2193328

17 files changed

Lines changed: 660 additions & 17 deletions

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
2424

2525
### Changed
2626
- The architect/design flow now surfaces settled vs unresolved design items before finalization, offers explicit choices for full finalization vs design-package-only handoff, clarifies how to use design notes versus the paste-ready GitHub issue draft, and requires finalization output to follow the project Markdown authoring guidance.
27+
- `ProjectTemplate.json` and the packaged example `project.json` now include Nova's default Pester `CodeCoverage` block with `Enabled=false`, shared `src/` coverage paths, JaCoCo output, and a `90` percent target so new projects can opt into coverage without hand-authoring the configuration.
2728

2829

2930
### Deprecated
@@ -33,6 +34,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
3334

3435

3536
### Fixed
37+
- `Test-NovaBuild` now fails when `project.json` configures `Pester.CodeCoverage.CoveragePercentTarget` and the measured coverage percentage is lower than the configured target, instead of passing through Pester's success result unchanged.
38+
- Nova now also applies that configured target directly to the Pester runtime configuration, so Pester's own coverage summary shows the configured threshold instead of the default `75%`.
3639

3740

3841
### Security

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,8 @@ Notes:
261261
- `Test-NovaBuild` validates the built module output, not just loose source files
262262
- it writes NUnit XML to `artifacts/TestResults.xml`
263263
- it respects `BuildRecursiveFolders` when discovering tests
264+
- if `project.json` sets `Pester.CodeCoverage.CoveragePercentTarget`, `Test-NovaBuild` fails when the measured coverage percentage is lower than that configured target
265+
- new template and packaged example `project.json` files already include an opt-in `Pester.CodeCoverage` block with `Enabled=false`, JaCoCo output in `artifacts/coverage.xml`, and a `90` percent target so projects can enable coverage when they are ready
264266
- contributor and CI environments should still install `Pester 5.7.1` explicitly before running `Test-NovaBuild`
265267
- the published `NovaModuleTools` manifest also declares `Pester 5.7.1`, so installed end-user workflows can still resolve that dependency automatically
266268

RELEASE_NOTE.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ This file summarizes public cmdlet, CLI, configuration, and migration changes fo
1111
- Before the first interactive scaffold question, Nova now also warns when a newer NovaModuleTools release is available by reusing the same non-blocking update warning behavior already used by `build`.
1212

1313
### Changed
14+
- New projects now start with Nova's default Pester `CodeCoverage` block in both the minimal template and packaged example `project.json`, with `Enabled=false`, shared `src/` coverage paths, JaCoCo output, and a `90` percent target ready to opt into.
1415

1516

1617
### Deprecated
@@ -20,6 +21,8 @@ This file summarizes public cmdlet, CLI, configuration, and migration changes fo
2021

2122

2223
### Fixed
24+
- `Test-NovaBuild` now fails when `project.json` sets `Pester.CodeCoverage.CoveragePercentTarget` and the measured coverage percentage is lower than the configured target.
25+
- The same configured target is now also applied to Pester's runtime configuration, so the console coverage summary no longer falls back to `75%`.
2326

2427

2528
### Security

docs/NovaModuleTools/en-US/Initialize-NovaModule.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ PS> Initialize-NovaModule [-Path <string>] [-Example] [-WhatIf] [-Confirm] [<Com
2727

2828
`Initialize-NovaModule` creates a new project folder, the standard `src/` layout, and a starter `project.json` file.
2929

30+
The starter `project.json` includes Nova's standard Pester defaults, including an opt-in `CodeCoverage` block with `Enabled=false`, common `src/` coverage paths, JaCoCo output in `artifacts/coverage.xml`, and a `90` percent target that can be enabled later.
31+
3032
The command collects project details interactively, including the module name, description, version, author, minimum PowerShell version, Git initialization, and an optional Agentic Copilot starter package. Before the first interactive question, Nova checks whether a newer `NovaModuleTools` release is available and warns without blocking the scaffold flow. When Git initialization is enabled, Nova also creates or updates a default `.gitignore` in the generated project root so common local and CI artifact paths such as `artifacts/`, `dist/`, `run.ps1`, and `reload.ps1` are ignored from the start. Existing `.gitignore` files are preserved and only receive the missing Nova-managed entries. When you enable the Agentic package, Nova also asks for a project short name used in generated guidance placeholders such as `Invoke-<ShortName>*`; for NovaModuleTools the short name is `Nova`, but it could also have been
3133
`NMT`. The Agentic package follows Nova's maintained agentic guidance through a filtered starter mirror, including Nova build/test/package expectations, `project.json`
3234
`Manifest.PowerShellHostVersion` compatibility guidance, strict ScriptAnalyzer guidance without excluded rules, generated `dist` module files, command-help ownership, source-mirrored test guidance, guidance that ScriptAnalyzer findings reported by
@@ -38,7 +40,8 @@ Use this command when you want to start a new module in the NovaModuleTools stru
3840

3941
Use `-Path` when you want to create the project under a specific base directory. Positional path syntax is no longer supported.
4042

41-
Use `-Example` when you want the scaffold to start from the packaged example project instead of the minimal default layout. The example flow keeps the example source, resource, and test files, skips the Pester enable/disable question, and applies the interactive metadata values to the copied `project.json`. The standard and example flows share the same upfront Nova update warning, inline validation and retry behavior for interactive answers, and optional Agentic Copilot setup prompt after the Git question. When Git is enabled in either flow, Nova also ensures the generated project root has the default `.gitignore` entries for local and CI artifacts without overwriting any existing `.gitignore` content. When you answer `Yes`, Nova asks for the short project name, adds the same starter package to either scaffold style, and merges the example README instead of replacing it with the generic starter README outright.
43+
Use `-Example` when you want the scaffold to start from the packaged example project instead of the minimal default layout. The example flow keeps the example source, resource, and test files, skips the Pester enable/disable question, and applies the interactive metadata values to the copied `project.json`, including the same disabled-by-default `CodeCoverage` block that the standard scaffold uses. The standard and example flows share the same upfront Nova update warning, inline validation and retry behavior for interactive answers, and optional Agentic Copilot setup prompt after the Git question. When Git is enabled in either flow, Nova also ensures the generated project root has the default `.gitignore` entries for local and CI artifacts without overwriting any existing `.gitignore` content. When you answer
44+
`Yes`, Nova asks for the short project name, adds the same starter package to either scaffold style, and merges the example README instead of replacing it with the generic starter README outright.
4245

4346
This command supports `-WhatIf` and `-Confirm` through PowerShell `SupportsShouldProcess`. Use `-WhatIf` to preview the scaffold target after the interactive answers have been collected, without creating folders, writing `project.json`, or initializing Git.
4447

@@ -139,7 +142,8 @@ This cmdlet does not emit an output object.
139142
140143
## NOTES
141144
142-
Generated projects start with NovaModuleTools defaults for recursive discovery, source markers, duplicate-function validation, and—when Git is enabled—a default `.gitignore` for common local and CI artifact paths. The packaged example scaffold keeps its bundled example source and tests, while still updating prompt-driven metadata such as project name, description, version, author, and PowerShell host version. The optional Agentic Copilot starter package adds repository-local Copilot workflow files under the project root and `.github/` that tell agents to keep build/test/package workflows on Nova, treat `project.json` `Manifest.PowerShellHostVersion` as the PowerShell compatibility target, run ScriptAnalyzer before build/test through the repo-standard `Invoke-ScriptAnalyzerCI.ps1` / `run.ps1` workflow, fix any ScriptAnalyzer findings before handoff, run project tests through `Test-NovaBuild` instead of direct `Invoke-Pester`, leave `.psm1` / `.psd1` files to generated
145+
Generated projects start with NovaModuleTools defaults for recursive discovery, source markers, duplicate-function validation, an opt-in Pester `CodeCoverage` block (`Enabled=false`, shared `src/` paths, JaCoCo output in `artifacts/coverage.xml`, and a `90` percent target), and—when Git is enabled—a default `.gitignore` for common local and CI artifact paths. The packaged example scaffold keeps its bundled example source and tests, while still updating prompt-driven metadata such as project name, description, version, author, and PowerShell host version. The optional Agentic Copilot starter package adds repository-local Copilot workflow files under the project root and `.github/` that tell agents to keep build/test/package workflows on Nova, treat `project.json` `Manifest.PowerShellHostVersion` as the PowerShell compatibility target, run ScriptAnalyzer before build/test through the repo-standard `Invoke-ScriptAnalyzerCI.ps1` /
146+
`run.ps1` workflow, fix any ScriptAnalyzer findings before handoff, run project tests through `Test-NovaBuild` instead of direct `Invoke-Pester`, leave `.psm1` / `.psd1` files to generated
143147
`dist` output, generate and validate command help with the Microsoft.PowerShell.PlatyPS cmdlets instead of hand-written Markdown structure, require a matching help file for every new public entry point in the same change, mirror new tests to source files, and add a text-file-formatting guardrail helper plus a Pester guardrail test when project tests are enabled.
144148

145149
`Initialize-NovaModule` uses `SupportsShouldProcess`, so `Get-Help Initialize-NovaModule -Full` surfaces native

docs/NovaModuleTools/en-US/Test-NovaBuild.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ PS> Test-NovaBuild [-Build] [-OverrideWarning] [[-TagFilter] <string[]>] [[-Excl
2828

2929
`Test-NovaBuild` reads the Pester configuration from `project.json`, resolves the correct test path, and runs the test suite against the current project.
3030

31+
When `project.json` sets `Pester.CodeCoverage.CoveragePercentTarget`, Nova also treats the configured threshold as a failure condition and stops the run if the measured coverage percentage is lower than that target.
32+
3133
Use `-Build` when you want Nova to rebuild the project output before the Pester run starts.
3234

3335
When `-Build` is used, `-OverrideWarning` lets that nested build continue even if the `src/public` layout guard reports zero or multiple top-level functions in a public file.
@@ -245,12 +247,14 @@ You can't pipe objects to this cmdlet.
245247

246248
### None
247249

248-
This cmdlet does not emit an output object. It throws when the test run fails.
250+
This cmdlet does not emit an output object. It throws when the test run fails or when a configured code coverage target is not met.
249251

250252
## NOTES
251253

252254
The generated test result XML is written to `artifacts/TestResults.xml`.
253255

256+
If `project.json` configures `Pester.CodeCoverage.CoveragePercentTarget`, `Test-NovaBuild` also fails when the measured coverage percentage is lower than that configured threshold.
257+
254258
`Test-NovaBuild` uses `SupportsShouldProcess`, so `Get-Help Test-NovaBuild -Full` surfaces native `-WhatIf` and
255259
`-Confirm` support.
256260

docs/commands.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ <h3>Start a new project</h3>
198198
public entry point, and a strict file-ending rule for changed or
199199
generated text files.
200200
</p>
201+
<p>New projects also start with Nova's default <code>Pester.CodeCoverage</code> block in
202+
<code>project.json</code>, but keep it disabled until you choose to enable coverage.</p>
201203
<p>If you enable the Agentic package, Nova also asks for a short project name used in generated
202204
guidance placeholders such as <code>Invoke-&lt;ShortName&gt;*</code>. For NovaModuleTools the
203205
short name is <code>Nova</code>, but it could also have been <code>NMT</code>.</p>
@@ -314,6 +316,9 @@ <h3>Run the test workflow</h3>
314316
</div>
315317
<p>Run Pester for the current project and write results to
316318
<code>artifacts/TestResults.xml</code>.</p>
319+
<p>If coverage is enabled in <code>project.json</code>, the same workflow also writes
320+
<code>artifacts/coverage.xml</code> and fails when measured coverage stays below the
321+
configured <code>CoveragePercentTarget</code>.</p>
317322
<ul class="plain-list">
318323
<li><strong>Use when:</strong> you want the standard Nova test flow</li>
319324
<li data-command-visibility="command-line" hidden><strong>Best launcher option:</strong>

docs/core-workflows.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,9 @@ <h2>Create the project</h2>
146146
<code>Test-MarkdownCommandHelp</code>, with a matching help file required for every new public
147147
entry point, and a strict file-ending rule for changed or generated text
148148
files.</p>
149+
<p>The generated <code>project.json</code> also starts with Nova's standard <code>Pester</code>
150+
defaults, including a disabled <code>CodeCoverage</code> block you can enable later without
151+
hand-authoring the structure.</p>
149152
<p>When you answer <code>Yes</code>, Nova also asks for a short project name used in generated guidance
150153
placeholders such as <code>Invoke-&lt;ShortName&gt;*</code>. For NovaModuleTools the short name is
151154
<code>Nova</code>, but it could also have been <code>NMT</code>.</p>
@@ -213,6 +216,11 @@ <h2>Run the tests</h2>
213216
</div>
214217
<p><code>Test-NovaBuild</code> reads the Pester configuration from <code>project.json</code>, resolves
215218
the test path, and writes results to <code>artifacts/TestResults.xml</code>.</p>
219+
<p>Starter projects already include the matching <code>Pester.CodeCoverage</code> block in
220+
<code>project.json</code>, but keep it disabled until you opt in. When you set
221+
<code>Pester.CodeCoverage.Enabled</code> to <code>true</code>, Nova also writes JaCoCo coverage to
222+
<code>artifacts/coverage.xml</code> and stops if the measured coverage percentage is lower than the
223+
configured <code>CoveragePercentTarget</code>.</p>
216224
<p>Use <code>-Build</code>, <code>--build</code>, or <code>-b</code> when you want Nova to rebuild the
217225
project before the test workflow starts.</p>
218226
<p><strong>Important behavior:</strong> when <code>BuildRecursiveFolders</code> is <code>true</code>,

docs/getting-started.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,10 @@ <h2>4. Scaffold the packaged example</h2>
217217
entry point, and a strict file-ending rule for changed or generated text
218218
files.
219219
Nova then creates a project folder under the path you selected.</p>
220+
<p>The generated <code>project.json</code> also starts with Nova's standard <code>Pester</code>
221+
defaults, including an opt-in <code>CodeCoverage</code> block with <code>Enabled=false</code>,
222+
shared <code>src/</code> coverage paths, JaCoCo output in <code>artifacts/coverage.xml</code>, and
223+
a <code>90</code> percent target you can enable later.</p>
220224
<p>If you enable the Agentic package, Nova also asks for a short project name used in generated guidance
221225
placeholders such as <code>Invoke-&lt;ShortName&gt;*</code>. For NovaModuleTools the short name is
222226
<code>Nova</code>, but it could also have been <code>NMT</code>.</p>
@@ -263,6 +267,10 @@ <h2>5. Build and test the example</h2>
263267
<li>the built module is written to <code>dist/&lt;ProjectName&gt;/</code></li>
264268
<li>the test run writes results to <code>artifacts/TestResults.xml</code></li>
265269
</ul>
270+
<p>The scaffold keeps code coverage opt-in. When you later set
271+
<code>Pester.CodeCoverage.Enabled</code> to <code>true</code>, the same Nova test flow also writes
272+
<code>artifacts/coverage.xml</code> and stops when the measured coverage percentage is lower than
273+
the configured <code>CoveragePercentTarget</code>.</p>
266274
</section>
267275

268276
<section class="content-section" id="import-and-run">

0 commit comments

Comments
 (0)