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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),

### Fixed

- `Invoke-NovaTest`, `Test-NovaBuild`, and `% nova test` now resolve and import a supported installed `Pester` version from `5.7.1` through `5.10.0` instead of using an unsupported `Pester 6.x` installation automatically.
- Nova test workflows now fail early with a clear dependency error when only unsupported `Pester 6.x` versions are available.
- Nova test workflows now reuse an already loaded supported `Pester 5.x` version in the current PowerShell session before selecting a different installed version.
- Repository CI no longer trips the `Pester` assembly loader by importing a gallery-installed `NovaModuleTools` module, building the local module, and then switching to another supported `Pester` version in the same session.

### Security

## [3.3.0] - 2026-06-16
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
![WorkFlow Status][WorkFlowStatus]
[![Keep a Changelog][changelog-badge]][changelog]

NovaModuleTools is an enterprise-focused build tool for Agentic Copilot PowerShell module development, repository automation, and maintainable Nova workflows.
NovaModuleTools is an enterprise-focused build tool for PowerShell module development, repository automation, and maintainable Nova workflows.

This README is the single developer-documentation entry point for the repository.

Expand Down Expand Up @@ -298,8 +298,9 @@ Notes:
- if `project.json` sets `Pester.CodeCoverage.CoveragePercentTarget`, `Invoke-NovaTest` fails when the measured coverage percentage is lower than that configured target
- this repository currently enables coverage with a `99` percent target; the template and packaged example
`project.json` files ship the same JaCoCo configuration shape with `Enabled=false` and a `90` percent opt-in target
- make sure `Pester 5.7.1` is available before running `Invoke-NovaTest` or `Test-NovaBuild`
- the published `NovaModuleTools` manifest also declares `Pester 5.7.1`, so installed end-user workflows can still resolve that dependency automatically
- make sure a supported `Pester` version from `5.7.1` through `5.10.0` is available before running `Invoke-NovaTest` or `Test-NovaBuild`
- Nova resolves and imports a compatible installed `Pester 5.x` version for the managed test workflow and does not run tests with `Pester 6.x`
- the published `NovaModuleTools` manifest declares `Pester` with `ModuleVersion = 5.7.1` and `MaximumVersion = 5.10.0`, so installed end-user workflows can still resolve that supported dependency range automatically

### Create a package artifact

Expand Down Expand Up @@ -640,7 +641,7 @@ Responsibilities currently covered by the release pipeline include:
- publishing to PowerShell Gallery
- preparing the next prerelease version on `develop`

The workflow now uses `KeepAChangelog` for changelog release moves, creates annotated git tags named directly from the release version, and bootstraps the local PSResourceGet repository store before calling `Publish-NovaModule`. The shared CI installer also installs `Pester 5.7.1` explicitly before it installs prerelease gallery modules so test workflows do not rely on transitive manifest dependency resolution.
The workflow now uses `KeepAChangelog` for changelog release moves, creates annotated git tags named directly from the release version, and bootstraps the local PSResourceGet repository store before calling `Publish-NovaModule`. The shared CI installer also installs `Pester 5.7.1` explicitly before it installs prerelease gallery modules so test workflows stay on Nova's supported `Pester 5.x` range and do not rely on transitive manifest dependency resolution.

### Where NovaModuleTools cmdlets fit

Expand Down
2 changes: 2 additions & 0 deletions RELEASE_NOTE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ This file summarizes the release notes for NovaModuleTools. **UNRELEASED** chang

### Fixed

- `Invoke-NovaTest`, `Test-NovaBuild`, and `% nova test` now stay on Nova's supported `Pester 5.x` range and stop with a clear error instead of trying to run with an installed `Pester 6.x` version.

### Security

## [3.3.0] - 2026-06-16
Expand Down
2 changes: 2 additions & 0 deletions docs/NovaModuleTools/en-US/Invoke-NovaTest.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ PS> Invoke-NovaTest [[-TagFilter] <string[]>] [[-ExcludeTagFilter] <string[]>]

`Invoke-NovaTest` reads the Pester configuration from `project.json`, discovers the repository unit-test files, and runs the managed Nova test workflow without rebuilding the project first.

Nova resolves a supported installed `Pester` version from `5.7.1` through `5.10.0` for the managed test workflow and stops with a clear dependency error when only unsupported `Pester 6.x` versions are available.

The unit-test workflow writes NUnit XML to `artifacts/UnitTestResults.xml`.

When `Pester.CodeCoverage.Enabled` is `true`, Nova also writes JaCoCo coverage to `artifacts/coverage.xml` and fails the run when the measured percentage is lower than `Pester.CodeCoverage.CoveragePercentTarget`.
Expand Down
8 changes: 5 additions & 3 deletions docs/NovaModuleTools/en-US/Test-NovaBuild.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@ PS> Test-NovaBuild [[-TagFilter] <string[]>] [[-ExcludeTagFilter] <string[]>]

`Test-NovaBuild` reads the Pester configuration from `project.json`, discovers the build-validation integration tests for the current project, and runs the managed Nova test workflow against the built-module validation surface.

Nova resolves a supported installed `Pester` version from `5.7.1` through `5.10.0` for the managed test workflow and stops with a clear dependency error when only unsupported `Pester 6.x` versions are available.

This build-validation flow writes NUnit XML to `artifacts/TestResults.xml`.

Unlike `Invoke-NovaTest`, this command does not enforce source-coverage targets. Use `Invoke-NovaTest` for the unit-test and code-coverage workflow, and use `Test-NovaBuild` when you need build-validation integration coverage that reflects the built module path.

