From 3ed8e8936ae15a5e15ee67fbf9f58e03477c2d17 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 17:28:20 +0200 Subject: [PATCH 01/22] docs: add Pester 6 migration skill Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- docs/content/guides/pester-migration.md | 44 +++ docs/content/index.md | 1 + docs/zensical.toml | 1 + skills/pester-migration/SKILL.md | 371 ++++++++++++++++++++++++ 4 files changed, 417 insertions(+) create mode 100644 docs/content/guides/pester-migration.md create mode 100644 skills/pester-migration/SKILL.md diff --git a/docs/content/guides/pester-migration.md b/docs/content/guides/pester-migration.md new file mode 100644 index 00000000..773fcd6f --- /dev/null +++ b/docs/content/guides/pester-migration.md @@ -0,0 +1,44 @@ +--- +title: Migrating Pester tests +description: A repository-wide checklist for migrating PSModule test sets to Pester 6.1.0. +--- + +# Migrating Pester tests + +Use the reusable [`pester-migration`](https://github.com/PSModule/Process-PSModule/tree/main/skills/pester-migration/SKILL.md) +agent skill to migrate every Pester test set in a PSModule repository. It is +written for Pester **6.1.0** and distinguishes required compatibility changes +from optional v6 modernization. + +The migration covers repository and test-set inventory, supported PowerShell +runtime and CI checks, per-file discovery and run isolation, hidden paths, +data-driven tests, setup blocks, mocks, pending tests, name templates, +coverage, `Invoke-Pester` configuration, reserved tags, and validation +reporting. It does not migrate consumer repositories as part of this framework +change. + +## Required before declaring a migration complete + +- Every test entry point is inventoried and runs on its supported runtime matrix. +- Pester 6.1.0 is imported in local and CI acceptance runs. +- Each test file is self-contained under per-file discovery and run. +- Hidden paths, empty data, duplicate setup blocks, mocks, pending tests, name + templates, coverage settings, legacy invocation parameters, and `None` tags + have been reviewed. +- Serial results, coverage, and test-result artifacts are recorded and compared + with the baseline. + +## Optional after compatibility + +`Should-*` assertions, `Run.Shuffle`, and experimental `Run.Parallel` are +independent adoption choices. Enable them only with separate validation and +document the choice. + +## Primary and secondary sources + +- [Official Pester v5-to-v6 migration](https://pester.dev/docs/migrations/v5-to-v6) +- [Pester installation](https://pester.dev/docs/introduction/installation) +- [Pester configuration](https://pester.dev/docs/usage/configuration) +- [Pester parallel execution](https://pester.dev/docs/usage/parallel) +- [Awesome Copilot pester-migration](https://github.com/github/awesome-copilot/tree/main/skills/pester-migration) +- [Awesome Copilot pester-should-migration](https://github.com/github/awesome-copilot/tree/main/skills/pester-should-migration) diff --git a/docs/content/index.md b/docs/content/index.md index 57fe5412..800c9189 100644 --- a/docs/content/index.md +++ b/docs/content/index.md @@ -40,6 +40,7 @@ Task-oriented deep dives into the pipeline's functionality. | [Configuring the pipeline](guides/configuring-the-pipeline.md) | Worked examples for coverage targets, rapid testing, linting, and PR-based release notes. | | [Structuring your module](guides/structuring-your-module.md) | The repository and module source layout the workflow expects, and how to declare dependencies. | | [Writing module tests](guides/writing-module-tests.md) | Test discovery, setup and teardown phases, and shared test infrastructure. | +| [Migrating Pester tests](guides/pester-migration.md) | A repository-wide checklist for migrating every test set to Pester 6.1.0. | | [Skipping framework tests](guides/skipping-framework-tests.md) | Skip individual framework tests on a per-file basis. | | [Versioning and releases](guides/versioning-and-releases.md) | Label-driven versioning, prereleases, and what a release produces. | | [Validating before review](guides/validating-before-review.md) | The PSModule validation pass before a draft pull request is marked ready. | diff --git a/docs/zensical.toml b/docs/zensical.toml index cdd222bf..699a3146 100644 --- a/docs/zensical.toml +++ b/docs/zensical.toml @@ -30,6 +30,7 @@ nav = [ {"Configuring the pipeline" = "guides/configuring-the-pipeline.md"}, {"Structuring your module" = "guides/structuring-your-module.md"}, {"Writing module tests" = "guides/writing-module-tests.md"}, + {"Migrating Pester tests" = "guides/pester-migration.md"}, {"Skipping framework tests" = "guides/skipping-framework-tests.md"}, {"Versioning and releases" = "guides/versioning-and-releases.md"}, {"Validating before review" = "guides/validating-before-review.md"}, diff --git a/skills/pester-migration/SKILL.md b/skills/pester-migration/SKILL.md new file mode 100644 index 00000000..2175bce3 --- /dev/null +++ b/skills/pester-migration/SKILL.md @@ -0,0 +1,371 @@ +--- +name: pester-migration +description: Migrate every Pester test set in a PSModule repository to Pester 6.1.0, preserving test intent while checking runtime, discovery, setup, mocks, data-driven tests, coverage, CI, and reporting. Use when upgrading a PSModule repository from Pester 5 or earlier, or when validating a repository-wide Pester migration. +--- + +# Migrate PSModule tests to Pester 6.1.0 + +Use this skill to migrate a PSModule repository one test set at a time. Do not +change consumer repositories while developing or validating this skill. + +The primary source is the official +[Pester v5-to-v6 migration guide](https://pester.dev/docs/migrations/v5-to-v6). +The two [Awesome Copilot skills](https://github.com/github/awesome-copilot/tree/main/skills) +are secondary practical guidance only. If this skill and the official guide +differ, follow the official guide and record the decision. + +## Compatibility boundary + +The target is **Pester 6.1.0** on **Windows PowerShell 5.1** or **PowerShell +7.4 or later**. Upgrade one major version at a time when the source is older: +v3 to v4, v4 to v5, then v5 to v6. Do not combine unrelated test refactoring +with compatibility fixes. + +Required compatibility work: + +- Install and run Pester 6.1.0 on every supported runtime and CI image. +- Make every test file self-contained under v6's per-file discovery-and-run + model. Put discovery-only data loading in `BeforeDiscovery`. +- Review hidden files and directories, including dot-prefixed paths and + Windows Hidden items. Exclude intentional non-tests with `Run.ExcludePath`. +- Fix empty or `$null` `-ForEach` and `-TestCases`; use + `-AllowNullOrEmptyForEach` only when empty data is intentional. +- Combine duplicate `BeforeAll`, `BeforeEach`, `AfterAll`, or `AfterEach` + blocks in the same scope. +- Replace removed `Assert-MockCalled` and `Assert-VerifiableMock`. +- Add a default mock when a parameter-filtered mock must handle other calls. +- Review `<...>` name templates because their contents are now expressions. +- Replace `Set-ItResult -Pending` with `-Inconclusive`, `-Skipped`, or + `It -Skip`. +- Review coverage tracer and output format settings. +- Replace removed v4-style `Invoke-Pester` parameters with + `New-PesterConfiguration`. +- Rename a real `None` tag; in v6 it is reserved for untagged tests. + +Optional v6 adoption after compatibility is green: + +- Convert classic `Should -Be` assertions to `Should-Be` commands + incrementally. Classic syntax remains supported. +- Enable `Run.Shuffle` only after proving order independence. +- Enable experimental `Run.Parallel` only after proving file isolation and + parallel-safe resources. +- Enable `Debug.ShowStartMarkers` for diagnostic runs. + +Never present optional adoption as required migration work. + +## Step 1: Inventory the repository and test sets + +Before editing, record the repository, branch, supported PowerShell versions, +CI workflow files, Pester installation source, and every test entry point. +Search the whole repository, not just `tests/`; framework tests, action tests, +source tests, generated test fixtures, and nested suites can use different +configuration. + +```powershell +Get-ChildItem -Force +Get-ChildItem -Force -Recurse -File -Include *.Tests.ps1,*.Configuration.ps1,*.Container.ps1 +Get-ChildItem -Force -Recurse -File -Include *.yml,*.yaml,*.ps1,*.psd1,*.psm1 | + Select-String -Pattern 'Pester|Invoke-Pester|Should|BeforeDiscovery|BeforeAll|Mock' +``` + +For each test set, add an inventory row to the migration report: + +| Field | Record | +| --- | --- | +| Test set | Relative path and purpose | +| Entry point | Workflow, action, script, or local command | +| Discovery paths | Explicit paths, recursive paths, containers, configurations | +| Pester source | Required module version, install step, lock or floating policy | +| Runtime matrix | Windows PowerShell 5.1 and/or PowerShell 7.4+ | +| Setup | Root `BeforeAll.ps1`, `Pester.BeforeContainer.ps1`, file setup | +| Data | `-ForEach`, `-TestCases`, external files, generated cases | +| Mocks | Filtered mocks, mock assertions, shared state | +| Coverage/results | Paths, formats, thresholds, uploaded artifacts | +| Baseline | Run command, result counts, known failures | + +Use the inventory to find test sets that are not reachable from the default +workflow. A green workflow is not evidence that every test set was migrated. + +## Step 2: Check versions, runtime, and CI + +Run the baseline on the current version before changing files. Save the command, +Pester version, runtime, OS, result counts, and known failures. + +```powershell +Get-Module Pester -ListAvailable | Sort-Object Version -Descending | + Select-Object Name, Version, Path +(Get-Module Pester).Version +$PSVersionTable | Select-Object PSVersion, PSEdition, OS +Invoke-Pester -Path ./tests -Output Detailed +``` + +Pin the target during migration so local and CI results are comparable: + +```powershell +Install-Module Pester -RequiredVersion 6.1.0 -Force +Import-Module Pester -RequiredVersion 6.1.0 -Force +``` + +On Windows PowerShell 5.1, use `-SkipPublisherCheck` only when required to +install a newer Pester beside the inbox Pester 3. Do not hide an installation +failure. Verify the imported module is 6.1.0, not merely that a 6.x package is +available. + +Update each CI installation and invocation. Prefer an explicit requirement in +test files when that is the repository convention: + +```powershell +#Requires -Modules @{ ModuleName = 'Pester'; ModuleVersion = '6.1.0'; MaximumVersion = '6.1.0' } +``` + +If the repository intentionally floats patch releases within the major, record +that policy and use `ModuleVersion = '6.0.0'; MaximumVersion = '6.*'` instead. +The migration acceptance run must still use 6.1.0. + +## Step 3: Migrate discovery, setup, and isolation + +Pester 6 discovers and runs one file before moving to the next. A file cannot +depend on top-level state created while another file was discovered. Import +modules and define file-local discovery data in the file that uses them: + +```powershell +BeforeDiscovery { + $cases = Get-Content -Raw -Path (Join-Path $PSScriptRoot 'cases.json') | + ConvertFrom-Json +} + +BeforeAll { + Import-Module (Join-Path $PSScriptRoot '..\src\MyModule.psd1') -Force +} + +Describe 'My command' { + It 'handles ' -ForEach $cases { + Get-MyThing -Name $Name | Should -Be 'ok' + } +} +``` + +Use `$PSScriptRoot` for paths. Do not rely on `$MyInvocation.MyCommand.Path`, +the current directory, another test file's variables, or discovery order. +Repository-wide bootstrap that every worker needs belongs in +`Pester.BeforeContainer.ps1` at the repository root. Keep it deterministic and +idempotent. + +Check the complete recursive path set. Pester 6 includes hidden files and +directories by default, while `.git`, `.svn`, and `.hg` remain excluded. A +newly discovered hidden test is an intended compatibility change: fix it or +exclude it explicitly, rather than assuming it should remain invisible. + +For every test set, run one file directly and then the complete set. This +isolates discovery failures from cross-file assumptions: + +```powershell +Invoke-Pester -Path ./tests/Example.Tests.ps1 -Output Detailed +Invoke-Pester -Path ./tests -Output Detailed +``` + +## Step 4: Fix v6 breaking changes + +### Data-driven tests + +Pester 6 throws for `$null` or an empty `-ForEach`/`-TestCases`. Prefer fixing +the data-loading path. If empty data is a valid result, state that intent: + +```powershell +Describe 'Optional cases' -ForEach $cases -AllowNullOrEmptyForEach { + It 'runs when a case exists' {} +} +``` + +Use the local opt-in before the run-wide +`$config.Run.FailOnNullOrEmptyForEach = $false`; the latter can hide a broken +data source. + +### Setup and teardown blocks + +Each block can contain only one `BeforeAll`, `BeforeEach`, `AfterAll`, and +`AfterEach` at its scope. Combine duplicate blocks and preserve their required +ordering explicitly. Do not move discovery-time test generation into +`BeforeAll`; use `BeforeDiscovery` for that. + +### Mocks + +Replace removed assertions: + +```powershell +# Old +Assert-MockCalled Get-Thing -Times 1 -Exactly +Assert-VerifiableMock + +# v6 +Should -Invoke Get-Thing -Times 1 -Exactly +Should -InvokeVerifiable +``` + +In v6, a call that matches no `-ParameterFilter` no longer falls through to +the real command. Add an unfiltered default mock when other calls are valid: + +```powershell +Mock Get-Thing { 'default' } +Mock Get-Thing -ParameterFilter { $Name -eq 'a' } -MockWith { 'a' } +``` + +Keep mocks and their assertions in the scope where the code under test invokes +them. A migration must not accidentally allow a real external call. + +### Pending tests + +`Set-ItResult -Pending` is removed. Use the result that expresses the intent: + +```powershell +It 'is not implemented yet' { + Set-ItResult -Inconclusive -Because 'not implemented yet' +} +``` + +Use `-Skip` when the test must not run, and `-Inconclusive` when the result +should be reported for follow-up. + +### Name templates + +In v6, every `<...>` token in a `Describe`, `Context`, or `It` name is +evaluated as a PowerShell expression in the test scope. Review arithmetic, +method calls, and expressions that were literal in v5. Escape a leading `<` +when literal text is intended: + +```powershell +It 'adds up to `<($a + $b)`>' -ForEach @{ a = 1; b = 2 } {} +``` + +Keep names stable and useful for CI result reporting. + +### Tags + +`None` is reserved, case-insensitively, to select tests with no inherited or +local tags. Rename a tag that relied on the old literal meaning and update +filters and reports. + +### Coverage + +Pester 6 uses the Profiler tracer by default and `CodeCoverage.UseBreakpoints` +defaults to `$false`. Keep the new default unless compatibility with historical +coverage numbers requires: + +```powershell +$config.CodeCoverage.UseBreakpoints = $true +``` + +`CoverageGutters` is removed. Use `JaCoCo` or `Cobertura`; coverage paths are +already relative to `Run.RepoRoot`. + +## Step 5: Standardize Invoke-Pester configuration + +Legacy v4 parameters such as `-Script`, `-OutputFile`, `-OutputFormat`, +`-EnableExit`, and direct coverage switches are removed. Use one configuration +object for scripted and CI runs: + +```powershell +$config = New-PesterConfiguration +$config.Run.Path = @('./tests') +$config.Run.Exit = $true +$config.Output.Verbosity = 'Detailed' + +$config.TestResult.Enabled = $true +$config.TestResult.OutputPath = './artifacts/pester-results.xml' +$config.TestResult.OutputFormat = 'NUnitXml' + +$config.CodeCoverage.Enabled = $true +$config.CodeCoverage.Path = @('./src') +$config.CodeCoverage.OutputFormat = 'JaCoCo' + +Invoke-Pester -Configuration $config +``` + +Set `Run.ExcludePath` for intentional exclusions, and keep paths relative to +the repository root where CI and local runs share the same layout. Do not +disable failures globally to make a migration green. + +## Step 6: Optional v6 features + +Only after the serial suite matches the baseline may a repository evaluate: + +```powershell +$config.Run.Shuffle = $true +$config.Run.Parallel = $true +``` + +`Run.Shuffle` detects order dependence. Fix order dependence rather than +permanently suppressing it. `Run.Parallel` is experimental and runs files in +separate runspaces. Prove that setup, mocks, environment variables, ports, +temporary paths, external resources, and cleanup are isolated. Use +`Pester.BeforeContainer.ps1` for shared bootstrap and `#pester:no-parallel` +only for a documented exception. Compare serial and parallel result counts and +artifacts. + +The optional `Should-*` commands are a separate modernization. Classic +`Should -Be` remains valid in v6: + +```powershell +$value | Should -Be 1 # compatible and may remain +$value | Should-Be 1 # optional v6 style +``` + +If converting, review behavior rather than applying a blind rename: + +- `Should -Not -Be` becomes `Should-NotBe`. +- Truthy/falsy expectations may need `Should-BeTruthy` or `Should-BeFalsy`; + strict boolean assertions are different. +- `Should -BeNullOrEmpty` has different intents: null, empty string, empty + collection, or falsy. +- Collection comparisons use collection assertions and may need `-Actual` + because pipeline input is unwrapped. +- `Should -Exist` and file-content assertions can remain classic. + +Adopt this style incrementally and report intentionally unchanged assertions. + +## Step 7: Validate and report + +Run the migrated test set in this order: + +1. Every discovered file directly, including hidden paths and files selected + by configuration or container scripts. +2. Each test set serially with Pester 6.1.0. +3. Each supported PowerShell runtime and CI operating system. +4. Coverage and test-result generation with the same configuration CI uses. +5. Optional shuffle and parallel runs, only if the repository opted in. + +For every run, record the command, runtime, Pester version, path, passed, +failed, skipped, inconclusive, not-run, coverage summary, and artifact paths. +Compare against the baseline and investigate changed counts. A report should +include: + +```text +Repository: +Target: Pester 6.1.0 +Test set: +Runtime / OS: +Baseline: +Serial result: +Coverage / result artifacts: +Required compatibility fixes: +Optional v6 features enabled: +Known limitations or deferred work: +``` + +Review the diff for test-intent changes, accidental real calls, path assumptions, +and generated artifacts before committing. Make small commits by file or +concern so a failed migration is easy to bisect. + +## References + +- [Pester v5-to-v6 migration](https://pester.dev/docs/migrations/v5-to-v6) +- [Pester installation and compatibility](https://pester.dev/docs/introduction/installation) +- [Pester configuration](https://pester.dev/docs/usage/configuration) +- [Pester data-driven tests](https://pester.dev/docs/usage/data-driven-tests) +- [Pester mocking](https://pester.dev/docs/usage/mocking) +- [Pester parallel execution](https://pester.dev/docs/usage/parallel) +- [Pester code coverage](https://pester.dev/docs/usage/code-coverage) +- [Pester test results](https://pester.dev/docs/usage/test-results) +- [Pester Should assertions](https://pester.dev/docs/assertions/should-command) +- [Awesome Copilot pester-migration](https://github.com/github/awesome-copilot/tree/main/skills/pester-migration) +- [Awesome Copilot pester-should-migration](https://github.com/github/awesome-copilot/tree/main/skills/pester-should-migration) From 8927592babd64b7c774f4d1fc3fc6d27601c2817 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 17:30:13 +0200 Subject: [PATCH 02/22] docs: document PSModule test state contract Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- docs/content/guides/pester-migration.md | 14 +++- skills/pester-migration/SKILL.md | 99 ++++++++++++++++++++++++- 2 files changed, 108 insertions(+), 5 deletions(-) diff --git a/docs/content/guides/pester-migration.md b/docs/content/guides/pester-migration.md index 773fcd6f..35a91b31 100644 --- a/docs/content/guides/pester-migration.md +++ b/docs/content/guides/pester-migration.md @@ -14,12 +14,22 @@ The migration covers repository and test-set inventory, supported PowerShell runtime and CI checks, per-file discovery and run isolation, hidden paths, data-driven tests, setup blocks, mocks, pending tests, name templates, coverage, `Invoke-Pester` configuration, reserved tags, and validation -reporting. It does not migrate consumer repositories as part of this framework -change. +reporting. It also defines the test-state/data contract: module-local tests +consume the target module already loaded by Process-PSModule and explicitly +load any PSD1 or other fixture data. They must not silently import the module as +a substitute for framework setup. It does not migrate consumer repositories as +part of this framework change. ## Required before declaring a migration complete - Every test entry point is inventoried and runs on its supported runtime matrix. +- The target module is loaded by the framework before module-local Pester tests; + tests do not hide a missing load with `Import-Module`. +- Every PSD1, JSON, CSV, XML, script, generated fixture, secret, variable, and + service dependency has an owner and explicit loading phase. +- `Invoke-Pester`, `Test-PSModule`, module-local/source workflows, + `BeforeAll`/`AfterAll`, `Expose-TestData`, result/coverage collectors, and + linter result publishing are included in the repository inventory. - Pester 6.1.0 is imported in local and CI acceptance runs. - Each test file is self-contained under per-file discovery and run. - Hidden paths, empty data, duplicate setup blocks, mocks, pending tests, name diff --git a/skills/pester-migration/SKILL.md b/skills/pester-migration/SKILL.md index 2175bce3..7b659c9c 100644 --- a/skills/pester-migration/SKILL.md +++ b/skills/pester-migration/SKILL.md @@ -86,6 +86,96 @@ For each test set, add an inventory row to the migration report: Use the inventory to find test sets that are not reachable from the default workflow. A green workflow is not evidence that every test set was migrated. +## Test-state and data contract + +Treat the test runner's prepared state as a contract, not an implementation +detail. A module-local Pester test must assume that the target, built module is +already loaded by the framework. It must not silently call `Import-Module`, +`Install-Module`, `Install-PSModule`, or dot-source the target module as a +fallback when the framework did not prepare it. A hidden import can make local +tests pass while the real workflow is misconfigured and can change the module +version or process state being tested. + +This does not prohibit a test whose explicit subject is module import, +manifest validity, or module removal. Such a framework or contract test should +say so in its name and use a deliberate, isolated import as the behavior under +test. It must not become setup for unrelated tests. + +Every additional fixture is also part of the test-state contract. A test set +must explicitly load its own JSON, CSV, XML, PSD1, script, or generated data, +or document which setup phase provides it. In particular, a PSD1 dataset is +not automatically loaded because it is in the repository: + +```powershell +BeforeDiscovery { + $cases = Import-PowerShellDataFile -Path (Join-Path $PSScriptRoot 'Data\Cases.psd1') +} +``` + +Record fixture ownership and availability in the inventory: + +| Fixture or state | Owner | Loaded in | Required environment | +| --- | --- | --- | --- | +| Target module | Process-PSModule or explicit contract test | Framework pre-run | Built module path and version | +| PSD1/JSON/CSV data | Test set or documented setup | `BeforeDiscovery`, `BeforeAll`, or setup job | Relative path and encoding | +| Secrets/variables | Calling workflow | `Expose-TestData` and environment | `TestData` JSON contract | +| Shared service | `tests/BeforeAll.ps1` | Before module-local matrix | Deterministic run-scoped name | +| Cleanup state | `tests/AfterAll.ps1` | Always-run teardown | Same `TestData` and run identity | + +Fail loudly when required data or state is absent. Do not use a broad +`try/catch`, an empty default, or an implicit import to turn a missing fixture +into a passing or skipped test. + +## Process-PSModule test-adjacent surfaces + +For every consumer repository, trace and record these surfaces before editing: + +| Surface | Framework contract to verify | Migration check | +| --- | --- | --- | +| `PSModule/Invoke-Pester` | Installs/runs Pester and emits per-suite JSON results and coverage artifacts | Pin/verify Pester 6.1.0, map all inputs to v6 configuration, preserve suite names | +| `Test-PSModule` action | Selects `tests/Module` or `tests/SourceCode`, resolves `outputs/module` or `src`, and passes paths to `Invoke-Pester` | Confirm path selection, exclusions, module state, and test extension | +| Module-local workflow | Downloads the built module, exposes `TestData`, imports the module, then runs module tests | Tests consume the prepared module; no hidden fallback import | +| Source-code workflow | Runs source tests against the checked-out `src` path | Record how source functions/classes are loaded and which fixtures are explicit | +| `BeforeAll-ModuleLocal` | Runs exact root `tests/BeforeAll.ps1` once before module-local jobs | Put shared services/data here only when every matrix job needs them | +| `AfterAll-ModuleLocal` | Runs exact root `tests/AfterAll.ps1` with `always()` | Make cleanup safe after setup/test failure | +| `Expose-TestData` | Converts caller `TestData` JSON into environment variables | Inventory every required variable; do not confuse it with repository fixtures | +| `Get-PesterTestResults` | Downloads `*-TestResults`, expects every configured suite, and fails missing/unexecuted/failed/inconclusive results | Preserve `TestSuiteName`, matrix names, and result counts | +| `Get-PesterCodeCoverage` | Aggregates `*-CodeCoverage` JSON and writes missed-path reports and summaries | Verify JaCoCo/Cobertura format, target, paths, and v6 tracer behavior | +| `Invoke-ScriptAnalyzer` integration | Publishes `PSModuleLint-*` results alongside test results | Treat lint suites as required result artifacts, not Pester test files | +| Repository linter | Checks repository/workflow/Markdown files independently of Pester | Include skill and documentation paths in the repository lint inventory | + +The current Process-PSModule flow specifically downloads the built module and +imports it before module-local tests, while `Test-PSModule` resolves source or +module paths for framework suites. The framework's own importability and +manifest tests may import/remove the module because import is their subject; +ordinary consumer tests must not copy that pattern as setup. + +Record the `PSModule/Invoke-Pester` action revision separately from the Pester +module version. The current Process-PSModule workflows reference that action at +`v5.1.0`; its revision and its Pester installation policy must both be checked +when adopting Pester 6.1.0. Updating one does not prove that the other changed. + +Use this per-repository checklist: + +- [ ] All `*.Tests.ps1`, `*.Configuration.ps1`, and `*.Container.ps1` files, + including action and hidden paths, are listed. +- [ ] Each test set is mapped to `Module`, `SourceCode`, action, or external + invocation and its `Run.Path`/`Run.ExcludePath` is recorded. +- [ ] The built target module is loaded by the framework before module-local + tests; tests do not silently load it themselves. +- [ ] Source-code test loading is explicit and documented separately from the + module-local contract. +- [ ] Every PSD1, JSON, CSV, XML, script, generated fixture, secret, variable, + and service dependency has an owner and loading phase. +- [ ] `BeforeAll.ps1`, `AfterAll.ps1`, and `Pester.BeforeContainer.ps1` paths + and scope are recorded. +- [ ] `Invoke-Pester` action inputs, Pester version, suite names, result paths, + coverage paths, filters, and output formats are recorded. +- [ ] `Get-PesterTestResults` expected artifact names include source, framework, + module, and linter suites. +- [ ] Coverage aggregation and its missed-path report are validated. +- [ ] Local, CI, and linter runs use the same intended fixture and module state. + ## Step 2: Check versions, runtime, and CI Run the baseline on the current version before changing files. Save the command, @@ -135,7 +225,8 @@ BeforeDiscovery { } BeforeAll { - Import-Module (Join-Path $PSScriptRoot '..\src\MyModule.psd1') -Force + # Consume the module loaded by the framework. + $command = Get-Command -Name Get-MyThing -ErrorAction Stop } Describe 'My command' { @@ -145,8 +236,10 @@ Describe 'My command' { } ``` -Use `$PSScriptRoot` for paths. Do not rely on `$MyInvocation.MyCommand.Path`, -the current directory, another test file's variables, or discovery order. +Use `$PSScriptRoot` for fixture paths. Do not rely on +`$MyInvocation.MyCommand.Path`, the current directory, another test file's +variables, or discovery order. If the command check fails, fix the workflow's +module preparation rather than adding an import to this test. Repository-wide bootstrap that every worker needs belongs in `Pester.BeforeContainer.ps1` at the repository root. Keep it deterministic and idempotent. From 75fdefebd996e96dcb941e48f003433d0763c334 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 17:35:04 +0200 Subject: [PATCH 03/22] feat: add PSModule process marketplace Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/plugin/README.md | 27 +++++++++++++++++++ .github/plugin/marketplace.json | 18 +++++++++++++ .../plugins/psmodule-process/plugin.json | 19 +++++++++++++ .../skills}/pester-migration/SKILL.md | 0 docs/content/guides/pester-migration.md | 6 +++-- docs/content/index.md | 1 + 6 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 .github/plugin/README.md create mode 100644 .github/plugin/marketplace.json create mode 100644 .github/plugin/plugins/psmodule-process/plugin.json rename {skills => .github/plugin/plugins/psmodule-process/skills}/pester-migration/SKILL.md (100%) diff --git a/.github/plugin/README.md b/.github/plugin/README.md new file mode 100644 index 00000000..477c661b --- /dev/null +++ b/.github/plugin/README.md @@ -0,0 +1,27 @@ +# PSModule process marketplace + +This repository is a GitHub Copilot CLI plugin marketplace. The marketplace +and its `psmodule-process` plugin are versioned **1.0.0**. + +## Install + +Add the marketplace and install the plugin: + +```console +copilot plugin marketplace add PSModule/Process-PSModule +copilot plugin install psmodule-process +``` + +The plugin provides the +[`pester-migration`](./plugins/psmodule-process/skills/pester-migration/SKILL.md) +skill for migrating every Pester test set in a PSModule repository to Pester +6.1.0. Verify the installation with: + +```console +copilot plugin list +/skills list +``` + +The marketplace manifest is +[`marketplace.json`](./marketplace.json); plugin metadata is in +[`plugin.json`](./plugins/psmodule-process/plugin.json). diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json new file mode 100644 index 00000000..9ff447ea --- /dev/null +++ b/.github/plugin/marketplace.json @@ -0,0 +1,18 @@ +{ + "name": "psmodule-process", + "owner": { + "name": "PSModule" + }, + "metadata": { + "description": "Plugins for building, testing, documenting, and publishing PowerShell modules with the PSModule process.", + "version": "1.0.0" + }, + "plugins": [ + { + "name": "psmodule-process", + "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", + "version": "1.0.0", + "source": "./plugins/psmodule-process" + } + ] +} diff --git a/.github/plugin/plugins/psmodule-process/plugin.json b/.github/plugin/plugins/psmodule-process/plugin.json new file mode 100644 index 00000000..cf185a43 --- /dev/null +++ b/.github/plugin/plugins/psmodule-process/plugin.json @@ -0,0 +1,19 @@ +{ + "name": "psmodule-process", + "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", + "version": "1.0.0", + "author": { + "name": "PSModule", + "url": "https://github.com/PSModule" + }, + "repository": "https://github.com/PSModule/Process-PSModule", + "license": "MIT", + "keywords": [ + "powershell", + "psmodule", + "pester", + "testing", + "github-actions" + ], + "skills": "skills/" +} diff --git a/skills/pester-migration/SKILL.md b/.github/plugin/plugins/psmodule-process/skills/pester-migration/SKILL.md similarity index 100% rename from skills/pester-migration/SKILL.md rename to .github/plugin/plugins/psmodule-process/skills/pester-migration/SKILL.md diff --git a/docs/content/guides/pester-migration.md b/docs/content/guides/pester-migration.md index 35a91b31..c6b45653 100644 --- a/docs/content/guides/pester-migration.md +++ b/docs/content/guides/pester-migration.md @@ -5,8 +5,10 @@ description: A repository-wide checklist for migrating PSModule test sets to Pes # Migrating Pester tests -Use the reusable [`pester-migration`](https://github.com/PSModule/Process-PSModule/tree/main/skills/pester-migration/SKILL.md) -agent skill to migrate every Pester test set in a PSModule repository. It is +Install the version 1.0.0 [`psmodule-process` marketplace +plugin](https://github.com/PSModule/Process-PSModule/tree/main/.github/plugin/marketplace.json) +and use its reusable `pester-migration` agent skill to migrate every Pester test +set in a PSModule repository. It is written for Pester **6.1.0** and distinguishes required compatibility changes from optional v6 modernization. diff --git a/docs/content/index.md b/docs/content/index.md index 800c9189..1456967d 100644 --- a/docs/content/index.md +++ b/docs/content/index.md @@ -41,6 +41,7 @@ Task-oriented deep dives into the pipeline's functionality. | [Structuring your module](guides/structuring-your-module.md) | The repository and module source layout the workflow expects, and how to declare dependencies. | | [Writing module tests](guides/writing-module-tests.md) | Test discovery, setup and teardown phases, and shared test infrastructure. | | [Migrating Pester tests](guides/pester-migration.md) | A repository-wide checklist for migrating every test set to Pester 6.1.0. | +| [PSModule process marketplace](https://github.com/PSModule/Process-PSModule/tree/main/.github/plugin) | Install the version 1.0.0 Copilot CLI plugin and its reusable skills. | | [Skipping framework tests](guides/skipping-framework-tests.md) | Skip individual framework tests on a per-file basis. | | [Versioning and releases](guides/versioning-and-releases.md) | Label-driven versioning, prereleases, and what a release produces. | | [Validating before review](guides/validating-before-review.md) | The PSModule validation pass before a draft pull request is marked ready. | From 69cc0e34a1199ba02cbbd40938f32fe4c7d8cba4 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 17:36:45 +0200 Subject: [PATCH 04/22] fix: align marketplace with MSX plugin layout Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/plugin/README.md | 4 ++-- .github/plugin/marketplace.json | 2 +- .../plugin/plugins => plugins}/psmodule-process/plugin.json | 2 ++ .../psmodule-process/skills/pester-migration/SKILL.md | 0 4 files changed, 5 insertions(+), 3 deletions(-) rename {.github/plugin/plugins => plugins}/psmodule-process/plugin.json (79%) rename {.github/plugin/plugins => plugins}/psmodule-process/skills/pester-migration/SKILL.md (100%) diff --git a/.github/plugin/README.md b/.github/plugin/README.md index 477c661b..7d0a79e2 100644 --- a/.github/plugin/README.md +++ b/.github/plugin/README.md @@ -13,7 +13,7 @@ copilot plugin install psmodule-process ``` The plugin provides the -[`pester-migration`](./plugins/psmodule-process/skills/pester-migration/SKILL.md) +[`pester-migration`](../../plugins/psmodule-process/skills/pester-migration/SKILL.md) skill for migrating every Pester test set in a PSModule repository to Pester 6.1.0. Verify the installation with: @@ -24,4 +24,4 @@ copilot plugin list The marketplace manifest is [`marketplace.json`](./marketplace.json); plugin metadata is in -[`plugin.json`](./plugins/psmodule-process/plugin.json). +[`plugin.json`](../../plugins/psmodule-process/plugin.json). diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index 9ff447ea..e03b483b 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -12,7 +12,7 @@ "name": "psmodule-process", "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", "version": "1.0.0", - "source": "./plugins/psmodule-process" + "source": "plugins/psmodule-process" } ] } diff --git a/.github/plugin/plugins/psmodule-process/plugin.json b/plugins/psmodule-process/plugin.json similarity index 79% rename from .github/plugin/plugins/psmodule-process/plugin.json rename to plugins/psmodule-process/plugin.json index cf185a43..9be5e8ce 100644 --- a/.github/plugin/plugins/psmodule-process/plugin.json +++ b/plugins/psmodule-process/plugin.json @@ -1,4 +1,5 @@ { + "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "psmodule-process", "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", "version": "1.0.0", @@ -6,6 +7,7 @@ "name": "PSModule", "url": "https://github.com/PSModule" }, + "homepage": "https://psmodule.io/docs/", "repository": "https://github.com/PSModule/Process-PSModule", "license": "MIT", "keywords": [ diff --git a/.github/plugin/plugins/psmodule-process/skills/pester-migration/SKILL.md b/plugins/psmodule-process/skills/pester-migration/SKILL.md similarity index 100% rename from .github/plugin/plugins/psmodule-process/skills/pester-migration/SKILL.md rename to plugins/psmodule-process/skills/pester-migration/SKILL.md From 4208d0a935d71d831e02be137d099218f23b912a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 17:38:22 +0200 Subject: [PATCH 05/22] refactor: hide marketplace plugin sources Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- {plugins => .github/plugin/plugins}/psmodule-process/plugin.json | 0 .../plugins}/psmodule-process/skills/pester-migration/SKILL.md | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {plugins => .github/plugin/plugins}/psmodule-process/plugin.json (100%) rename {plugins => .github/plugin/plugins}/psmodule-process/skills/pester-migration/SKILL.md (100%) diff --git a/plugins/psmodule-process/plugin.json b/.github/plugin/plugins/psmodule-process/plugin.json similarity index 100% rename from plugins/psmodule-process/plugin.json rename to .github/plugin/plugins/psmodule-process/plugin.json diff --git a/plugins/psmodule-process/skills/pester-migration/SKILL.md b/.github/plugin/plugins/psmodule-process/skills/pester-migration/SKILL.md similarity index 100% rename from plugins/psmodule-process/skills/pester-migration/SKILL.md rename to .github/plugin/plugins/psmodule-process/skills/pester-migration/SKILL.md From 6aec0ec137060233d528dca8d017cc2117a4e80c Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 17:38:31 +0200 Subject: [PATCH 06/22] docs: update hidden marketplace links Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/plugin/README.md | 4 ++-- .github/plugin/marketplace.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/plugin/README.md b/.github/plugin/README.md index 7d0a79e2..477c661b 100644 --- a/.github/plugin/README.md +++ b/.github/plugin/README.md @@ -13,7 +13,7 @@ copilot plugin install psmodule-process ``` The plugin provides the -[`pester-migration`](../../plugins/psmodule-process/skills/pester-migration/SKILL.md) +[`pester-migration`](./plugins/psmodule-process/skills/pester-migration/SKILL.md) skill for migrating every Pester test set in a PSModule repository to Pester 6.1.0. Verify the installation with: @@ -24,4 +24,4 @@ copilot plugin list The marketplace manifest is [`marketplace.json`](./marketplace.json); plugin metadata is in -[`plugin.json`](../../plugins/psmodule-process/plugin.json). +[`plugin.json`](./plugins/psmodule-process/plugin.json). diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index e03b483b..360070ab 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -12,7 +12,7 @@ "name": "psmodule-process", "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", "version": "1.0.0", - "source": "plugins/psmodule-process" + "source": ".github/plugin/plugins/psmodule-process" } ] } From 1a3f83c47df6d186518de5813812ab1c483d6fea Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 17:39:44 +0200 Subject: [PATCH 07/22] refactor: use shared MSX plugin marketplace Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/plugin/README.md | 19 ++++++++++--------- .github/plugin/marketplace.json | 18 ------------------ docs/content/guides/pester-migration.md | 10 ++++++---- docs/content/index.md | 2 +- 4 files changed, 17 insertions(+), 32 deletions(-) delete mode 100644 .github/plugin/marketplace.json diff --git a/.github/plugin/README.md b/.github/plugin/README.md index 477c661b..d8e6a385 100644 --- a/.github/plugin/README.md +++ b/.github/plugin/README.md @@ -1,15 +1,15 @@ -# PSModule process marketplace +# PSModule process plugin -This repository is a GitHub Copilot CLI plugin marketplace. The marketplace -and its `psmodule-process` plugin are versioned **1.0.0**. +This repository hosts the canonical `psmodule-process` GitHub Copilot CLI +plugin. The shared MSXOrg marketplace publishes this plugin alongside the +other initiative plugins. -## Install +## Install directly -Add the marketplace and install the plugin: +Install the plugin directly from this repository: ```console -copilot plugin marketplace add PSModule/Process-PSModule -copilot plugin install psmodule-process +copilot plugin install PSModule/Process-PSModule:.github/plugin/plugins/psmodule-process ``` The plugin provides the @@ -22,6 +22,7 @@ copilot plugin list /skills list ``` -The marketplace manifest is -[`marketplace.json`](./marketplace.json); plugin metadata is in +The shared marketplace is maintained in +[MSXOrg/docs](https://github.com/MSXOrg/docs/tree/main/.github/plugin). +Plugin metadata is in [`plugin.json`](./plugins/psmodule-process/plugin.json). diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json deleted file mode 100644 index 360070ab..00000000 --- a/.github/plugin/marketplace.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "psmodule-process", - "owner": { - "name": "PSModule" - }, - "metadata": { - "description": "Plugins for building, testing, documenting, and publishing PowerShell modules with the PSModule process.", - "version": "1.0.0" - }, - "plugins": [ - { - "name": "psmodule-process", - "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", - "version": "1.0.0", - "source": ".github/plugin/plugins/psmodule-process" - } - ] -} diff --git a/docs/content/guides/pester-migration.md b/docs/content/guides/pester-migration.md index c6b45653..11dca4c8 100644 --- a/docs/content/guides/pester-migration.md +++ b/docs/content/guides/pester-migration.md @@ -5,10 +5,12 @@ description: A repository-wide checklist for migrating PSModule test sets to Pes # Migrating Pester tests -Install the version 1.0.0 [`psmodule-process` marketplace -plugin](https://github.com/PSModule/Process-PSModule/tree/main/.github/plugin/marketplace.json) -and use its reusable `pester-migration` agent skill to migrate every Pester test -set in a PSModule repository. It is +Install the `psmodule-process` plugin from the shared +[MSXOrg marketplace](https://github.com/MSXOrg/docs/tree/main/.github/plugin) +and use its reusable `pester-migration` agent skill to migrate every Pester +test set in a PSModule repository. For direct installation during development, +use `copilot plugin install +PSModule/Process-PSModule:.github/plugin/plugins/psmodule-process`. It is written for Pester **6.1.0** and distinguishes required compatibility changes from optional v6 modernization. diff --git a/docs/content/index.md b/docs/content/index.md index 1456967d..ff6c88bb 100644 --- a/docs/content/index.md +++ b/docs/content/index.md @@ -41,7 +41,7 @@ Task-oriented deep dives into the pipeline's functionality. | [Structuring your module](guides/structuring-your-module.md) | The repository and module source layout the workflow expects, and how to declare dependencies. | | [Writing module tests](guides/writing-module-tests.md) | Test discovery, setup and teardown phases, and shared test infrastructure. | | [Migrating Pester tests](guides/pester-migration.md) | A repository-wide checklist for migrating every test set to Pester 6.1.0. | -| [PSModule process marketplace](https://github.com/PSModule/Process-PSModule/tree/main/.github/plugin) | Install the version 1.0.0 Copilot CLI plugin and its reusable skills. | +| [PSModule process plugin](https://github.com/PSModule/Process-PSModule/tree/main/.github/plugin) | Install the plugin directly or through the shared MSXOrg marketplace. | | [Skipping framework tests](guides/skipping-framework-tests.md) | Skip individual framework tests on a per-file basis. | | [Versioning and releases](guides/versioning-and-releases.md) | Label-driven versioning, prereleases, and what a release produces. | | [Validating before review](guides/validating-before-review.md) | The PSModule validation pass before a draft pull request is marked ready. | From ab2a135cacfd7ca518149602fe8ed1b5eeab19c7 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 18:00:48 +0200 Subject: [PATCH 08/22] feat: own PSModule plugin marketplace Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/plugin/README.md | 20 ++++++++++++++------ .github/plugin/marketplace.json | 19 +++++++++++++++++++ docs/content/guides/pester-migration.md | 12 +++++++++--- docs/content/index.md | 2 +- 4 files changed, 43 insertions(+), 10 deletions(-) create mode 100644 .github/plugin/marketplace.json diff --git a/.github/plugin/README.md b/.github/plugin/README.md index d8e6a385..86e66ebb 100644 --- a/.github/plugin/README.md +++ b/.github/plugin/README.md @@ -1,8 +1,17 @@ # PSModule process plugin -This repository hosts the canonical `psmodule-process` GitHub Copilot CLI -plugin. The shared MSXOrg marketplace publishes this plugin alongside the -other initiative plugins. +This repository hosts the `psmodule` GitHub Copilot CLI marketplace and its +`psmodule-process` plugin. The marketplace and plugin are owned and released +with the PSModule process. + +## Install through the marketplace + +Register this repository's marketplace and install the plugin: + +```console +copilot plugin marketplace add https://github.com/PSModule/Process-PSModule.git +copilot plugin install psmodule-process +``` ## Install directly @@ -22,7 +31,6 @@ copilot plugin list /skills list ``` -The shared marketplace is maintained in -[MSXOrg/docs](https://github.com/MSXOrg/docs/tree/main/.github/plugin). -Plugin metadata is in +The marketplace catalog is in [`marketplace.json`](./marketplace.json), and +plugin metadata is in [`plugin.json`](./plugins/psmodule-process/plugin.json). diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json new file mode 100644 index 00000000..d6533a01 --- /dev/null +++ b/.github/plugin/marketplace.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://agent-plugins.org/schemas/1.0.0/marketplace.schema.json", + "name": "psmodule", + "owner": { + "name": "PSModule" + }, + "metadata": { + "description": "Agent plugins for the PSModule repository process.", + "version": "1.0.0" + }, + "plugins": [ + { + "name": "psmodule-process", + "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", + "version": "1.0.0", + "source": "plugins/psmodule-process" + } + ] +} diff --git a/docs/content/guides/pester-migration.md b/docs/content/guides/pester-migration.md index 11dca4c8..b7c63045 100644 --- a/docs/content/guides/pester-migration.md +++ b/docs/content/guides/pester-migration.md @@ -5,9 +5,15 @@ description: A repository-wide checklist for migrating PSModule test sets to Pes # Migrating Pester tests -Install the `psmodule-process` plugin from the shared -[MSXOrg marketplace](https://github.com/MSXOrg/docs/tree/main/.github/plugin) -and use its reusable `pester-migration` agent skill to migrate every Pester +Register the PSModule initiative marketplace and install its `psmodule-process` +plugin: + +```console +copilot plugin marketplace add https://github.com/PSModule/Process-PSModule.git +copilot plugin install psmodule-process +``` + +Then use its reusable `pester-migration` agent skill to migrate every Pester test set in a PSModule repository. For direct installation during development, use `copilot plugin install PSModule/Process-PSModule:.github/plugin/plugins/psmodule-process`. It is diff --git a/docs/content/index.md b/docs/content/index.md index ff6c88bb..50ab0a04 100644 --- a/docs/content/index.md +++ b/docs/content/index.md @@ -41,7 +41,7 @@ Task-oriented deep dives into the pipeline's functionality. | [Structuring your module](guides/structuring-your-module.md) | The repository and module source layout the workflow expects, and how to declare dependencies. | | [Writing module tests](guides/writing-module-tests.md) | Test discovery, setup and teardown phases, and shared test infrastructure. | | [Migrating Pester tests](guides/pester-migration.md) | A repository-wide checklist for migrating every test set to Pester 6.1.0. | -| [PSModule process plugin](https://github.com/PSModule/Process-PSModule/tree/main/.github/plugin) | Install the plugin directly or through the shared MSXOrg marketplace. | +| [PSModule process marketplace](https://github.com/PSModule/Process-PSModule/tree/main/.github/plugin) | Register the initiative marketplace and install the PSModule process plugin. | | [Skipping framework tests](guides/skipping-framework-tests.md) | Skip individual framework tests on a per-file basis. | | [Versioning and releases](guides/versioning-and-releases.md) | Label-driven versioning, prereleases, and what a release produces. | | [Validating before review](guides/validating-before-review.md) | The PSModule validation pass before a draft pull request is marked ready. | From b8e77875d55e65ab41f59b22ae89e3fecf9825fb Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 18:04:37 +0200 Subject: [PATCH 09/22] refactor: flatten plugin marketplace layout Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/plugin/README.md | 6 +++--- .github/plugin/marketplace.json | 2 +- .github/plugin/{plugins => }/psmodule-process/plugin.json | 0 .../psmodule-process/skills/pester-migration/SKILL.md | 0 docs/content/guides/pester-migration.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename .github/plugin/{plugins => }/psmodule-process/plugin.json (100%) rename .github/plugin/{plugins => }/psmodule-process/skills/pester-migration/SKILL.md (100%) diff --git a/.github/plugin/README.md b/.github/plugin/README.md index 86e66ebb..9fc939e1 100644 --- a/.github/plugin/README.md +++ b/.github/plugin/README.md @@ -18,11 +18,11 @@ copilot plugin install psmodule-process Install the plugin directly from this repository: ```console -copilot plugin install PSModule/Process-PSModule:.github/plugin/plugins/psmodule-process +copilot plugin install PSModule/Process-PSModule:.github/plugin/psmodule-process ``` The plugin provides the -[`pester-migration`](./plugins/psmodule-process/skills/pester-migration/SKILL.md) +[`pester-migration`](./psmodule-process/skills/pester-migration/SKILL.md) skill for migrating every Pester test set in a PSModule repository to Pester 6.1.0. Verify the installation with: @@ -33,4 +33,4 @@ copilot plugin list The marketplace catalog is in [`marketplace.json`](./marketplace.json), and plugin metadata is in -[`plugin.json`](./plugins/psmodule-process/plugin.json). +[`plugin.json`](./psmodule-process/plugin.json). diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index d6533a01..d180b535 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -13,7 +13,7 @@ "name": "psmodule-process", "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", "version": "1.0.0", - "source": "plugins/psmodule-process" + "source": "psmodule-process" } ] } diff --git a/.github/plugin/plugins/psmodule-process/plugin.json b/.github/plugin/psmodule-process/plugin.json similarity index 100% rename from .github/plugin/plugins/psmodule-process/plugin.json rename to .github/plugin/psmodule-process/plugin.json diff --git a/.github/plugin/plugins/psmodule-process/skills/pester-migration/SKILL.md b/.github/plugin/psmodule-process/skills/pester-migration/SKILL.md similarity index 100% rename from .github/plugin/plugins/psmodule-process/skills/pester-migration/SKILL.md rename to .github/plugin/psmodule-process/skills/pester-migration/SKILL.md diff --git a/docs/content/guides/pester-migration.md b/docs/content/guides/pester-migration.md index b7c63045..6bc27d22 100644 --- a/docs/content/guides/pester-migration.md +++ b/docs/content/guides/pester-migration.md @@ -16,7 +16,7 @@ copilot plugin install psmodule-process Then use its reusable `pester-migration` agent skill to migrate every Pester test set in a PSModule repository. For direct installation during development, use `copilot plugin install -PSModule/Process-PSModule:.github/plugin/plugins/psmodule-process`. It is +PSModule/Process-PSModule:.github/plugin/psmodule-process`. It is written for Pester **6.1.0** and distinguishes required compatibility changes from optional v6 modernization. From b41e4317cc1bb454c505fa318f2371e01b3c50c5 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 18:05:17 +0200 Subject: [PATCH 10/22] fix: use repository relative plugin source Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/plugin/marketplace.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index d180b535..60060f4d 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -13,7 +13,7 @@ "name": "psmodule-process", "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", "version": "1.0.0", - "source": "psmodule-process" + "source": ".github/plugin/psmodule-process" } ] } From 764ff6e07e3ceec286e3cf9c61518d75ee97e2fb Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 18:07:09 +0200 Subject: [PATCH 11/22] refactor: use canonical PSModule plugin name Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/plugin/README.md | 10 +++++----- .github/plugin/marketplace.json | 4 ++-- .../plugin/{psmodule-process => psmodule}/plugin.json | 2 +- .../skills/psmodule-pester-migration}/SKILL.md | 2 +- docs/content/guides/pester-migration.md | 8 ++++---- 5 files changed, 13 insertions(+), 13 deletions(-) rename .github/plugin/{psmodule-process => psmodule}/plugin.json (94%) rename .github/plugin/{psmodule-process/skills/pester-migration => psmodule/skills/psmodule-pester-migration}/SKILL.md (99%) diff --git a/.github/plugin/README.md b/.github/plugin/README.md index 9fc939e1..d4fd4b0a 100644 --- a/.github/plugin/README.md +++ b/.github/plugin/README.md @@ -1,7 +1,7 @@ # PSModule process plugin This repository hosts the `psmodule` GitHub Copilot CLI marketplace and its -`psmodule-process` plugin. The marketplace and plugin are owned and released +`psmodule` plugin. The marketplace and plugin are owned and released with the PSModule process. ## Install through the marketplace @@ -10,7 +10,7 @@ Register this repository's marketplace and install the plugin: ```console copilot plugin marketplace add https://github.com/PSModule/Process-PSModule.git -copilot plugin install psmodule-process +copilot plugin install psmodule ``` ## Install directly @@ -18,11 +18,11 @@ copilot plugin install psmodule-process Install the plugin directly from this repository: ```console -copilot plugin install PSModule/Process-PSModule:.github/plugin/psmodule-process +copilot plugin install PSModule/Process-PSModule:.github/plugin/psmodule ``` The plugin provides the -[`pester-migration`](./psmodule-process/skills/pester-migration/SKILL.md) +[`psmodule-pester-migration`](./psmodule/skills/psmodule-pester-migration/SKILL.md) skill for migrating every Pester test set in a PSModule repository to Pester 6.1.0. Verify the installation with: @@ -33,4 +33,4 @@ copilot plugin list The marketplace catalog is in [`marketplace.json`](./marketplace.json), and plugin metadata is in -[`plugin.json`](./psmodule-process/plugin.json). +[`plugin.json`](./psmodule/plugin.json). diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index 60060f4d..32ff5943 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -10,10 +10,10 @@ }, "plugins": [ { - "name": "psmodule-process", + "name": "psmodule", "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", "version": "1.0.0", - "source": ".github/plugin/psmodule-process" + "source": ".github/plugin/psmodule" } ] } diff --git a/.github/plugin/psmodule-process/plugin.json b/.github/plugin/psmodule/plugin.json similarity index 94% rename from .github/plugin/psmodule-process/plugin.json rename to .github/plugin/psmodule/plugin.json index 9be5e8ce..7b3cce75 100644 --- a/.github/plugin/psmodule-process/plugin.json +++ b/.github/plugin/psmodule/plugin.json @@ -1,6 +1,6 @@ { "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", - "name": "psmodule-process", + "name": "psmodule", "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", "version": "1.0.0", "author": { diff --git a/.github/plugin/psmodule-process/skills/pester-migration/SKILL.md b/.github/plugin/psmodule/skills/psmodule-pester-migration/SKILL.md similarity index 99% rename from .github/plugin/psmodule-process/skills/pester-migration/SKILL.md rename to .github/plugin/psmodule/skills/psmodule-pester-migration/SKILL.md index 7b659c9c..6a506707 100644 --- a/.github/plugin/psmodule-process/skills/pester-migration/SKILL.md +++ b/.github/plugin/psmodule/skills/psmodule-pester-migration/SKILL.md @@ -1,5 +1,5 @@ --- -name: pester-migration +name: psmodule-pester-migration description: Migrate every Pester test set in a PSModule repository to Pester 6.1.0, preserving test intent while checking runtime, discovery, setup, mocks, data-driven tests, coverage, CI, and reporting. Use when upgrading a PSModule repository from Pester 5 or earlier, or when validating a repository-wide Pester migration. --- diff --git a/docs/content/guides/pester-migration.md b/docs/content/guides/pester-migration.md index 6bc27d22..aa1383fb 100644 --- a/docs/content/guides/pester-migration.md +++ b/docs/content/guides/pester-migration.md @@ -5,18 +5,18 @@ description: A repository-wide checklist for migrating PSModule test sets to Pes # Migrating Pester tests -Register the PSModule initiative marketplace and install its `psmodule-process` +Register the PSModule initiative marketplace and install its `psmodule` plugin: ```console copilot plugin marketplace add https://github.com/PSModule/Process-PSModule.git -copilot plugin install psmodule-process +copilot plugin install psmodule ``` -Then use its reusable `pester-migration` agent skill to migrate every Pester +Then use its reusable `psmodule-pester-migration` agent skill to migrate every Pester test set in a PSModule repository. For direct installation during development, use `copilot plugin install -PSModule/Process-PSModule:.github/plugin/psmodule-process`. It is +PSModule/Process-PSModule:.github/plugin/psmodule`. It is written for Pester **6.1.0** and distinguishes required compatibility changes from optional v6 modernization. From 5ce33d77286f1897e82d9838bb6ffb581595d595 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 18:23:42 +0200 Subject: [PATCH 12/22] docs: link PSModule skill to source docs Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../psmodule/skills/psmodule-pester-migration/SKILL.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/plugin/psmodule/skills/psmodule-pester-migration/SKILL.md b/.github/plugin/psmodule/skills/psmodule-pester-migration/SKILL.md index 6a506707..c574c17e 100644 --- a/.github/plugin/psmodule/skills/psmodule-pester-migration/SKILL.md +++ b/.github/plugin/psmodule/skills/psmodule-pester-migration/SKILL.md @@ -451,6 +451,11 @@ concern so a failed migration is easy to bisect. ## References +- [PSModule module test guidance](https://github.com/PSModule/Process-PSModule/blob/main/docs/content/guides/writing-module-tests.md) +- [PSModule workflow and test data guidance](https://github.com/PSModule/Process-PSModule/blob/main/docs/content/guides/calling-the-workflow.md) +- [PSModule pipeline configuration](https://github.com/PSModule/Process-PSModule/blob/main/docs/content/guides/configuring-the-pipeline.md) +- [PSModule test specification](https://github.com/PSModule/Process-PSModule/blob/main/docs/content/reference/test-specification.md) +- [PSModule workflow inputs](https://github.com/PSModule/Process-PSModule/blob/main/docs/content/reference/workflow-inputs.md) - [Pester v5-to-v6 migration](https://pester.dev/docs/migrations/v5-to-v6) - [Pester installation and compatibility](https://pester.dev/docs/introduction/installation) - [Pester configuration](https://pester.dev/docs/usage/configuration) From 34af15a3190eb940f60f3a286f020acf7a727e95 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 18:26:15 +0200 Subject: [PATCH 13/22] feat: add Process-PSModule v8 upgrade skill Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/plugin/README.md | 5 +- .github/plugin/marketplace.json | 4 +- .github/plugin/psmodule/plugin.json | 2 +- .../skills/psmodule-v8-upgrade/SKILL.md | 189 ++++++++++++++++++ 4 files changed, 196 insertions(+), 4 deletions(-) create mode 100644 .github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md diff --git a/.github/plugin/README.md b/.github/plugin/README.md index d4fd4b0a..16b5e31a 100644 --- a/.github/plugin/README.md +++ b/.github/plugin/README.md @@ -24,7 +24,10 @@ copilot plugin install PSModule/Process-PSModule:.github/plugin/psmodule The plugin provides the [`psmodule-pester-migration`](./psmodule/skills/psmodule-pester-migration/SKILL.md) skill for migrating every Pester test set in a PSModule repository to Pester -6.1.0. Verify the installation with: +6.1.0, and the +[`psmodule-v8-upgrade`](./psmodule/skills/psmodule-v8-upgrade/SKILL.md) +skill for upgrading Process-PSModule consumer repositories to framework v8. +Verify the installation with: ```console copilot plugin list diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index 32ff5943..0f710916 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -6,13 +6,13 @@ }, "metadata": { "description": "Agent plugins for the PSModule repository process.", - "version": "1.0.0" + "version": "1.1.0" }, "plugins": [ { "name": "psmodule", "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", - "version": "1.0.0", + "version": "1.1.0", "source": ".github/plugin/psmodule" } ] diff --git a/.github/plugin/psmodule/plugin.json b/.github/plugin/psmodule/plugin.json index 7b3cce75..8ffe1fa4 100644 --- a/.github/plugin/psmodule/plugin.json +++ b/.github/plugin/psmodule/plugin.json @@ -2,7 +2,7 @@ "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "psmodule", "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", - "version": "1.0.0", + "version": "1.1.0", "author": { "name": "PSModule", "url": "https://github.com/PSModule" diff --git a/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md b/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md new file mode 100644 index 00000000..95cbd740 --- /dev/null +++ b/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md @@ -0,0 +1,189 @@ +--- +name: psmodule-v8-upgrade +description: Upgrade a Process-PSModule consumer repository to framework version 8 while preserving repository intent, enforcing the caller workflow contract, migrating Pester tests to v6, and retaining the repository's Zensical documentation design. +--- + +# Upgrade a Process-PSModule consumer to v8 + +Use this skill when a consumer repository needs to move its +`Process-PSModule.yml` caller to `PSModule/Process-PSModule/.github/workflows/workflow.yml@v8`. +Keep the change limited to the requested framework upgrade. Do not migrate +consumer repositories while developing or validating this skill. + +## Operating contract + +1. Inspect the consumer repository before editing. Read its local guidance, + workflow, documentation configuration and content, tests, settings, + dependencies, and existing validation commands. +2. Work on a dedicated branch, open a draft pull request early, and use small + commits. Include the required Copilot co-author trailer in every commit. +3. Preserve test intent, fixtures, secrets, variables, documentation content, + custom theme assets, and repository-owned automation unless the upgrade + requires a direct change. +4. Report preserved TestData, Pester migration details, Zensical/theme changes, + validation results, and blockers in the pull request. + +Use the repository's applicable MSX workflow and PR format guidance. Do not +silently broaden the scope when the consumer has unrelated failures. + +## Caller workflow contract + +Replace `.github/workflows/Process-PSModule.yml` with exactly this template: + +```yaml +name: Process-PSModule + +on: + workflow_dispatch: + schedule: + - cron: '0 0 * * *' + push: + branches: + - main + pull_request: + branches: + - main + types: + - closed + - opened + - reopened + - synchronize + - labeled + - unlabeled + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +permissions: {} + +jobs: + Process-PSModule: + permissions: + contents: read + pages: write + id-token: write + uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@v8 + secrets: + PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }} + GitHubAppClientId: ${{ secrets.SHELLY_CLIENT_ID }} + GitHubAppPrivateKey: ${{ secrets.SHELLY_PRIVATE_KEY }} +``` + +The only permitted variation is an optional `TestData` entry under +`jobs.Process-PSModule.secrets`. Do not add `with:` inputs, extra jobs, +conditions, schedule changes, `run-name`, permission changes, trigger changes, +concurrency changes, debug options, or version overrides. Repository-owned +automation belongs in separate workflow files. + +### TestData preservation + +First determine whether the current caller passes secrets or variables to the +framework. Preserve a required payload by translating it to this compact JSON +shape: + +```yaml + TestData: >- + {"secrets":{"SERVICE_TOKEN":"SERVICE_TOKEN"},"variables":{"ENVIRONMENT":"production"}} +``` + +Include only the `secrets` and/or `variables` maps that the consumer uses. Keep +the existing names and semantics. Omit `TestData` entirely when the repository +does not use it. Never move secrets into source files, workflow `env`, or +committed settings. + +## Documentation integration + +Treat `docs/zensical.toml` as authoritative. Do not create or maintain +`mkdocs.yml`, introduce MkDocs configuration, or replace the consumer's +documentation design with a parallel theme. + +Compare the consumer's configuration with the Process-PSModule template and +preserve or migrate these surfaces deliberately: + +- `docs/zensical.toml`, including `docs_dir` and navigation. +- `docs/content/` as the documentation source directory. +- `docs/overrides/` and custom templates. +- `docs/overrides/assets/stylesheets/navigation.css`. +- `docs/assets/`, logo, favicon, palette, fonts, and custom JavaScript/CSS. +- Existing navigation labels, page paths, and custom theme behavior. + +Do not delete existing custom CSS/assets merely because the default theme also +provides an equivalent feature. Resolve duplicate configuration in favor of +the existing consumer source of truth, then validate the generated site. + +## Pester v6 migration + +The framework upgrade does not permit leaving tests on an undeclared or +unsupported Pester version. Inspect module requirements, dependency manifests, +local setup, CI installation, and every test entry point. Declare and run the +repository's supported Pester 6 dependency. + +Rewrite tests using native Pester v6 terminology and APIs: + +- Prefer `New-PesterConfiguration` and + `Invoke-Pester -Configuration`. +- Update discovery, run configuration, output, result, and coverage handling + without changing test intent. +- Make each test file safe under Pester v6 per-file discovery and execution. +- Preserve explicit fixture ownership and loading; do not silently import the + target module as a fallback for a broken framework setup. +- Keep setup and teardown deterministic and scoped. +- Preserve data-driven cases, mocks, pending behavior, names, tags, coverage, + and result reporting while applying the v6 compatibility rules. + +Do not merely rename commands. Run the migrated tests with the declared Pester +6 dependency and investigate failures as migration or repository issues. + +## Repository integration inventory + +Before editing, record the current state and the intended v8 result for: + +| Surface | Inspect | Required result | +| --- | --- | --- | +| Caller workflow | Triggers, permissions, concurrency, secrets, `with:` inputs | Exact v8 contract; only documented `TestData` may vary | +| TestData | Secret and variable names and consumers | Explicit compact JSON maps, or omitted when unused | +| Pester dependency | `#Requires`, manifests, install steps, lock files | Pester 6 is declared and installed consistently | +| Pester configuration | `Invoke-Pester`, output, result, coverage | Native configuration object and v6-compatible output | +| Test setup | Before/After blocks, module load, fixtures, services | Explicit ownership and deterministic per-file behavior | +| Documentation | Zensical config, content, overrides, assets | Existing Zensical design remains authoritative | +| Repository automation | Other workflows and scripts | Unrelated automation remains separate and unchanged | +| Validation | Existing tests, lint, site build, workflow checks | Existing repository-native validation is rerun | + +## Validation + +Run the smallest existing checks that cover the changed surfaces, then escalate +when a targeted check reveals a broader dependency: + +1. Validate YAML syntax and confirm the caller has no forbidden variation. +2. Run the existing Process-PSModule workflow or its repository-native + equivalent when available. +3. Run the Pester v6 test suites with the repository's declared configuration. +4. Run the repository's existing lint and test commands. +5. When documentation exists, run: + + ```powershell + Push-Location docs + zensical build --clean + Pop-Location + ``` + +6. Review the diff for accidental workflow permissions, trigger changes, + secret exposure, fixture removal, generated files, or unrelated refactoring. + +Report commands and outcomes, including blocked checks and why they were +blocked. A green documentation build does not substitute for Pester or +workflow validation. + +## References + +- [PSModule repository standard](https://github.com/PSModule/Process-PSModule/blob/main/docs/content/reference/repository-standard.md) +- [PSModule workflow inputs](https://github.com/PSModule/Process-PSModule/blob/main/docs/content/reference/workflow-inputs.md) +- [PSModule pipeline stages](https://github.com/PSModule/Process-PSModule/blob/main/docs/content/reference/pipeline-stages.md) +- [PSModule module test guidance](https://github.com/PSModule/Process-PSModule/blob/main/docs/content/guides/writing-module-tests.md) +- [PSModule workflow and test data guidance](https://github.com/PSModule/Process-PSModule/blob/main/docs/content/guides/calling-the-workflow.md) +- [Zensical setup basics](https://zensical.org/docs/setup/basics/) +- [Pester v6 quick start](https://pester.dev/docs/v6/quick-start) +- [Pester `New-PesterConfiguration` command](https://pester.dev/docs/commands/New-PesterConfiguration) +- [Pester `Invoke-Pester` command](https://pester.dev/docs/commands/Invoke-Pester) +- [MSX PR format](https://msxorg.github.io/docs/Ways-of-Working/PR-Format/) From 8ae272c94c00d208d6f848e120c072f5a25eb07e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 21:05:21 +0200 Subject: [PATCH 14/22] docs: enrich Process-PSModule v8 upgrade skill Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/plugin/marketplace.json | 4 +- .github/plugin/psmodule/plugin.json | 2 +- .../skills/psmodule-v8-upgrade/SKILL.md | 41 ++++++++++++++++++- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index 0f710916..d7f53e44 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -6,13 +6,13 @@ }, "metadata": { "description": "Agent plugins for the PSModule repository process.", - "version": "1.1.0" + "version": "1.2.0" }, "plugins": [ { "name": "psmodule", "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", - "version": "1.1.0", + "version": "1.2.0", "source": ".github/plugin/psmodule" } ] diff --git a/.github/plugin/psmodule/plugin.json b/.github/plugin/psmodule/plugin.json index 8ffe1fa4..b4c0f32d 100644 --- a/.github/plugin/psmodule/plugin.json +++ b/.github/plugin/psmodule/plugin.json @@ -2,7 +2,7 @@ "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "psmodule", "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", - "version": "1.1.0", + "version": "1.2.0", "author": { "name": "PSModule", "url": "https://github.com/PSModule" diff --git a/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md b/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md index 95cbd740..ae163240 100644 --- a/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md +++ b/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md @@ -26,6 +26,25 @@ consumer repositories while developing or validating this skill. Use the repository's applicable MSX workflow and PR format guidance. Do not silently broaden the scope when the consumer has unrelated failures. +## Consumer layout variance + +Do not assume that a consumer already resembles Process-PSModule. Inventory +what is present before deciding what to migrate: + +- Many consumers have a legacy `.github/mkdocs.yml` and no `docs/` directory. +- Some consumers already have `docs/zensical.toml`, custom overrides, and + assets that must be preserved. +- A consumer may already declare Pester 6; do not repeat a dependency migration + that is already complete. +- Existing repository-owned workflows, scripts, and settings are not caller + workflow extensions. Keep them in separate files and validate them in place. + +When documentation is absent, do not invent a site as part of the caller +upgrade unless the requested scope explicitly includes documentation migration. +When a legacy MkDocs configuration exists and documentation migration is in +scope, migrate its content and design deliberately to Zensical, then remove +the obsolete configuration only after the generated site validates. + ## Caller workflow contract Replace `.github/workflows/Process-PSModule.yml` with exactly this template: @@ -92,6 +111,24 @@ the existing names and semantics. Omit `TestData` entirely when the repository does not use it. Never move secrets into source files, workflow `env`, or committed settings. +For example, preserve a secrets-only caller payload such as PSModule/GitHub's: + +```yaml + TestData: >- + {"secrets":{"TEST_USER_USER_FG_PAT":"${{ secrets.TEST_USER_USER_FG_PAT }}","TEST_USER_ORG_FG_PAT":"${{ secrets.TEST_USER_ORG_FG_PAT }}","TEST_USER_PAT":"${{ secrets.TEST_USER_PAT }}","TEST_APP_ORG_CLIENT_ID":"${{ secrets.TEST_APP_ORG_CLIENT_ID }}","TEST_APP_ORG_PRIVATE_KEY":"${{ secrets.TEST_APP_ORG_PRIVATE_KEY }}","TEST_APP_ENT_CLIENT_ID":"${{ secrets.TEST_APP_ENT_CLIENT_ID }}","TEST_APP_ENT_PRIVATE_KEY":"${{ secrets.TEST_APP_ENT_PRIVATE_KEY }}"}} +``` + +Preserve a mixed secrets-and-variables payload such as PSModule/Confluence's: + +```yaml + TestData: >- + {"secrets":{"CONFLUENCE_API_TOKEN":"${{ secrets.CONFLUENCE_API_TOKEN }}"},"variables":{"CONFLUENCE_SITE":"${{ vars.CONFLUENCE_SITE }}","CONFLUENCE_USERNAME":"${{ vars.CONFLUENCE_USERNAME }}","CONFLUENCE_SPACE_KEY":"${{ vars.CONFLUENCE_SPACE_KEY }}"}} +``` + +These examples are contracts, not values to copy into an unrelated consumer. +Read the original workflow and preserve only the maps and keys it actually +uses. + ## Documentation integration Treat `docs/zensical.toml` as authoritative. Do not create or maintain @@ -117,7 +154,9 @@ the existing consumer source of truth, then validate the generated site. The framework upgrade does not permit leaving tests on an undeclared or unsupported Pester version. Inspect module requirements, dependency manifests, local setup, CI installation, and every test entry point. Declare and run the -repository's supported Pester 6 dependency. +repository's supported Pester 6 dependency. If Pester 6 is already declared, +retain the declaration and focus on configuration, discovery, assertions, +setup/teardown, and output compatibility. Rewrite tests using native Pester v6 terminology and APIs: From c82ca36c075eb6118a7133dd267ec7b4a29447d2 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 21:06:51 +0200 Subject: [PATCH 15/22] docs: add Template-PSModule baseline to v8 skill Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/plugin/marketplace.json | 4 +- .github/plugin/psmodule/plugin.json | 2 +- .../skills/psmodule-v8-upgrade/SKILL.md | 83 +++++++++++++++++++ 3 files changed, 86 insertions(+), 3 deletions(-) diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index d7f53e44..b70e344c 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -6,13 +6,13 @@ }, "metadata": { "description": "Agent plugins for the PSModule repository process.", - "version": "1.2.0" + "version": "1.3.0" }, "plugins": [ { "name": "psmodule", "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", - "version": "1.2.0", + "version": "1.3.0", "source": ".github/plugin/psmodule" } ] diff --git a/.github/plugin/psmodule/plugin.json b/.github/plugin/psmodule/plugin.json index b4c0f32d..ece7dc6a 100644 --- a/.github/plugin/psmodule/plugin.json +++ b/.github/plugin/psmodule/plugin.json @@ -2,7 +2,7 @@ "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "psmodule", "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", - "version": "1.2.0", + "version": "1.3.0", "author": { "name": "PSModule", "url": "https://github.com/PSModule" diff --git a/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md b/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md index ae163240..5a49146a 100644 --- a/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md +++ b/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md @@ -45,6 +45,89 @@ When a legacy MkDocs configuration exists and documentation migration is in scope, migrate its content and design deliberately to Zensical, then remove the obsolete configuration only after the generated site validates. +## Template-PSModule baseline + +Use [`PSModule/Template-PSModule`](https://github.com/PSModule/Template-PSModule) +and the [PSModule Repository Standard](https://github.com/PSModule/Process-PSModule/blob/main/docs/content/reference/repository-standard.md) +as the structural baseline for module repositories. Compare the consumer with +the template's default files before adding, removing, or relocating anything. +The template is a starting point, not a reason to overwrite module-specific +content. + +The expected repository anatomy is: + +```text +/ +├── .github/ +│ ├── CODEOWNERS +│ ├── dependabot.yml +│ ├── linters/ +│ │ ├── .markdown-lint.yml +│ │ ├── .powershell-psscriptanalyzer.psd1 +│ │ └── .textlintrc +│ ├── PSModule.yml +│ ├── pull_request_template.md +│ ├── release.yml +│ └── workflows/ +│ └── Process-PSModule.yml +├── docs/ +│ ├── assets/ +│ ├── content/ +│ ├── overrides/ +│ └── zensical.toml +├── examples/ +├── icon/ +├── src/ +│ ├── classes/ +│ ├── data/ +│ ├── formats/ +│ ├── functions/ +│ │ ├── private/ +│ │ └── public/ +│ ├── init/ +│ ├── modules/ +│ ├── scripts/ +│ ├── types/ +│ └── variables/ +├── tests/ +│ ├── AfterAll.ps1 +│ ├── BeforeAll.ps1 +│ └── .Tests.ps1 +├── .gitattributes +├── .gitignore +├── AGENTS.md +├── CLAUDE.md +├── CODE_OF_CONDUCT.md +├── CONTRIBUTING.md +├── LICENSE +├── README.md +├── SECURITY.md +└── SUPPORT.md +``` + +Treat files and directories as follows: + +- Required baseline files should be present in the consumer and remain + repository-local; do not rely on organization-level fallback files. +- `src/`, especially `src/functions/public/` and `src/functions/private/`, + along with `tests/`, `examples/`, and `icon/`, is module-owned content. + Preserve its intent and only migrate paths when the framework contract + requires it. +- `.github/PSModule.yml`, linters, Dependabot, CODEOWNERS, release metadata, + pull-request templates, and repository guidance are configuration surfaces. + Inspect and preserve them independently of the caller workflow. +- `tests/BeforeAll.ps1` and `tests/AfterAll.ps1` are optional root-level + module-local phases, not recursively discovered test files. +- Optional source folders such as `assemblies`, `formats`, `types`, `variables`, + `data`, `modules`, and `scripts` are added when the module needs them; do not + create empty placeholders solely to match the tree. + +If the template revision and the consumer's existing layout disagree, record +the difference and migrate only the requested integration surface. In +particular, this v8 skill uses `docs/zensical.toml`, `docs/content/`, +`docs/overrides/`, and `docs/assets/` as the documentation contract described +below; do not create a second configuration under `.github/`. + ## Caller workflow contract Replace `.github/workflows/Process-PSModule.yml` with exactly this template: From eed97deaa66dafd3a4830983e09f7d5a07b0c15a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 21:08:30 +0200 Subject: [PATCH 16/22] docs: align v8 skill with template defaults Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/plugin/marketplace.json | 4 +-- .github/plugin/psmodule/plugin.json | 2 +- .../skills/psmodule-v8-upgrade/SKILL.md | 34 +++++++++++-------- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index b70e344c..a04e2622 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -6,13 +6,13 @@ }, "metadata": { "description": "Agent plugins for the PSModule repository process.", - "version": "1.3.0" + "version": "1.4.0" }, "plugins": [ { "name": "psmodule", "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", - "version": "1.3.0", + "version": "1.4.0", "source": ".github/plugin/psmodule" } ] diff --git a/.github/plugin/psmodule/plugin.json b/.github/plugin/psmodule/plugin.json index ece7dc6a..0a920e96 100644 --- a/.github/plugin/psmodule/plugin.json +++ b/.github/plugin/psmodule/plugin.json @@ -2,7 +2,7 @@ "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "psmodule", "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", - "version": "1.3.0", + "version": "1.4.0", "author": { "name": "PSModule", "url": "https://github.com/PSModule" diff --git a/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md b/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md index 5a49146a..66532347 100644 --- a/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md +++ b/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md @@ -54,7 +54,7 @@ the template's default files before adding, removing, or relocating anything. The template is a starting point, not a reason to overwrite module-specific content. -The expected repository anatomy is: +The current template's default repository anatomy is: ```text / @@ -62,18 +62,15 @@ The expected repository anatomy is: │ ├── CODEOWNERS │ ├── dependabot.yml │ ├── linters/ +│ │ ├── .codespellrc │ │ ├── .markdown-lint.yml │ │ ├── .powershell-psscriptanalyzer.psd1 │ │ └── .textlintrc │ ├── PSModule.yml │ ├── pull_request_template.md │ ├── release.yml -│ └── workflows/ +│ ├── workflows/ │ └── Process-PSModule.yml -├── docs/ -│ ├── assets/ -│ ├── content/ -│ ├── overrides/ │ └── zensical.toml ├── examples/ ├── icon/ @@ -96,13 +93,9 @@ The expected repository anatomy is: ├── .gitattributes ├── .gitignore ├── AGENTS.md -├── CLAUDE.md -├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE -├── README.md -├── SECURITY.md -└── SUPPORT.md +└── README.md ``` Treat files and directories as follows: @@ -121,12 +114,25 @@ Treat files and directories as follows: - Optional source folders such as `assemblies`, `formats`, `types`, `variables`, `data`, `modules`, and `scripts` are added when the module needs them; do not create empty placeholders solely to match the tree. +- The template's starter test declares Pester 6 with `#Requires` and uses the + native `Describe`, `It`, and `Should-Be` syntax. Preserve that requirement + when the consumer already has the Pester 6 baseline. +- The template's `.github/PSModule.yml` sets a zero code-coverage target and + carries explicit linter environment defaults; compare these settings before + replacing or deleting a consumer settings file. +- The template's `AGENTS.md` points to Template-PSModule quickstart, repository + defaults, module anatomy, build/test/pack/publish, and standards guidance. + Preserve the consumer's local onboarding contract while updating stale links. If the template revision and the consumer's existing layout disagree, record the difference and migrate only the requested integration surface. In -particular, this v8 skill uses `docs/zensical.toml`, `docs/content/`, -`docs/overrides/`, and `docs/assets/` as the documentation contract described -below; do not create a second configuration under `.github/`. +particular, the current template uses `.github/zensical.toml`, while this v8 +upgrade request uses `docs/zensical.toml`, `docs/content/`, `docs/overrides/`, +and `docs/assets/` as its documentation contract. When that requested +documentation migration is in scope, move the template's Zensical settings +and custom assets into the `docs/` contract rather than maintaining both +configurations. When it is not in scope, preserve the consumer's existing +working configuration and report the difference. ## Caller workflow contract From 548ac52d9f5cfcf92d3e70bcb87e235375eb07aa Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 21:13:16 +0200 Subject: [PATCH 17/22] feat: add MkDocs to Zensical migration skill Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/plugin/README.md | 3 + .github/plugin/marketplace.json | 4 +- .github/plugin/psmodule/plugin.json | 2 +- .../skills/psmodule-v8-upgrade/SKILL.md | 13 +- .../psmodule-zensical-migration/SKILL.md | 159 ++++++++++++++++++ 5 files changed, 175 insertions(+), 6 deletions(-) create mode 100644 .github/plugin/psmodule/skills/psmodule-zensical-migration/SKILL.md diff --git a/.github/plugin/README.md b/.github/plugin/README.md index 16b5e31a..5b0f9e43 100644 --- a/.github/plugin/README.md +++ b/.github/plugin/README.md @@ -27,6 +27,9 @@ skill for migrating every Pester test set in a PSModule repository to Pester 6.1.0, and the [`psmodule-v8-upgrade`](./psmodule/skills/psmodule-v8-upgrade/SKILL.md) skill for upgrading Process-PSModule consumer repositories to framework v8. +It also provides +[`psmodule-zensical-migration`](./psmodule/skills/psmodule-zensical-migration/SKILL.md) +for migrating legacy MkDocs sites to the Process-PSModule Zensical design. Verify the installation with: ```console diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index a04e2622..d70c101e 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -6,13 +6,13 @@ }, "metadata": { "description": "Agent plugins for the PSModule repository process.", - "version": "1.4.0" + "version": "1.5.0" }, "plugins": [ { "name": "psmodule", "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", - "version": "1.4.0", + "version": "1.5.0", "source": ".github/plugin/psmodule" } ] diff --git a/.github/plugin/psmodule/plugin.json b/.github/plugin/psmodule/plugin.json index 0a920e96..3040470d 100644 --- a/.github/plugin/psmodule/plugin.json +++ b/.github/plugin/psmodule/plugin.json @@ -2,7 +2,7 @@ "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "psmodule", "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", - "version": "1.4.0", + "version": "1.5.0", "author": { "name": "PSModule", "url": "https://github.com/PSModule" diff --git a/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md b/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md index 66532347..d51536a5 100644 --- a/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md +++ b/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md @@ -127,13 +127,19 @@ Treat files and directories as follows: If the template revision and the consumer's existing layout disagree, record the difference and migrate only the requested integration surface. In particular, the current template uses `.github/zensical.toml`, while this v8 -upgrade request uses `docs/zensical.toml`, `docs/content/`, `docs/overrides/`, -and `docs/assets/` as its documentation contract. When that requested +upgrade request uses `docs/zensical.toml`, `docs/content/`, and +`docs/overrides/` (including `docs/overrides/assets/`) as its documentation +contract; a separate `docs/assets/` directory is optional. When that requested documentation migration is in scope, move the template's Zensical settings and custom assets into the `docs/` contract rather than maintaining both configurations. When it is not in scope, preserve the consumer's existing working configuration and report the difference. +For a documentation-only MkDocs migration, use the dedicated +[`psmodule-zensical-migration`](../psmodule-zensical-migration/SKILL.md) skill +so content, theme, assets, and link validation are handled independently from +the caller workflow upgrade. + ## Caller workflow contract Replace `.github/workflows/Process-PSModule.yml` with exactly this template: @@ -231,7 +237,8 @@ preserve or migrate these surfaces deliberately: - `docs/content/` as the documentation source directory. - `docs/overrides/` and custom templates. - `docs/overrides/assets/stylesheets/navigation.css`. -- `docs/assets/`, logo, favicon, palette, fonts, and custom JavaScript/CSS. +- `docs/overrides/assets/`, any optional `docs/assets/`, logo, favicon, palette, + fonts, and custom JavaScript/CSS. - Existing navigation labels, page paths, and custom theme behavior. Do not delete existing custom CSS/assets merely because the default theme also diff --git a/.github/plugin/psmodule/skills/psmodule-zensical-migration/SKILL.md b/.github/plugin/psmodule/skills/psmodule-zensical-migration/SKILL.md new file mode 100644 index 00000000..b6e19fef --- /dev/null +++ b/.github/plugin/psmodule/skills/psmodule-zensical-migration/SKILL.md @@ -0,0 +1,159 @@ +--- +name: psmodule-zensical-migration +description: Migrate a PSModule repository from MkDocs to Zensical using the Process-PSModule documentation design as the default while preserving content, navigation, assets, and repository-specific behavior. +--- + +# Migrate PSModule documentation from MkDocs to Zensical + +Use this skill when a PSModule repository has a legacy MkDocs configuration, +usually `.github/mkdocs.yml`, or needs its documentation site aligned with the +Process-PSModule Zensical design. Keep the migration limited to documentation +integration. Do not rewrite module code or tests unless a documentation build +requires a directly related fix. + +## Source-of-truth design + +Use the current +[`Process-PSModule` `docs/zensical.toml`](https://github.com/PSModule/Process-PSModule/blob/main/docs/zensical.toml) +as the default style and configuration baseline. Reuse its behavior rather than +inventing a second theme: + +- `docs_dir = "content"` with content under `docs/content/`. +- `docs/overrides/` as the custom theme directory. +- `docs/overrides/assets/stylesheets/navigation.css` for navigation styling. +- `docs/overrides/assets/` and any repository-owned `docs/assets/` directory + when present as the asset source of truth. +- Mona Sans text and Source Code Pro code fonts. +- Material-style GitHub/link icons, light/dark/system palette toggles, + black/slate/light-blue colors, and the established navigation features. +- Instant navigation, prefetch/preview/progress, tabs, tracking, top navigation, + search, code copy, tooltips, table of contents, and footer behavior. +- TOC, attribute lists, abbreviations, admonitions, definition lists, + footnotes, tables, HTML-in-Markdown, details, superfences, task lists, and + snippets extensions. +- Mermaid fenced blocks and the shared abbreviations snippet. +- Existing social links, consent configuration, site metadata, edit URI, and + custom tablesort JavaScript where those features apply. + +Customize only repository identity and content-specific values such as +`site_name`, `site_url`, `repo_name`, `repo_url`, `edit_uri`, copyright, social +links, and `nav`. Do not remove a default feature merely because the old +MkDocs site did not use it. + +## Inspect before changing + +Inventory the existing repository and record: + +1. Local guidance, branch state, and documentation build commands. +2. `.github/mkdocs.yml`, any `mkdocs.yml`, and any existing Zensical config. +3. The Markdown content root, includes/snippets, templates, media, and assets. +4. `theme`, `theme.custom_dir`, `extra_css`, `extra_javascript`, `plugins`, + `markdown_extensions`, `nav`, `extra`, and `watch` settings. +5. Links, anchors, generated API/help pages, redirects, and CI publishing steps. +6. Existing custom CSS, JavaScript, templates, logos, favicons, and fonts. + +Do not assume every consumer has a `docs/` tree. If documentation is absent, +create it only when the requested scope includes documentation migration. If +the repository already uses Zensical, compare it with the Process-PSModule +baseline and make only the required alignment changes. + +## Target layout + +For the Process-PSModule documentation contract, use: + +```text +docs/ +├── content/ +├── overrides/ +│ └── assets/ +│ ├── javascripts/ +│ └── stylesheets/ +└── zensical.toml +``` + +Keep existing content under `docs/content/`, custom templates under +`docs/overrides/`, and theme assets under `docs/overrides/assets/`. A separate +`docs/assets/` directory is optional for static content assets. Do not create a +parallel MkDocs theme or leave two active site configurations. + +The current `PSModule/Template-PSModule` repository historically stores a +starter `.github/zensical.toml` and may not contain a `docs/` tree. When the +consumer upgrade explicitly requires the Process-PSModule `docs/` contract, +move the template settings and custom assets into `docs/` and remove the +obsolete active configuration only after the site builds. When that contract +is not in scope, preserve a working template layout and report the difference +instead of moving files speculatively. + +## MkDocs-to-Zensical mapping + +Translate behavior, not just filenames: + +| MkDocs | Zensical | +| --- | --- | +| `site_name`, `site_url` | `[project]` metadata | +| `docs_dir` | `[project].docs_dir` | +| `repo_name`, `repo_url`, `edit_uri` | `[project]` metadata | +| `nav` | `nav = [...]` TOML entries | +| `theme.name` | `[project.theme]` settings | +| `theme.custom_dir` | `[project.theme].custom_dir` | +| `theme.logo`, `theme.favicon` | `[project.theme]` paths | +| `theme.features` | `[project.theme].features` | +| `theme.palette` | `[[project.theme.palette]]` tables | +| `extra_css`, `extra_javascript` | `[project]` arrays | +| `markdown_extensions` | `[project.markdown_extensions.*]` tables | +| `plugins: search` | `[project.plugins.search]` | +| `extra.social` | `[[project.extra.social]]` | +| `watch` | `[project].watch` | + +Preserve Markdown semantics while checking extensions that affect formatting: +admonitions, fenced code, tables, task lists, definition lists, attributes, +snippets, Mermaid, and anchor/permalink behavior. Fix only documented +Zensical incompatibilities; do not silently change headings or links to hide +build failures. + +## Content and link migration + +- Preserve page paths and navigation labels where possible. +- Keep explicit `nav` entries for important landing pages and references. +- Resolve relative links from the new `docs/content/` root. +- Recheck fragment anchors because heading and permalink behavior can differ. +- Move includes/snippets to the configured Zensical location and update every + reference. +- Keep generated API/help inputs in their framework-owned locations. +- Preserve images and downloads; update paths rather than deleting assets. +- Keep custom templates only when they are still required by the migrated site. + +## Validation + +Run repository-native checks and the smallest targeted site checks first: + +1. Parse the new `docs/zensical.toml` and verify all configured paths exist. +2. Confirm no active `mkdocs.yml` or MkDocs workflow remains. +3. Check every navigation target, image, download, include, and fragment link. +4. Run the existing documentation lint and link checks. +5. Build the site: + + ```powershell + Push-Location docs + zensical build --clean + Pop-Location + ``` + +6. Review the generated site for navigation, search, palette toggles, fonts, + logo/favicon, custom navigation behavior, code blocks, Mermaid, and social + links. +7. Run the repository's existing Process-PSModule workflow validation when the + documentation is part of that pipeline. + +Do not claim success if the site builds while links, assets, navigation, or +publishing behavior are broken. Report intentionally deferred pages, +unsupported extensions, and unrelated pre-existing failures. + +## References + +- [Process-PSModule Zensical configuration](https://github.com/PSModule/Process-PSModule/blob/main/docs/zensical.toml) +- [Process-PSModule documentation overrides](https://github.com/PSModule/Process-PSModule/tree/main/docs/overrides) +- [Process-PSModule override assets](https://github.com/PSModule/Process-PSModule/tree/main/docs/overrides/assets) +- [PSModule repository standard](https://github.com/PSModule/Process-PSModule/blob/main/docs/content/reference/repository-standard.md) +- [PSModule documentation model](https://github.com/PSModule/Process-PSModule/blob/main/docs/content/guides/structuring-your-module.md) +- [Zensical setup basics](https://zensical.org/docs/setup/basics/) From f33a0e16c74aa740daab5c16b8648a13f7b25b71 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 21:15:58 +0200 Subject: [PATCH 18/22] fix: reset new marketplace version Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/plugin/marketplace.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index d70c101e..efac3e4b 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -6,7 +6,7 @@ }, "metadata": { "description": "Agent plugins for the PSModule repository process.", - "version": "1.5.0" + "version": "1.0.0" }, "plugins": [ { From 18ba8a504d1dd7f9d26820ab7e192e6cf98402f7 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 21:16:42 +0200 Subject: [PATCH 19/22] fix: reset initial plugin version Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/plugin/marketplace.json | 2 +- .github/plugin/psmodule/plugin.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index efac3e4b..32ff5943 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -12,7 +12,7 @@ { "name": "psmodule", "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", - "version": "1.5.0", + "version": "1.0.0", "source": ".github/plugin/psmodule" } ] diff --git a/.github/plugin/psmodule/plugin.json b/.github/plugin/psmodule/plugin.json index 3040470d..7b3cce75 100644 --- a/.github/plugin/psmodule/plugin.json +++ b/.github/plugin/psmodule/plugin.json @@ -2,7 +2,7 @@ "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "psmodule", "description": "PSModule process guidance and reusable skills for PowerShell module repositories.", - "version": "1.5.0", + "version": "1.0.0", "author": { "name": "PSModule", "url": "https://github.com/PSModule" From ecc0dbfb8c33546cddb1cf61c811a705ddbeabcf Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 21:18:56 +0200 Subject: [PATCH 20/22] docs: define Pester public interface test contract Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../skills/psmodule-pester-migration/SKILL.md | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/.github/plugin/psmodule/skills/psmodule-pester-migration/SKILL.md b/.github/plugin/psmodule/skills/psmodule-pester-migration/SKILL.md index c574c17e..cd11f56f 100644 --- a/.github/plugin/psmodule/skills/psmodule-pester-migration/SKILL.md +++ b/.github/plugin/psmodule/skills/psmodule-pester-migration/SKILL.md @@ -101,6 +101,28 @@ manifest validity, or module removal. Such a framework or contract test should say so in its name and use a deliberate, isolated import as the behavior under test. It must not become setup for unrelated tests. +### Build, load, and interface boundary + +The normal module-local execution sequence is: + +1. Process-PSModule builds the module from `src/`. +2. The framework prepares and loads that built module for the test job. +3. Pester runs the module-local test files against the prepared module. +4. Results and coverage are collected for the configured suite. + +Module-local tests validate the module's **public interface**: exported +functions, exported aliases, public classes, public variables, documented +formats, and observable behavior. They must not call private functions, +private variables, internal classes, or implementation scripts directly. +Private implementation is covered indirectly through public behavior. This +keeps tests stable when internals are refactored and proves that the shipped +module artifact works for consumers. + +Source-code or framework suites may inspect internal files when that is their +explicit purpose, but they are a separate test surface. Do not use source-code +access as setup for module-local tests, and do not interpret source-suite +coverage as proof that the public module artifact is usable. + Every additional fixture is also part of the test-state contract. A test set must explicitly load its own JSON, CSV, XML, PSD1, script, or generated data, or document which setup phase provides it. In particular, a PSD1 dataset is @@ -117,6 +139,8 @@ Record fixture ownership and availability in the inventory: | Fixture or state | Owner | Loaded in | Required environment | | --- | --- | --- | --- | | Target module | Process-PSModule or explicit contract test | Framework pre-run | Built module path and version | +| Public interface | Module-local test set | Pester after framework module load | Exported commands/classes and observable behavior | +| Private implementation | Source/framework suite only when explicitly required | Separate source-test setup | Never a module-local test dependency | | PSD1/JSON/CSV data | Test set or documented setup | `BeforeDiscovery`, `BeforeAll`, or setup job | Relative path and encoding | | Secrets/variables | Calling workflow | `Expose-TestData` and environment | `TestData` JSON contract | | Shared service | `tests/BeforeAll.ps1` | Before module-local matrix | Deterministic run-scoped name | @@ -163,6 +187,9 @@ Use this per-repository checklist: invocation and its `Run.Path`/`Run.ExcludePath` is recorded. - [ ] The built target module is loaded by the framework before module-local tests; tests do not silently load it themselves. +- [ ] Module-local tests exercise only the built module's public interface; + private implementation tests, if required, are separate source/framework + suites. - [ ] Source-code test loading is explicit and documented separately from the module-local contract. - [ ] Every PSD1, JSON, CSV, XML, script, generated fixture, secret, variable, From e7de1913d8df963a346dc1bb21c8e501313aff4b Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 21:20:23 +0200 Subject: [PATCH 21/22] docs: remove temporary Pester migration guide Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- docs/content/guides/pester-migration.md | 64 ------------------------- docs/content/index.md | 1 - docs/zensical.toml | 1 - 3 files changed, 66 deletions(-) delete mode 100644 docs/content/guides/pester-migration.md diff --git a/docs/content/guides/pester-migration.md b/docs/content/guides/pester-migration.md deleted file mode 100644 index aa1383fb..00000000 --- a/docs/content/guides/pester-migration.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: Migrating Pester tests -description: A repository-wide checklist for migrating PSModule test sets to Pester 6.1.0. ---- - -# Migrating Pester tests - -Register the PSModule initiative marketplace and install its `psmodule` -plugin: - -```console -copilot plugin marketplace add https://github.com/PSModule/Process-PSModule.git -copilot plugin install psmodule -``` - -Then use its reusable `psmodule-pester-migration` agent skill to migrate every Pester -test set in a PSModule repository. For direct installation during development, -use `copilot plugin install -PSModule/Process-PSModule:.github/plugin/psmodule`. It is -written for Pester **6.1.0** and distinguishes required compatibility changes -from optional v6 modernization. - -The migration covers repository and test-set inventory, supported PowerShell -runtime and CI checks, per-file discovery and run isolation, hidden paths, -data-driven tests, setup blocks, mocks, pending tests, name templates, -coverage, `Invoke-Pester` configuration, reserved tags, and validation -reporting. It also defines the test-state/data contract: module-local tests -consume the target module already loaded by Process-PSModule and explicitly -load any PSD1 or other fixture data. They must not silently import the module as -a substitute for framework setup. It does not migrate consumer repositories as -part of this framework change. - -## Required before declaring a migration complete - -- Every test entry point is inventoried and runs on its supported runtime matrix. -- The target module is loaded by the framework before module-local Pester tests; - tests do not hide a missing load with `Import-Module`. -- Every PSD1, JSON, CSV, XML, script, generated fixture, secret, variable, and - service dependency has an owner and explicit loading phase. -- `Invoke-Pester`, `Test-PSModule`, module-local/source workflows, - `BeforeAll`/`AfterAll`, `Expose-TestData`, result/coverage collectors, and - linter result publishing are included in the repository inventory. -- Pester 6.1.0 is imported in local and CI acceptance runs. -- Each test file is self-contained under per-file discovery and run. -- Hidden paths, empty data, duplicate setup blocks, mocks, pending tests, name - templates, coverage settings, legacy invocation parameters, and `None` tags - have been reviewed. -- Serial results, coverage, and test-result artifacts are recorded and compared - with the baseline. - -## Optional after compatibility - -`Should-*` assertions, `Run.Shuffle`, and experimental `Run.Parallel` are -independent adoption choices. Enable them only with separate validation and -document the choice. - -## Primary and secondary sources - -- [Official Pester v5-to-v6 migration](https://pester.dev/docs/migrations/v5-to-v6) -- [Pester installation](https://pester.dev/docs/introduction/installation) -- [Pester configuration](https://pester.dev/docs/usage/configuration) -- [Pester parallel execution](https://pester.dev/docs/usage/parallel) -- [Awesome Copilot pester-migration](https://github.com/github/awesome-copilot/tree/main/skills/pester-migration) -- [Awesome Copilot pester-should-migration](https://github.com/github/awesome-copilot/tree/main/skills/pester-should-migration) diff --git a/docs/content/index.md b/docs/content/index.md index 50ab0a04..d7f2abc8 100644 --- a/docs/content/index.md +++ b/docs/content/index.md @@ -40,7 +40,6 @@ Task-oriented deep dives into the pipeline's functionality. | [Configuring the pipeline](guides/configuring-the-pipeline.md) | Worked examples for coverage targets, rapid testing, linting, and PR-based release notes. | | [Structuring your module](guides/structuring-your-module.md) | The repository and module source layout the workflow expects, and how to declare dependencies. | | [Writing module tests](guides/writing-module-tests.md) | Test discovery, setup and teardown phases, and shared test infrastructure. | -| [Migrating Pester tests](guides/pester-migration.md) | A repository-wide checklist for migrating every test set to Pester 6.1.0. | | [PSModule process marketplace](https://github.com/PSModule/Process-PSModule/tree/main/.github/plugin) | Register the initiative marketplace and install the PSModule process plugin. | | [Skipping framework tests](guides/skipping-framework-tests.md) | Skip individual framework tests on a per-file basis. | | [Versioning and releases](guides/versioning-and-releases.md) | Label-driven versioning, prereleases, and what a release produces. | diff --git a/docs/zensical.toml b/docs/zensical.toml index 699a3146..cdd222bf 100644 --- a/docs/zensical.toml +++ b/docs/zensical.toml @@ -30,7 +30,6 @@ nav = [ {"Configuring the pipeline" = "guides/configuring-the-pipeline.md"}, {"Structuring your module" = "guides/structuring-your-module.md"}, {"Writing module tests" = "guides/writing-module-tests.md"}, - {"Migrating Pester tests" = "guides/pester-migration.md"}, {"Skipping framework tests" = "guides/skipping-framework-tests.md"}, {"Versioning and releases" = "guides/versioning-and-releases.md"}, {"Validating before review" = "guides/validating-before-review.md"}, From facbef0232a3beb5aabe10ea7e352fae2c0f8f3a Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Sat, 15 Aug 2026 21:27:20 +0200 Subject: [PATCH 22/22] fix: satisfy natural language lint Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md b/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md index d51536a5..1d4201c3 100644 --- a/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md +++ b/.github/plugin/psmodule/skills/psmodule-v8-upgrade/SKILL.md @@ -278,7 +278,7 @@ Before editing, record the current state and the intended v8 result for: | --- | --- | --- | | Caller workflow | Triggers, permissions, concurrency, secrets, `with:` inputs | Exact v8 contract; only documented `TestData` may vary | | TestData | Secret and variable names and consumers | Explicit compact JSON maps, or omitted when unused | -| Pester dependency | `#Requires`, manifests, install steps, lock files | Pester 6 is declared and installed consistently | +| Pester dependency | `#Requires`, manifests, install steps, lockfiles | Pester 6 is declared and installed consistently | | Pester configuration | `Invoke-Pester`, output, result, coverage | Native configuration object and v6-compatible output | | Test setup | Before/After blocks, module load, fixtures, services | Explicit ownership and deterministic per-file behavior | | Documentation | Zensical config, content, overrides, assets | Existing Zensical design remains authoritative |