If the current project does not contain any `*.Integration.Tests.ps1` files, `Test-NovaBuild` stops with a Nova-native error that explains the expected naming and reminds you to use `Invoke-NovaTest` for unit tests.
If the current project does not contain any `*.Integration.Tests.ps1` files, `Test-NovaBuild` writes an actionable warning that explains the expected naming and reminds you to use `Invoke-NovaTest` for unit tests.

`-OverrideWarning` lets the nested build-validation flow continue even if the `src/public` layout guard reports zero or multiple top-level functions in a public file.

Expand Down Expand Up @@ -271,5 +273,5 @@ Returns the Pester result object from the managed build-validation run.

## RELATED LINKS

[Invoke-NovaTest](Invoke-NovaTest.md)
[Invoke-NovaBuild](Invoke-NovaBuild.md)
- [Invoke-NovaTest](./Invoke-NovaTest.md)
- [Invoke-NovaBuild](./Invoke-NovaBuild.md)
7 changes: 4 additions & 3 deletions project.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"ProjectName": "NovaModuleTools",
"Description": "NovaModuleTools is an enterprise-focused build tool for Agentic Copilot PowerShell module development, with a strong emphasis on structure, maintainability, and automated CI/CD pipelines.",
"Version": "3.3.0",
"Description": "NovaModuleTools is an enterprise-focused build tool for PowerShell module development, with a strong emphasis on structure, maintainability, and build for automated CI/CD pipelines.",
"Version": "3.3.1-preview",
"Preamble": [
"Set-StrictMode -Version Latest",
"$ErrorActionPreference = 'Stop'"
Expand All @@ -14,7 +14,8 @@
"RequiredModules": [
{
"ModuleName": "Pester",
"ModuleVersion": "5.7.1"
"ModuleVersion": "5.7.1",
"MaximumVersion": "5.10.0"
},
{
"ModuleName": "Microsoft.PowerShell.PlatyPS",
Expand Down
1 change: 1 addition & 0 deletions scripts/build/ci/Install-CiPowerShellModules.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ function Get-CiModuleInstallOption {
if ($Name -eq 'Pester') {
return [pscustomobject]@{
RequiredVersion = '5.7.1'
MaximumVersion = '5.10.0'
AllowPrerelease = $false
}
}
Expand Down
55 changes: 42 additions & 13 deletions scripts/build/ci/Invoke-NovaModuleToolsCI.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,58 @@ function Copy-NovaModuleToolsArtifactIfPresent {
}
}

function ConvertTo-NovaSingleQuotedPowerShellLiteral {
param(
[Parameter(Mandatory)][string]$Value
)

return "'$($Value.Replace("'", "''") )'"
}

function Get-NovaModuleToolsValidationCommand {
param(
[Parameter(Mandatory)][string]$BuiltModulePath,
[Parameter(Mandatory)][string]$CommandName,
[string[]]$ExcludeTag = @()
)

$commandLine = $CommandName
if (@($ExcludeTag).Count -gt 0) {
$excludeTagLiteral = @($ExcludeTag | ForEach-Object {ConvertTo-NovaSingleQuotedPowerShellLiteral -Value ([string]$_)}) -join ', '
$commandLine += " -ExcludeTagFilter @($excludeTagLiteral)"
}

return "Import-Module $( ConvertTo-NovaSingleQuotedPowerShellLiteral -Value $BuiltModulePath ) -Force -ErrorAction Stop; $commandLine"
}

function Invoke-NovaModuleToolsFreshValidationCommand {
param(
[Parameter(Mandatory)][string]$Command
)

& pwsh -NoLogo -NoProfile -Command $Command
if ($LASTEXITCODE -ne 0) {
throw "Validation command failed: $Command"
}
}

$repoRoot = (Resolve-Path -LiteralPath (Join-Path $PSScriptRoot '..' '..' '..')).Path
Set-Location $repoRoot
New-Item -ItemType Directory -Path $OutputDirectory -Force | Out-Null

Import-Module NovaModuleTools -ErrorAction Stop

Invoke-NovaBuild

$projectInfo = Get-NovaProjectInfo
$builtModulePath = $projectInfo.OutputModuleDir
Remove-Module $projectInfo.ProjectName -ErrorAction SilentlyContinue
Import-Module $builtModulePath -Force
$projectInfo = Get-NovaProjectInfo
Invoke-NovaBuild
$builtModulePath = Join-Path $projectInfo.OutputModuleDir "$( $projectInfo.ProjectName ).psd1"

$novaModuleToolsTestFailed = $false
try {
if (@($ExcludeTag).Count -gt 0) {
Invoke-NovaTest -ExcludeTagFilter $ExcludeTag
Test-NovaBuild -ExcludeTagFilter $ExcludeTag
} else {
Invoke-NovaTest
Test-NovaBuild
}
$unitTestCommand = Get-NovaModuleToolsValidationCommand -BuiltModulePath $builtModulePath -CommandName 'Invoke-NovaTest' -ExcludeTag $ExcludeTag
Invoke-NovaModuleToolsFreshValidationCommand -Command $unitTestCommand

$buildValidationCommand = Get-NovaModuleToolsValidationCommand -BuiltModulePath $builtModulePath -CommandName 'Test-NovaBuild' -ExcludeTag $ExcludeTag
Invoke-NovaModuleToolsFreshValidationCommand -Command $buildValidationCommand
} catch {
$novaModuleToolsTestFailed = $true
Write-Warning "Nova test workflow failed: $( $_.Exception.Message )"
Expand Down
Loading
Loading