diff --git a/.codescene/code-health-rules.json b/.codescene/code-health-rules.json index d47a3009..b0232f98 100644 --- a/.codescene/code-health-rules.json +++ b/.codescene/code-health-rules.json @@ -1,5 +1,5 @@ { - "usage": "Persist this file inside your repositories as .codescene/code-health-rules.json Keep the rules you want to override, remove the rest for simplicity and an easy overview.Override the code health rules by changing the default 1.0 value to a lower relative weight. A value of 0.0 disables the rule. A value of 0.5 still implies a code health hit but only at 50% of the default impact. Note that you can specify multiple rule sets and use the matching-content-path to control to which parts or languages the rules apply. This makes it possible to differentiate between test vs application code, or tailor rules to specific languages. In case multiple rule sets match a piece of content, then we prioritize the first mathcing set of rules.", + "usage": "Keep the rules you want to override, remove the rest for simplicity and an easy overview. Override the code health rules by changing the default 1.0 value to a lower relative weight. A value of 0.0 disables the rule. A value of 0.5 still implies a code health hit but only at 50% of the default impact. Note that you can specify multiple rule sets and use the matching-content-path to control to which parts or languages the rules apply. This makes it possible to differentiate between test vs application code, or tailor rules to specific languages. In case multiple rule sets match a piece of content, then we prioritize the first matching set of rules.", "rule_sets": [ { "thresholds": [ diff --git a/.github/actions/check-coverage/action.yml b/.github/actions/check-coverage/action.yml index 9195411c..2ac221c6 100644 --- a/.github/actions/check-coverage/action.yml +++ b/.github/actions/check-coverage/action.yml @@ -30,5 +30,5 @@ runs: CS_ACCESS_TOKEN: ${{ inputs.access-token }} run: | set -euo pipefail - find "$(pwd)" -name '*.cobertura.xml' -print + find "$(pwd)" -name 'coverage.xml' -print "$(pwd)/cs-coverage" check --verbose --coverage-files "${{ inputs.coverage-files }}" diff --git a/.github/agents/architect.agent.md b/.github/agents/architect.agent.md index b19e5f70..cbb84c43 100644 --- a/.github/agents/architect.agent.md +++ b/.github/agents/architect.agent.md @@ -37,11 +37,12 @@ Design or reshape changes that cross public commands, private helper boundaries, ## Skills to use - `/powershell-module-development` -- `/github-actions` - `/release-and-changelog` +- `/markdown-authoring` +- `/building-maintainable-code` +- `/github-actions` - `/codescene-quality` - `/guiding-refactoring-with-code-health` -- `/markdown-authoring` ## Constraints @@ -62,6 +63,7 @@ Design or reshape changes that cross public commands, private helper boundaries, - If the user chooses full finalization, a GitHub issue draft is ready to paste or create from the final output. - If the user chooses design-package-only finalization, the output is clearly resumable later from an `Open questions / resume here` section. +- Finalization output is copy-ready Markdown that applies the project `markdown-authoring` skill. ## Must not do @@ -71,4 +73,5 @@ Design or reshape changes that cross public commands, private helper boundaries, - Must not create or edit repository files when the task is still in design mode. - Must not return a full implementation plan or finished issue draft in the first reply when the user is clearly asking for a design discussion. - Must not leave the user guessing whether the final output is a handoff document, paste-ready issue text, or both. +- Must not return finalization Markdown that skips the project `markdown-authoring` guidance. - Must not decide on its own that requested work is out of scope and then finalize the design without the user's confirmation. diff --git a/.github/agents/docs-site.agent.md b/.github/agents/docs-site.agent.md index e5a2e1d6..8815a31c 100644 --- a/.github/agents/docs-site.agent.md +++ b/.github/agents/docs-site.agent.md @@ -27,7 +27,7 @@ Keep the GitHub Pages documentation under `docs/*.html` accurate, user-focused, ## Skills to use -- `/docs-site-html` +- `/docs-site` - `/markdown-authoring` - `/powershell-module-development` - `/release-and-changelog` diff --git a/.github/agents/powershell-developer.agent.md b/.github/agents/powershell-developer.agent.md index 3774137d..3a7dc0cc 100644 --- a/.github/agents/powershell-developer.agent.md +++ b/.github/agents/powershell-developer.agent.md @@ -13,12 +13,19 @@ Implement PowerShell command and helper changes in the NovaModuleTools style. - Change the relevant public command and private helper flow. - Keep public files delegating and internal helpers domain-aligned. -- Add or update tests and documentation for the changed behavior. +- Preserve Nova's `project.json`-driven build model; do not add hand-written source `.psm1` or module `.psd1` files. +- Read `project.json` `Manifest.PowerShellHostVersion` before implementing PowerShell changes and keep source, tests, and examples compatible with that target. +- Keep one externally called function per file and match the file name to that function. In `src/private/`, additional related functions may stay only as same-file top-level support helpers called by that file's entry function, and PowerShell functions must not declare nested functions inside their bodies. +- Use `.github/instructions/code-quality-matrix.instructions.md` as the best-effort source-code maintainability guidance while shaping `src/**/*.ps1`. +- Use `.github/instructions/psscriptanalyzer.instructions.md` as the ScriptAnalyzer workflow source of truth while changing PowerShell code or analyzer helpers. +- Add or update source-mirrored tests and valid PlatyPS-compatible help docs for the changed behavior, using the Microsoft.PowerShell.PlatyPS cmdlets instead of hand-written help structure. +- Every new public entry point must add its matching help file in the same change. +- Before handoff, review every changed or generated text file and normalize it to exactly one trailing newline with no extra blank lines at the bottom. ## Inputs to inspect - The relevant file in `src/public/` -- Matching helpers in `src/private/build|cli|package|quality|release|scaffold|shared|update/` +- Matching helpers in `src/private/` - Matching test files in `tests/` - `project.json` @@ -26,6 +33,7 @@ Implement PowerShell command and helper changes in the NovaModuleTools style. - `/powershell-module-development` - `/pester-testing` +- `/building-maintainable-code` - `/codescene-quality` - `/guiding-refactoring-with-code-health` - `/safeguarding-ai-generated-code` @@ -36,10 +44,20 @@ Implement PowerShell command and helper changes in the NovaModuleTools style. - Keep `ShouldProcess` behavior where the command already supports it. - Keep raw infrastructure calls behind approved adapters. - Preserve existing command names, warning semantics, and output shape. +- Keep new or heavily changed source functions aligned with `.github/instructions/code-quality-matrix.instructions.md`: short, single-purpose, low-duplication, and split by clear responsibility unless the scope explicitly justifies otherwise. +- Prefer `./scripts/build/Invoke-ScriptAnalyzerCI.ps1` and `./run.ps1` for normal analyzer loops; use direct `Invoke-ScriptAnalyzer` only for focused local checks that reuse the repository-approved settings. +- Validate Nova-managed project tests through `Test-NovaBuild`; do not call `Invoke-Pester` directly. +- When help files change, keep `docs/NovaModuleTools/en-US/*.md` valid for `Import-MarkdownCommandHelp`: build and import the dist module first (`Import-Module ./dist/NovaModuleTools/NovaModuleTools.psd1 -Force`), then use `New-MarkdownCommandHelp` for new files, `Update-MarkdownCommandHelp` after command-surface changes, and `Test-MarkdownCommandHelp` before handoff. Generating help without the module imported causes `external help file` to default to the command name instead of the module name, producing per-command XML files that the manifest cannot find. A new public `src/public/*.ps1` file is not done until its matching help file exists. ## Definition of done - Production code and tests both reflect the intended behavior. +- Build output still comes from Nova-generated `dist/` files, not hand-authored module files in `src/`. +- Public/private file ownership still follows the one externally called function per file rule, with private helpers kept as sibling top-level functions instead of nested function declarations. +- Every new public entry point has its matching help file. +- Project test validation ran through `Test-NovaBuild`. +- Any ScriptAnalyzer findings reported by `run.ps1` or `Invoke-ScriptAnalyzerCI.ps1` are resolved. +- Every changed or generated text file has been checked and ends with exactly one trailing newline and no extra blank lines at the bottom. - Docs/changelog review is complete. - The relevant validation commands have been run. @@ -48,3 +66,4 @@ Implement PowerShell command and helper changes in the NovaModuleTools style. - Must not mix PowerShell cmdlet UX and `nova` CLI UX. - Must not add silent fallbacks for invalid or risky behavior. - Must not duplicate helpers that already exist elsewhere in the repo. +- Must not introduce PowerShell 7.x-only constructs into a `5.1` project unless guarded multi-version support is explicitly part of the change. diff --git a/.github/agents/release-manager.agent.md b/.github/agents/release-manager.agent.md index 2ac0a504..a8786637 100644 --- a/.github/agents/release-manager.agent.md +++ b/.github/agents/release-manager.agent.md @@ -15,6 +15,7 @@ Handle versioning, changelog shaping, release-flow documentation, and publish au - Keep `CHANGELOG.md` accurate and release-ready. - Review workflow, docs, and versioning implications together. - Produce a release-ready summary that follows `.github/pull_request_template.md` when a release preparation summary is requested. +- When the release scope is unclear (for example whether the change targets a stable bump, a prerelease, or both), ask one clarifying question before proceeding instead of guessing. ## Inputs to inspect @@ -29,20 +30,18 @@ Handle versioning, changelog shaping, release-flow documentation, and publish au - `/release-and-changelog` - `/markdown-authoring` -- `/github-actions` - `/pester-testing` +- `/github-actions` ## Constraints - Treat release automation as high-risk. - Keep Keep a Changelog structure intact. -- Use only the official Keep a Changelog section types in `CHANGELOG.md` and `RELEASE_NOTE.md`: `Added`, `Changed`, - `Deprecated`, `Removed`, `Fixed`, and `Security`. +- Use only the official Keep a Changelog section types in `CHANGELOG.md` and `RELEASE_NOTE.md`: `Added`, `Changed`, `Deprecated`, `Removed`, `Fixed`, and `Security`. - Do not invent extra changelog section headings such as `Documentation`; place documentation-related release notes under the official type that best matches the actual impact. - Distinguish contributor docs from end-user docs. - Treat `.github/pull_request_template.md` as the authoritative format for structured release summaries. -- When the release summary is returned as Markdown or copy-ready UI output, it must follow the `markdown-authoring` - skill (`.github/skills/markdown-authoring/SKILL.md`). +- When the release summary is returned as Markdown or copy-ready UI output, it must follow the `markdown-authoring` skill (`.github/skills/markdown-authoring/SKILL.md`). ## Definition of done diff --git a/.github/agents/reviewer.agent.md b/.github/agents/reviewer.agent.md index 71f8167f..aab9fde0 100644 --- a/.github/agents/reviewer.agent.md +++ b/.github/agents/reviewer.agent.md @@ -14,9 +14,23 @@ Review changes for correctness, maintainability, test coverage, workflow safety, - Start with the highest-risk workflow or public behavior surface. - Check for missing tests, doc drift, changelog gaps, and CI/release side effects. - Use the PR template categories as the review frame. +- When the review scope is genuinely ambiguous (for example which subset of files to focus on, or whether a borderline behavior change is intentional), ask one clarifying question before proceeding instead of guessing. - Treat CodeScene maintainability and changed-code coverage results as release-blocking signals unless risk is accepted explicitly. - If local CodeScene tooling is unavailable, continue the review with normal validation and rely on PR/CI as the effective CodeScene gate. - Check whether website docs preserve the CLI-vs-cmdlet separation when `docs/*.html` or help markdown changed. +- Check that Nova projects still use generated `dist/` module files instead of hand-written source `.psm1` or module `.psd1` files. +- Check changed PowerShell code, tests, and examples against `project.json` `Manifest.PowerShellHostVersion`; flag PowerShell 7.x-only constructs in projects that target `5.1` unless the change explicitly adds guarded compatibility handling. +- Check that public commands/classes have matching valid PlatyPS-compatible help and that new source files have source-mirrored tests. Flag help files under `docs/NovaModuleTools/en-US/` that look like plain Markdown, break the required PlatyPS section order, or would fail `Test-MarkdownCommandHelp` / `Import-MarkdownCommandHelp`. +- Flag any new public entry point that does not add its matching help file in the same change. +- Flag help files where `external help file` contains a command name instead of the module name. The correct value is `NovaModuleTools-Help.xml`; a per-command name like `Get-Something-Help.xml` means the help was generated without the built module imported. +- Check analyzer changes and PowerShell validation flow against `.github/instructions/psscriptanalyzer.instructions.md`. Flag direct `Invoke-ScriptAnalyzer` usage that bypasses repository-approved settings or wrapper semantics without a clear reason. +- Review changed `src/**/*.ps1` against `.github/instructions/code-quality-matrix.instructions.md` and `tests/**/*.ps1` against `.github/instructions/testing-policy.instructions.md`; flag new or heavily changed code that ignores those maintainability rules without a clear, explicit reason. +- Flag public files that do not keep exactly one top-level function, and flag private files that group multiple externally called functions instead of limiting extra functions to related same-file top-level support helpers. Also flag file/function name mismatches for public commands or externally called private helpers, and flag nested function declarations inside PowerShell functions. +- Flag broad catch-all test files when focused source-mirrored tests would make ownership clearer. +- Flag Nova-managed validation that bypasses `Test-NovaBuild` with direct `Invoke-Pester`. +- Flag any PSScriptAnalyzer rule excludes or suppressions; the code should be fixed instead. +- Flag unresolved ScriptAnalyzer findings from `run.ps1` or `Invoke-ScriptAnalyzerCI.ps1`; they should be fixed instead of deferred. +- Flag every changed or generated text file if they do not exactly have one trailing newline with no extra blank lines at the bottom. ## Inputs to inspect @@ -29,11 +43,12 @@ Review changes for correctness, maintainability, test coverage, workflow safety, - `/codescene-quality` - `/safeguarding-ai-generated-code` -- `/docs-site-html` +- `/building-maintainable-code` +- `/docs-site` - `/markdown-authoring` - `/pester-testing` -- `/github-actions` - `/release-and-changelog` +- `/github-actions` ## Constraints diff --git a/.github/agents/test-engineer.agent.md b/.github/agents/test-engineer.agent.md index 358d82c8..4071d21a 100644 --- a/.github/agents/test-engineer.agent.md +++ b/.github/agents/test-engineer.agent.md @@ -13,7 +13,13 @@ Improve or maintain the repository's Pester coverage, coverage-gate behavior, an - Add missing Pester coverage for changed behavior. - Refactor brittle or duplicated tests into reusable support patterns. +- Enforce a source-mirrored test layout for new projects and newly added or changed source files. +- Keep test files and helpers compatible with the project's `project.json` `Manifest.PowerShellHostVersion` target. +- Use `.github/instructions/testing-policy.instructions.md` as the test-design source of truth while shaping `tests/**/*.ps1`. +- Use `.github/instructions/psscriptanalyzer.instructions.md` when changing tests, test helpers, or analyzer/CI helpers so the repo-standard analyzer workflow stays intact. - Keep CI coverage output compatible with the CodeScene workflow. +- Before handoff, review every changed or generated text file and normalize it to exactly one trailing newline with no extra blank lines at the bottom. + ## Inputs to inspect @@ -27,21 +33,29 @@ Improve or maintain the repository's Pester coverage, coverage-gate behavior, an - `/pester-testing` - `/codescene-quality` +- `/building-maintainable-code` - `/github-actions` - `/guiding-refactoring-with-code-health` - `/safeguarding-ai-generated-code` ## Constraints -- Prefer targeted tests first, then the full repo quality loop. +- Prefer the smallest `Test-NovaBuild` scope the project already supports, then the full repo quality loop. - Keep test files maintainable; passing tests are not enough if Code Health degrades. - Reuse existing fixture and support patterns before adding new ones. +- Do not group unrelated source files into one broad test file when mirrored `tests/public`, `tests/private`, or `tests/classes` ownership is possible. +- Do not introduce PowerShell 7.x-only test syntax or APIs into a project that targets `5.1` unless compatibility coverage is explicitly part of the scope. - If CodeScene flags a regression, refactor the tests or helpers instead of suppressing the finding. +- Keep new or heavily changed tests focused, isolated, and easy to scan; split setup or assertion helpers when a test stops being readable. +- Use `./scripts/build/Invoke-ScriptAnalyzerCI.ps1` as the normal analyzer entrypoint for changed test/helpers, and only fall back to direct `Invoke-ScriptAnalyzer` for focused local investigation with the repository-approved settings. +- Use `Test-NovaBuild` as the test entrypoint for Nova-managed projects; do not validate with direct `Invoke-Pester`. ## Definition of done - The changed behavior is covered. +- Each new or changed `src/**/*.ps1` file has a matching source-mirrored test, or the cross-cutting owner test is named explicitly. - The touched tests are readable and low-duplication. +- Validation uses `Test-NovaBuild` for project test execution. - Validation and CodeScene implications are addressed. - The pre-commit CodeScene safeguard is clean before the work is treated as commit-ready when local CodeScene tooling is available. diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 43e2548e..e8a83d51 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -2,108 +2,64 @@ ## Purpose -Use this file as the repository-wide Copilot instruction entry point for NovaModuleTools. - -NovaModuleTools is not a generic PowerShell repo. It has a strong split between public commands, private helpers, Pester-heavy testing, GitHub Actions automation, CodeScene coverage gates, and Keep a Changelog / SemVer release flow. +Index of repository-wide Copilot guidance for NovaModuleTools. This file is intentionally thin. Canonical rule text lives in `.github/instructions/` (path-scoped, auto-loaded by Copilot) and how-to guidance lives in `.github/skills/`. ## Start here -Read these files before making non-trivial changes: +For non-trivial changes, read in this order: 1. `README.md` 2. `CONTRIBUTING.md` 3. `.github/pull_request_template.md` -4. The relevant file in `.github/instructions/` -5. The relevant skill under `.github/skills//SKILL.md` - -Prompt templates under `.github/prompts/*.prompt.md` are not auto-loaded. Reference them explicitly in chat when you want to use one of the repository's reusable task prompts. +4. `.github/instructions/repository-conventions.instructions.md` — cross-cutting rules +5. The topic-scoped instruction file(s) that match the paths you are touching +6. The skill listed under that topic in the task map below -For new or not-yet-scoped work, start with `.github/agents/architect.agent.md` and -`.github/prompts/design-change.prompt.md`. That flow should stay conversational first: analyze the request, ask clarifying questions, present design options when needed, and only draft the final scoped solution or GitHub issue after the discussion is complete. When unresolved questions still remain, architect should surface what is settled vs unresolved before asking whether to finalize, and should allow either full finalization or a resumable design-package-only handoff. Proposed scope cuts or out-of-scope boundaries must be confirmed by the user before they are treated as final. +For new or not-yet-scoped work, use the `architect` agent with `.github/prompts/design-change.prompt.md`. The architect flow is discussion-first: clarify the request, explore options, and only finalize a scoped solution or issue draft after the discussion is done. ## Repository map -- `src/public/` - public PowerShell command surface; one top-level function per file -- `src/private/` - internal helpers grouped by domain (`build/`, `cli/`, `package/`, `quality/`, `release/`, `scaffold/`, `shared/`, `update/`) -- `tests/` - Pester tests and shared test-support scripts -- `scripts/build/` - local analyzer and build helpers -- `scripts/build/ci/` - CI coverage, CodeScene, and artifact helpers -- `.github/workflows/` - GitHub Actions CI, analyzer, dependency review, and publish automation -- `.github/actions/` - reusable workflow actions used by release and coverage flows -- `docs/NovaModuleTools/en-US/` - command help source -- `docs/*.html` - end-user GitHub Pages content - -## Repository-wide rules - -- Keep changes small, reviewable, and easy to validate. -- Do not invent behavior that is not visible in source, tests, docs, workflows, or issues. -- Preserve the distinction between PowerShell cmdlet UX and `nova` CLI UX. -- Review `README.md`, `CONTRIBUTING.md`, `CHANGELOG.md`, and `RELEASE_NOTE.md` after every meaningful change. -- Update tests when behavior changes. -- Prefer existing helpers and support files over ad hoc duplication. -- Treat Code Health as authoritative for maintainability in this repository. -- Target Code Health `10.0` for AI-touched files; `9.x` is not the goal state. -- Prefer small, incremental refactors over large rewrites when fixing maintainability issues. -- Keep `docs/*.html`, `docs/NovaModuleTools/en-US/*.md`, and contributor docs clearly separated by audience and syntax. - -## Commit message guidance - -- When you are asked to suggest or prepare a commit message, answer in English. -- Use Conventional Commit format. -- Extract the ticket number from `$GIT_BRANCH_NAME` and render it as `(#)` immediately after the type when one is available. -- If `$GIT_BRANCH_NAME` starts with `hotfix/` or `bug/`, use `fix` as the type even when the implementation looks more like a feature. Use `fix!` if that branch change is also breaking. -- Otherwise estimate the type from the actual change: - - `feat` for feature work - - `fix` for bug fixes - - `feat!` for breaking feature work - - `fix!` for breaking fixes -- Keep the subject short, specific, and free of unnecessary detail. -- If you provide multiple commit message suggestions or summarize multiple change options, use bullet points. -- Do not invent a ticket number when `$GIT_BRANCH_NAME` does not contain one. - -## Markdown output guidance - -- When the output is intended to be copied as Markdown from the UI or written to a Markdown file, follow the `markdown-authoring` skill (`.github/skills/markdown-authoring/SKILL.md`). -- Apply that rule especially to release summaries, review summaries, contributor-facing Markdown docs, prompt output, and PR-template-shaped text. - -## Validation expectations - -Use the smallest validation set that proves the change, then run the repository quality loop before finishing code work: - -- local quality loop: `pwsh -NoLogo -NoProfile -File ./run.ps1` -- targeted tests: `Invoke-Pester -Path ./tests/.Tests.ps1 -Output Detailed` -- analyzer only: `./scripts/build/Invoke-ScriptAnalyzerCI.ps1` -- CI-parity coverage flow: `./scripts/build/ci/Invoke-NovaModuleToolsCI.ps1 -OutputDirectory ./artifacts` - -When CodeScene tooling is available: - -- run the pre-commit safeguard on AI-touched changes before suggesting a commit -- run a branch/change-set analysis before suggesting a PR or declaring a larger change ready -- if CodeScene reports a regression, refactor instead of treating the work as done -- use the `guiding-refactoring-with-code-health` skill for small, measured Code Health-driven refactors -- use the `safeguarding-ai-generated-code` skill when deciding whether AI-touched work is ready for commit or PR handoff - -If CodeScene tooling is unavailable locally, continue with the normal repository validation flow and continue silently; the pull request and CI flow remains the effective CodeScene gate. - -For documentation-only changes, executable validation may be skipped if no code path or workflow behavior changed. - -## File formatting rule - -- Modified or created text files must end with exactly one trailing newline. -- Do not leave multiple blank lines at the end of edited files. -- Do not alter internal whitespace just to enforce the trailing newline rule. - -## Safety constraints - -- Do not publish packages, create tags, or push changes unless explicitly requested. -- Do not modify GitHub Actions release automation casually; `Publish.yml` mutates `main` and `develop`. -- Do not bypass warnings or guards silently; Nova uses explicit `-OverrideWarning` / `--override-warning`. -- Do not add raw infrastructure calls in public commands when an adapter/helper layer already exists. +- `src/public/` — public PowerShell commands; one top-level function per file, file name matches function name +- `src/private/` — domain-grouped helpers (`build/`, `cli/`, `package/`, `quality/`, `release/`, `scaffold/`, `shared/`, `update/`); one externally called helper per file +- `tests/` — Pester tests and shared test-support scripts +- `scripts/build/` — local analyzer and build helpers +- `scripts/build/ci/` — CI coverage, CodeScene, and artifact helpers +- `.github/workflows/` — GitHub Actions CI, analyzer, dependency review, publish automation +- `.github/actions/` — reusable workflow actions used by release and coverage flows +- `docs/NovaModuleTools/en-US/` — PlatyPS command help source +- `docs/*.html` — end-user GitHub Pages content +- `.github/instructions/` — canonical rules, path-scoped via `applyTo:` +- `.github/skills/` — how-to playbooks invoked through the `skill` tool +- `.github/agents/` — role definitions for specialized agents +- `.github/prompts/` — reusable task prompts (not auto-loaded; invoke explicitly with `@.github/prompts/.prompt.md`) + +## Task map + +The table below shows how to route work. Prompts are the task entry points; each prompt delegates to its agent, which uses the listed skills, which in turn enforce the listed instructions. + +| Task | Prompt | Agent | Primary skills | Primary instructions | +| ----------------------------- | ------------------------------------------ | ---------------------- | ------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------- | +| Design or scope a change | `design-change.prompt.md` | `architect` | `powershell-module-development`, `github-actions`, `release-and-changelog`, `markdown-authoring` | `repository-conventions`, `code-quality-matrix` | +| Implement an issue | `implement-issue.prompt.md` | `powershell-developer` | `powershell-module-development`, `pester-testing`, `building-maintainable-code`, `codescene-quality`, `safeguarding-ai-generated-code` | `repository-conventions`, `code-quality-matrix`, `psscriptanalyzer`, `powershell-coding-standards`, `platyps-help` | +| Review a change | `review-change.prompt.md` | `reviewer` | `codescene-quality`, `safeguarding-ai-generated-code`, `building-maintainable-code`, `docs-site`, `markdown-authoring`, `pester-testing`, `release-and-changelog`, `github-actions` | All `.github/instructions/*.instructions.md` | +| Improve test coverage | `improve-test-coverage.prompt.md` | `test-engineer` | `pester-testing`, `building-maintainable-code`, `codescene-quality`, `github-actions`, `guiding-refactoring-with-code-health`, `safeguarding-ai-generated-code` | `testing-policy`, `psscriptanalyzer` | +| Prepare a release | `prepare-release.prompt.md` | `release-manager` | `release-and-changelog`, `markdown-authoring` | `release-policy`, `repository-conventions` | +| Fix a CI failure | `fix-ci-failure.prompt.md` | `powershell-developer` (or `test-engineer`) | `github-actions`, `pester-testing` | `testing-policy`, `psscriptanalyzer`, `repository-conventions` | +| Update website docs | (no dedicated prompt — invoke agent) | `docs-site` | `docs-site`, `markdown-authoring` | `documentation-separation` | + +## Notation + +- Skills referenced as `/skill-name` in agent files map 1-to-1 to the `name:` field in `.github/skills//SKILL.md`. The runtime invokes them through the `skill` tool with the bare name. +- Prompts are referenced by path. Custom prompts are not auto-loaded by the Copilot CLI; invoke them explicitly with `@.github/prompts/.prompt.md`. +- Instructions auto-load when their `applyTo:` glob matches a file in the change set. ## Related guidance -- `.github/instructions/powershell-coding-standards.instructions.md` -- `.github/instructions/testing-policy.instructions.md` -- `.github/instructions/release-policy.instructions.md` -- `.github/instructions/documentation-separation.instructions.md` -- `.github/skills/markdown-authoring/SKILL.md` +- Cross-cutting rules: `.github/instructions/repository-conventions.instructions.md` +- Source code maintainability: `.github/instructions/code-quality-matrix.instructions.md` + `building-maintainable-code` skill +- Testing: `.github/instructions/testing-policy.instructions.md` + `pester-testing` skill +- PSScriptAnalyzer workflow: `.github/instructions/psscriptanalyzer.instructions.md` +- PowerShell coding standards: `.github/instructions/powershell-coding-standards.instructions.md` +- PlatyPS help generation: `.github/instructions/platyps-help.instructions.md` +- Release flow: `.github/instructions/release-policy.instructions.md` + `release-and-changelog` skill +- Documentation separation: `.github/instructions/documentation-separation.instructions.md` + `docs-site` skill diff --git a/.github/instructions/code-quality-matrix.instructions.md b/.github/instructions/code-quality-matrix.instructions.md new file mode 100644 index 00000000..ba1261b5 --- /dev/null +++ b/.github/instructions/code-quality-matrix.instructions.md @@ -0,0 +1,138 @@ +--- +applyTo: "src/**/*.ps1,scripts/**/*.ps1,run.ps1,reload.ps1" +--- + +# Code quality matrix + +## Purpose + +Use this file as the maintainability guidance for PowerShell source and helper scripts in this repository. + +It frames ten widely recognized maintainability dimensions in PowerShell terms: unit size, unit complexity, duplication, interface width, separation of concerns, coupling, component balance, codebase size, automated tests, and clean code. Each guideline below covers one dimension with concrete PowerShell thresholds. + +This file tells Agentic Copilot how to shape source code from the start. Test-specific guidance lives in `.github/instructions/testing-policy.instructions.md` and the `pester-testing` skill. The matching operational workflow for these ten rules lives in the `building-maintainable-code` skill. + +## How to apply this guidance + +- Use these rules when writing or reviewing `src/**/*.ps1`, `scripts/**/*.ps1`, `run.ps1`, and `reload.ps1`. +- Prefer these patterns in new or heavily changed code instead of leaving cleanup for later. +- Treat the thresholds as default goals, not as opinions. Use them to decide whether a function or file should be split. +- If a change must violate one of these rules, keep the exception narrow and explain the trade-off clearly in the handoff. +- Favor small refactors that remove the smell at the source over comments, suppressions, or wrappers that only hide it. +- Apply lower-level (unit) guidelines before higher-level (component) guidelines. Fix size, complexity, duplication, and interface width first; balance and component coupling become much easier afterward. +- Every commit counts. Leave each touched file at least as healthy as you found it; that is how the codebase trends upward over time. + +## Guideline 1 — Write short units of code + +- Threshold: keep each PowerShell function body at most 15 lines, excluding the `function` line, the closing `}`, the `param(...)` block, and blank lines. +- Why: short units are easier to read, test, reuse, and review, and they fit inside human and agent working memory. +- How to apply in PowerShell: + - Extract named helper functions; in `src/private/` they may stay as sibling top-level functions in the same file when they belong together. + - Replace inline transformation chains with a helper named after its intent. + - Move repeated setup or formatting into helpers, not into comments that mark sections. +- Common objection: "It is one logical step." If the function still ends up over 15 lines, the step has substeps. Name them. + +## Guideline 2 — Write simple units of code + +- Threshold: keep cyclomatic complexity at most 5, which is 4 branch points. Count `if`, `elseif`, `switch` case bodies, `-and`, `-or`, ternary `? :`, `while`, `for`, `foreach`, and `catch`. +- Why: complex units have too many paths to test thoroughly and are the most common source of regressions. +- How to apply in PowerShell: + - Replace long `switch` blocks or `if`/`elseif` chains with a dispatch hashtable keyed by mode, provider, state, or kind. + - Replace nested decision branches with early returns and small `Test-*` / `Resolve-*` / `Get-*Action` helpers. + - Use PowerShell classes when several branches behave like the same operation on different data. +- Common objection: "The domain is complex." The domain may be complex; the unit must not be. Split the decision layer from the work layer. + +## Guideline 3 — Write code once + +- Rule: no Type 1 clones. Any identical block of 6 or more functional lines that appears twice is a finding. +- Why: duplicated code drifts. Bugs fixed in one copy keep living in the other. +- How to apply in PowerShell: + - Extract the shared block into a helper under the correct `src/private//` folder and call it from both sites. + - When two flows differ only in inputs or order of small steps, parameterize the helper instead of cloning it. + - For repeated test setup, extend `tests/*TestSupport.ps1` or `tests/TestHelpers/` instead of copying `BeforeAll` blocks. +- Common objection: "It is a small variation, so cloning is fine." Extract the shared part and pass the variation as a parameter, a scriptblock, or a small lookup table. + +## Guideline 4 — Keep unit interfaces small + +- Threshold: at most 4 parameters per function. `[CmdletBinding()]` common parameters do not count. +- Why: long parameter lists are hard to read at the call site, hard to extend safely, and usually a sign that two or more concepts have been bundled into one function. +- How to apply in PowerShell: + - Group related parameters into a single `[pscustomobject]`, ordered hashtable, or small class such as a workflow context, an options object, or a request. + - Use parameter sets when the function legitimately supports more than one calling shape, not as a way to hide 8 parameters in one signature. + - Pass already-prepared context objects (for example `WorkflowContext`, `BuildOption`, `TestOption`) between helpers instead of passing every individual field. +- Common objection: "Each parameter is needed." If they always travel together, give the group a name and pass it as one object. + +## Guideline 5 — Separate concerns in modules + +- Rule: each file owns one externally called responsibility. +- Why: modules that mix concerns become magnets for unrelated changes and are harder to test, replace, or move. +- How to apply in PowerShell: + - In `src/public/`, keep exactly one top-level public function per file, matching the file name. + - In `src/private/`, keep at most one externally called function per file. Additional helpers may stay as sibling top-level functions in the same file when they belong to that entry function. + - Do not declare nested functions inside other functions. Keep helpers as siblings at file scope. + - When a private file starts mixing lookup, mutation, formatting, validation, and transport, split it by concern before it becomes a catch-all helper. +- Common objection: "It is convenient to keep both here." Convenience now becomes confusion later. Split early, while the seams are still obvious. + +## Guideline 6 — Couple architecture components loosely + +- Rule: public commands depend on private adapter/helper layers, not on raw infrastructure. +- Why: tight coupling to environment variables, Git, HTTP, file system, or module-update APIs spreads infrastructure leaks across the public surface and breaks tests. +- How to apply in PowerShell: + - Route environment access, Git execution, REST calls, uploads, and self-update behavior through their approved private helpers. `tests/ArchitectureGuardrails.Tests.ps1` is authoritative. + - Hide provider-specific or platform-specific branching behind a small adapter surface so callers depend on a stable contract, not on the provider's quirks. + - Avoid pass-through helpers that only forward parameters to another function. Either add policy, validation, translation, or abstraction, or call the underlying function directly. +- Common objection: "The adapter feels redundant." It pays off the moment the underlying call changes, gains an error mode, or needs mocking. + +## Guideline 7 — Keep architecture components balanced + +- Rule: keep `src/private//` folders and the public surface balanced in size and responsibility. +- Why: one folder absorbing everything is a code smell at the component level. It signals missing domains. +- How to apply in PowerShell: + - When one private domain keeps absorbing unrelated responsibilities, propose a new domain folder before it becomes the default dumping ground. + - When the public command surface starts mixing CLI routing, package operations, and quality flows in the same file, split the public command instead of growing it. + - Keep workflow contexts narrow per workflow. A single context object that knows everything about every flow is a balance smell. +- Common objection: "It is only a few helpers." A few becomes many. Name the concern early so callers and reviewers can find them. + +## Guideline 8 — Keep your codebase small + +- Rule: do not let the codebase grow for its own sake. +- Why: every line written is a line maintained, tested, reviewed, scanned, and reasoned about. +- How to apply in PowerShell: + - Remove dead code, obsolete private helpers, and commented-out code instead of leaving them "just in case." Source control is the safety net. + - Prefer existing platform capabilities, repository helpers, and well-known modules over custom utility layers when the custom code adds no durable value. + - When extending behavior, ask whether the extension belongs in an existing helper rather than as a parallel new helper. + - Treat scaffold and template additions like production code; they multiply across every generated project. +- Common objection: "We might need it later." Delete it now. Re-add it later from history with the context that proves it is needed. + +## Guideline 9 — Automate tests + +- Rule: every behavior change requires Pester coverage in this repository. +- Why: automated tests make change safe, predictable, and reviewable, and they are the only practical way to prevent regressions in a continuously evolving codebase. +- How to apply in PowerShell: + - Add or update a source-mirrored `tests//.Tests.ps1` file for every changed `src/**/*.ps1` file. + - Cover both the happy path and the meaningful unhappy, invalid, and boundary cases that the change introduces. + - Use `Test-NovaBuild` as the authoritative test entrypoint in Nova-managed projects. Do not call `Invoke-Pester` directly. + - Isolate collaborators with mocks/stubs when verifying side effects or branching. Keep tests order-independent. + - See `.github/instructions/testing-policy.instructions.md` and the `pester-testing` skill for the full testing rules. +- Common objection: "It is too small to test." If it is too small to test, it is too small to be a change worth landing. + +## Guideline 10 — Write clean code + +- Rule: leave no trace. Touched files leave with fewer smells than they arrived with. +- Why: small smells compound. A few magic numbers, a few swallowed exceptions, a few commented-out blocks per commit becomes an unmaintainable file in months. +- How to apply in PowerShell: + - No bad comments. If a comment is needed to explain a line, rename the helper or split the function until the comment becomes redundant. + - No commented-out code. Use source control history instead. + - No dead code. Remove unreachable branches and unused private helpers. + - No long or multi-responsibility identifiers. Use focused, intent-revealing names. + - No magic literals. Lift unexplained numbers and strings into named constants, script variables, or lookup tables. + - No broad catches. Catch specific exceptions only when the layer adds context; otherwise let failures surface clearly through `Stop-NovaOperation` or a structured `ErrorRecord` instead of silent fallback. + - Files must end with exactly one trailing newline and no extra blank lines at the bottom. +- Common objection: "Style is taste." Style is repeatable. These items are not taste, they are signals reviewers and tools rely on. + +## Review expectations + +- Flag long mixed-responsibility functions, deep nesting, duplicated blocks, long parameter lists, pass-through helpers, provider-specific branching spread across callers, dead or commented-out code, magic values, and broad or hidden exception handling. +- When a finding is unit-level (Guidelines 1–4), prefer raising it before component-level findings (Guidelines 5–8). The unit fix usually makes the component fix smaller. +- When the code smell is test-specific, route that feedback through `.github/instructions/testing-policy.instructions.md` and the `pester-testing` skill instead of stretching this file to cover test-only patterns. +- For step-by-step refactoring of unhealthy files, use the `building-maintainable-code` and `guiding-refactoring-with-code-health` skills together: the first picks the right guideline, the second runs measured Code Health checks between steps. diff --git a/.github/instructions/platyps-help.instructions.md b/.github/instructions/platyps-help.instructions.md new file mode 100644 index 00000000..dcb320ce --- /dev/null +++ b/.github/instructions/platyps-help.instructions.md @@ -0,0 +1,93 @@ +--- +applyTo: "docs/NovaModuleTools/**/*.md" +--- + +# PlatyPS command help rules + +## Scope + +Use this file when creating or updating command help under `docs/NovaModuleTools/en-US/`. + +## Why this matters + +- Nova build imports command-help markdown with `Import-MarkdownCommandHelp` and converts it to MAML with `Export-MamlCommandHelp`. +- `Microsoft.PowerShell.PlatyPS` is part of Nova's help toolchain, so use its cmdlets instead of inventing command-help Markdown by hand. + +## Required workflow + +1. Build and import the dist module before generating or updating help files. This ensures PlatyPS picks up the correct module name for both the `Module Name` and `external help file` metadata fields. + +```powershell +Invoke-NovaBuild +Import-Module ./dist/NovaModuleTools/NovaModuleTools.psd1 -Force +``` + +2. For new command help, generate the initial skeleton with `New-MarkdownCommandHelp` from the imported module commands rather than starting from a blank Markdown file. + +```powershell +$newMarkdownHelp = @{ + CommandInfo = Get-Command -Module 'NovaModuleTools' + OutputFolder = './docs' + WithModulePage = $true + Force = $true +} +New-MarkdownCommandHelp @newMarkdownHelp +``` + +3. Every new public entry point must add its matching command-help file in the same change. A new `src/public/.ps1` file is not done until `docs/NovaModuleTools/en-US/.md` exists. +4. Keep the resulting command-help files under `docs/NovaModuleTools/en-US/` before handoff. If you generate files in a staging folder first, move the command-help markdown files into the repository's locale folder before you finish. +5. For existing command help, refresh syntax and parameter metadata with `Update-MarkdownCommandHelp` instead of editing the generated YAML structure by hand. + +```powershell +Measure-PlatyPSMarkdown -Path ./docs/NovaModuleTools/en-US/*.md | + Where-Object FileType -match 'CommandHelp' | + Update-MarkdownCommandHelp -Path {$_.FilePath} +``` + +6. Validate the final help with `Test-MarkdownCommandHelp -DetailView`, and inspect `Import-MarkdownCommandHelp` diagnostics when the structure or build result is unclear. + +```powershell +Test-MarkdownCommandHelp -Path ./docs/NovaModuleTools/en-US/*.md -DetailView + +Import-MarkdownCommandHelp -Path ./docs/NovaModuleTools/en-US/.md | + Select-Object -ExpandProperty Diagnostics +``` + +7. Remember the build path: Nova effectively runs `Measure-PlatyPSMarkdown | Import-MarkdownCommandHelp | Export-MamlCommandHelp`. If your help files fail that path, the help is not done yet. +8. `-WithModulePage` is optional. Nova build consumes the command-help markdown files; a module page can exist, but it does not replace per-command help. + +## Required format + +- Files under `docs/NovaModuleTools/en-US/` must be valid PlatyPS command-help markdown, not plain project prose. +- Start new help files from a PlatyPS-generated skeleton or from an existing valid help file that already matches the repository's help shape. +- Keep one command-help file per public entry point, and match the markdown file name to the command name. +- Keep the YAML metadata block at the top of every help file, delimited by `---`. +- Keep the metadata aligned with the command being documented. At minimum, preserve the same metadata keys used by the repository's existing valid help files, including `document type`, `external help file`, `HelpUri`, `Locale`, `Module Name`, `ms.date`, `PlatyPS schema version`, and `title`. +- The `external help file` field must always use the module name, not the command name: `NovaModuleTools-Help.xml`. The `Module Name` field must match the project name. When both fields use the module name, Nova build produces a single `-Help.xml` under `dist//en-US/`. If either field contains a command name instead, the build produces per-command XML files and the module manifest cannot find its help. +- Keep the H1 title equal to the exact command name. +- Preserve the standard PlatyPS section order with uppercase H2 headers: `SYNOPSIS`, `SYNTAX`, optional `ALIASES`, `DESCRIPTION`, `EXAMPLES`, `PARAMETERS`, `INPUTS`, `OUTPUTS`, `NOTES`, and `RELATED LINKS`. +- Keep at least one example under `## EXAMPLES`. +- Keep parameter sections as `### -ParameterName` blocks with the PlatyPS-generated YAML metadata code block. +- Only hand-edit parameter metadata when PlatyPS cannot infer it correctly, especially `DefaultValue` and `SupportsWildcards`. +- `## NOTES` and `## RELATED LINKS` headers are required even when the sections are empty. +- Do not add ad hoc sections or reorder the required sections. +- If content is still incomplete, keep placeholder text inside a valid PlatyPS skeleton rather than collapsing the file into generic Markdown. + +## Authoring guidance + +- Always import the built dist module (`Import-Module ./dist/NovaModuleTools/NovaModuleTools.psd1 -Force`) before running `New-MarkdownCommandHelp` or `Update-MarkdownCommandHelp`. Generating help without the module imported causes PlatyPS to default `external help file` to the command name instead of the module name, which produces per-command XML files that the module manifest cannot find. +- Prefer generating the initial help shape from the actual public command so syntax and parameter blocks stay aligned with the implementation. +- When source adds a new public entry point, create the matching help file immediately in the same change even if the narrative text still needs follow-up refinement. +- When editing an existing help file, preserve the YAML metadata and parameter sections unless you intentionally regenerate the file from the command surface. +- Use `Update-MarkdownCommandHelp` after command or parameter changes so syntax, aliases, and parameter metadata stay synchronized with the implementation. +- Use `Test-MarkdownCommandHelp` as the quick structural gate before handoff; use `Import-MarkdownCommandHelp` diagnostics when you need more detail. +- Use existing valid files under `docs/NovaModuleTools/en-US/` as the structural template before inventing a new layout. +- Keep command help separate from contributor docs and project/site docs. + +## Review expectations + +- Reviewers should flag help files that lack YAML metadata, break the expected PlatyPS section structure, skip the `New-MarkdownCommandHelp` / `Update-MarkdownCommandHelp` workflow, or look like plain Markdown prose instead of command help. +- Reviewers should flag help files where `external help file` contains a command name (e.g., `Get-Something-Help.xml`) instead of the module name (`NovaModuleTools-Help.xml`). This produces per-command XML files that the module manifest cannot locate at runtime. +- Reviewers should flag help files that would fail `Test-MarkdownCommandHelp` or produce diagnostics/errors when imported with `Import-MarkdownCommandHelp`. +- Reviewers should flag any new public entry point that does not add its matching command-help file in the same change. +- Treat build errors from `Import-MarkdownCommandHelp` as a sign that the file is not valid PlatyPS help yet. diff --git a/.github/instructions/powershell-coding-standards.instructions.md b/.github/instructions/powershell-coding-standards.instructions.md index 6c6d195f..3d1a5b7d 100644 --- a/.github/instructions/powershell-coding-standards.instructions.md +++ b/.github/instructions/powershell-coding-standards.instructions.md @@ -12,13 +12,19 @@ Use this file when changing `src/public/`, `src/private/`, or PowerShell build/r - Keep public command files small and delegating. - Keep exactly one top-level public function per file in `src/public/`. +- Match the file name to that top-level public function name. - Public mutating commands should support PowerShell `ShouldProcess` semantics. -- Preserve existing naming and command model conventions such as `Invoke-Nova*`, `Get-Nova*`, `Update-Nova*`, and the - `nova` CLI routing model. +- Preserve existing naming and command model conventions for public commands/functions such as `Invoke-Nova*`, `Get-Nova*`, `Update-Nova*`, and the `nova` CLI routing model. +- Do not create or maintain hand-written module `.psm1` or module `.psd1` files in source. Nova generates the built module root and manifest under `dist/NovaModuleTools/` from `project.json` and `src/**/*.ps1`. ## Internal structure rules - Put internal helpers in the correct domain folder under `src/private/`. +- In `src/private/`, keep at most one externally called function per file and match the file name to that entry function. +- Additional functions in a private file are allowed only as related top-level support helpers called from that same file. +- If two private functions are both called from outside their file, split them into separate same-named files. +- Do not declare functions inside other functions. Keep private support helpers as sibling top-level functions in the file instead of nested function declarations. +- Private helper names should not use the public `Invoke-Nova*`, `Get-Nova*`, `Update-Nova*`, or `nova` CLI route naming conventions. Give private helpers clear implementation-focused names that describe what the helper does. - Reuse existing adapters and shared helpers before adding new infrastructure calls. - Keep direct environment access, Git execution, upload requests, and self-update execution in their approved helper locations. `tests/ArchitectureGuardrails.Tests.ps1` is authoritative. - Prefer explicit workflow-context objects (`[pscustomobject]` / ordered hashtables) for multi-step flows. @@ -28,6 +34,12 @@ Use this file when changing `src/public/`, `src/private/`, or PowerShell build/r - Prefer clear, structured Nova errors over silent fallback behavior. - Preserve existing warning semantics; do not rename warning opt-ins to a generic `-Force` pattern. - Keep CLI spellings and PowerShell spellings distinct in messages and docs. +- Read `project.json` `Manifest.PowerShellHostVersion` before changing PowerShell source, scripts, or tests, and keep new usage compatible with that target. A `5.1` project must not receive PowerShell 7.x-only syntax, cmdlets, parameters, or APIs unless compatibility is explicitly guarded and within scope. +- Follow `.github/instructions/psscriptanalyzer.instructions.md` as the ScriptAnalyzer workflow source of truth. Use the repository analyzer wrapper for normal runs and reuse repository-approved settings when invoking `Invoke-ScriptAnalyzer` directly on a focused path. +- When public command help changes, follow `.github/instructions/platyps-help.instructions.md` and use `New-MarkdownCommandHelp`, `Update-MarkdownCommandHelp`, and `Test-MarkdownCommandHelp` instead of hand-authoring the help structure. +- Do not add PSScriptAnalyzer `ExcludeRule`, `ExcludeRules`, suppression attributes, or generated settings that hide analyzer findings. Fix the rule violation instead. +- Keep local quality wrappers ordered as ScriptAnalyzer first, then `Invoke-NovaBuild`, then `Test-NovaBuild`. +- If `run.ps1` or `Invoke-ScriptAnalyzerCI.ps1` reports ScriptAnalyzer findings, fix them before treating the change as complete. ## Formatting rules @@ -41,9 +53,7 @@ Use this file when changing `src/public/`, `src/private/`, or PowerShell build/r ### Spacing -- Use one space between language keywords and `(` in control statements such as `if (...)`, `foreach (...)`, - `switch (...)`, - `while (...)`, and `for (...)`. +- Use one space between language keywords and `(` in control statements such as `if (...)`, `foreach (...)`, `switch (...)`, `while (...)`, and `for (...)`. - Use one space before an opening `{`. - Use one space around binary, comparison, and logical operators. - Use one space after commas in parameter and argument lists. @@ -65,15 +75,24 @@ Use this file when changing `src/public/`, `src/private/`, or PowerShell build/r - Do not stack multiple blank lines. - Avoid decorative blank lines inside short blocks. - Keep one blank line between top-level declarations when a file contains more than one declaration. +- Every changed or generated text file, including `.ps1` files, must end with exactly one trailing newline and no extra blank lines at the bottom. ## Maintainability rules +- Use `.github/instructions/code-quality-matrix.instructions.md` as the best-effort source-code maintainability guidance for `src/**/*.ps1`; keep new or heavily changed code short, single-purpose, low-duplication, and split by clear responsibility. - Favor short functions and extracted helpers over large nested logic. +- Replace long `switch` or `if`/`elseif` chains with lookup tables, dispatch helpers, or focused strategy functions when behavior varies by mode, provider, or state. - Avoid copy/paste across source or test files. +- Remove dead code and commented-out code instead of leaving it behind. +- Prefer concise, specific names over identifiers that hide multiple responsibilities. +- Replace magic values with named constants, lookup tables, or variables that reveal intent. - Add comments only when the code would otherwise be hard to follow. +- Avoid broad catch blocks that hide failures; catch specific exceptions only when the layer can add useful context. ## Verification - Update or add Pester coverage for behavior changes. - Recheck `tests/ArchitectureGuardrails.Tests.ps1` when changing layering or helper placement. - Run `./run.ps1` before considering a code change complete. +- Resolve any ScriptAnalyzer findings that `./run.ps1` reports before handoff. +- Before handoff, review the changed/generated text files and normalize any file endings that violate the single-trailing-newline rule. diff --git a/.github/instructions/psscriptanalyzer.instructions.md b/.github/instructions/psscriptanalyzer.instructions.md new file mode 100644 index 00000000..82cf78a7 --- /dev/null +++ b/.github/instructions/psscriptanalyzer.instructions.md @@ -0,0 +1,39 @@ +--- +applyTo: "src/**/*.ps1,tests/**/*.ps1,scripts/**/*.ps1,run.ps1,reload.ps1" +--- + +# PSScriptAnalyzer workflow rules + +## Scope + +Use this file when changing PowerShell code, tests, build helpers, or analyzer wrappers. + +## Why this matters + +- PSScriptAnalyzer is the supported static analyzer for PowerShell scripts and modules in this repository. +- The repository quality loop already expects ScriptAnalyzer to run before build and test, so agents should follow that workflow instead of inventing their own lint steps. + +## Required workflow + +1. Use the repository wrappers as the authoritative entrypoints: + - analyzer only: `./scripts/build/Invoke-ScriptAnalyzerCI.ps1` + - full local loop: `./run.ps1` +2. Use raw `Invoke-ScriptAnalyzer` only for focused local investigation or when you are deliberately changing analyzer tooling. +3. When you call `Invoke-ScriptAnalyzer` directly, point it at real `.ps1`, `.psm1`, or `.psd1` paths, use `-Recurse` when analyzing a directory, and reuse the repository-approved analyzer settings through `-Settings` instead of inventing a new rule selection. +4. Treat `Error`, `Warning`, and `ParseError` diagnostics as findings to fix before handoff. Parser errors are analyzer diagnostics too and are not something to suppress away. +5. Do not add ad hoc `ExcludeRule`, `ExcludeRules`, `SuppressMessageAttribute`, or custom settings changes just to make the analyzer pass. Only keep analyzer exceptions that the repository already approves and can justify narrowly. +6. `Invoke-ScriptAnalyzer -Fix` is optional and only applies to selected rules. Review every change it would make, prefer `-WhatIf` first, and inspect the diff afterwards. +7. `Invoke-ScriptAnalyzer -EnableExit` is useful for CI shells, but if the repository already has a wrapper with established failure semantics, do not replace that wrapper with an ad hoc direct invocation. + +## Authoring guidance + +- Prefer one focused analyzer run on the changed files while iterating, then rerun `./scripts/build/Invoke-ScriptAnalyzerCI.ps1`, then `./run.ps1` before handoff. +- Keep analyzer wrappers focused on source files and helper scripts, not generated output such as `dist/` or `artifacts/`. +- If the repository has a `PSScriptAnalyzerSettings.psd1` file or a wrapper-owned settings hashtable, treat that configuration as authoritative for direct `Invoke-ScriptAnalyzer` runs. +- Built-in presets such as `PSGallery` or `CodeFormatting` exist, but do not switch to them unless the repository explicitly adopts them. + +## Review expectations + +- Reviewers should flag direct `Invoke-ScriptAnalyzer` usage that bypasses the repository wrapper or repository-approved settings without a clear reason. +- Reviewers should flag new rule suppressions, exclusions, or analyzer-setting changes that are broader than the specific justified need. +- Reviewers should flag PowerShell changes handed off with unresolved analyzer findings. diff --git a/.github/instructions/release-policy.instructions.md b/.github/instructions/release-policy.instructions.md index 81427c89..528ffd6b 100644 --- a/.github/instructions/release-policy.instructions.md +++ b/.github/instructions/release-policy.instructions.md @@ -29,8 +29,7 @@ Use this file when changing versioning, changelog handling, package metadata, pu - `Publish.yml` owns the release/publish flow. - `main` handles stable release commit/tag flow and prepares `develop` for the next prerelease. - `develop` handles prerelease publish and next-prerelease bump flow. -- Do not change branch mutation behavior, tag creation, or publish steps without reading `.github/workflows/Publish.yml` - and the related custom actions first. +- Do not change branch mutation behavior, tag creation, or publish steps without reading `.github/workflows/Publish.yml` and the related custom actions first. ## Documentation rules diff --git a/.github/instructions/repository-conventions.instructions.md b/.github/instructions/repository-conventions.instructions.md new file mode 100644 index 00000000..c31d5036 --- /dev/null +++ b/.github/instructions/repository-conventions.instructions.md @@ -0,0 +1,82 @@ +--- +applyTo: "**" +--- + +# Repository conventions + +## Purpose + +Canonical rule source for cross-cutting NovaModuleTools conventions that apply to every change. Topic-specific rules live in the other `.instructions.md` files; this file owns the rules that do not belong to one topic. + +## Project layering + +- Treat `project.json` as the source of truth for project metadata, build output, package settings, and release settings. +- Treat `project.json` `Manifest.PowerShellHostVersion` as the compatibility target for PowerShell code, tests, and examples. If a project targets `5.1`, do not introduce PowerShell 7.x-only syntax, cmdlets, parameters, or APIs unless the work explicitly adds guarded compatibility handling. +- Use Nova commands and repository wrappers for build, test, package, and release workflows; do not replace them with ad hoc PowerShell module build scripts. +- Do not create or maintain hand-written module `.psm1` or module `.psd1` files in source; Nova generates the built module root and manifest under `dist/NovaModuleTools/` from `project.json` and `src/**/*.ps1`. +- Preserve the distinction between PowerShell cmdlet UX and `nova` CLI UX. + +## File ownership + +- `src/public/` files own exactly one top-level function each. The file name matches the function name. +- `src/private/` files expose at most one externally called function per file. Additional helpers may stay as sibling top-level functions in the same file when they belong to that entry function. The file name matches the externally called function. +- PowerShell functions must not declare nested functions inside their bodies. +- Prefer existing helpers and support files over ad hoc duplication. +- Do not add raw infrastructure calls in public commands when an adapter/helper layer already exists. + +## Validation expectations + +Use the smallest validation set that proves the change, then run the repository quality loop before finishing code work: + +- local quality loop: `pwsh -NoLogo -NoProfile -File ./run.ps1` +- test validation: `Test-NovaBuild` +- analyzer only: `./scripts/build/Invoke-ScriptAnalyzerCI.ps1` +- CI-parity coverage flow: `./scripts/build/ci/Invoke-NovaModuleToolsCI.ps1 -OutputDirectory ./artifacts` + +If `run.ps1` or `./scripts/build/Invoke-ScriptAnalyzerCI.ps1` reports findings, fix them before review, handoff, or commit. Do not treat a failing local quality loop as an acceptable stopping point. + +When CodeScene tooling is available: + +- run the pre-commit safeguard on AI-touched changes before suggesting a commit +- run a branch/change-set analysis before suggesting a PR or declaring a larger change ready +- if CodeScene reports a regression, refactor instead of treating the work as done + +If CodeScene tooling is unavailable locally, continue with the normal repository validation flow; pull requests and CI remain the effective gate. + +For documentation-only changes, executable validation may be skipped if no code path or workflow behavior changed. + +## Documentation review + +- Review `README.md`, `CONTRIBUTING.md`, `CHANGELOG.md`, and `RELEASE_NOTE.md` after every meaningful change. +- Update tests when behavior changes. + +## File formatting rule + +- Before handoff, review every changed or created text file and ensure it ends with exactly one trailing newline and no extra blank lines at the bottom. +- Do not leave any edited file with extra blank lines at the end, even if the functional code change is already complete. +- Do not alter internal whitespace just to enforce the trailing newline rule. + +## Safety constraints + +- Do not publish packages, create tags, or push changes unless explicitly requested. +- Do not modify GitHub Actions release automation casually; `Publish.yml` mutates `main` and `develop`. +- Do not bypass warnings or guards silently; Nova uses explicit `-OverrideWarning` / `--override-warning`. + +## Commit message guidance + +- When you are asked to suggest or prepare a commit message, answer in English. +- Use Conventional Commit format. +- Extract the ticket number from `$GIT_BRANCH_NAME` and render it as `(#)` immediately after the type when one is available. +- If `$GIT_BRANCH_NAME` starts with `hotfix/` or `bug/`, use `fix` as the type even when the implementation looks more like a feature. Use `fix!` if that branch change is also breaking. +- Otherwise estimate the type from the actual change: + - `feat` for feature work + - `fix` for bug fixes + - `feat!` for breaking feature work + - `fix!` for breaking fixes +- Keep the subject short, specific, and free of unnecessary detail. +- If you provide multiple commit message suggestions or summarize multiple change options, use bullet points. +- Do not invent a ticket number when `$GIT_BRANCH_NAME` does not contain one. + +## Markdown output + +When the output is intended to be copied as Markdown from the UI or written to a Markdown file, follow the `markdown-authoring` skill (`.github/skills/markdown-authoring/SKILL.md`). Apply that rule especially to release summaries, review summaries, contributor-facing Markdown docs, prompt output, and PR-template-shaped text. diff --git a/.github/instructions/testing-policy.instructions.md b/.github/instructions/testing-policy.instructions.md index 73a55c56..5f5c5cb3 100644 --- a/.github/instructions/testing-policy.instructions.md +++ b/.github/instructions/testing-policy.instructions.md @@ -11,32 +11,48 @@ Use this file when changing production code, tests, coverage behavior, or CI tes ## Test expectations - Behavior changes require Pester coverage. -- Prefer targeted tests close to the changed workflow area before running the full quality loop. +- Use `Test-NovaBuild` as the authoritative test entrypoint in Nova-managed projects. Do not validate with direct `Invoke-Pester`, because it can bypass Nova's build/import/StrictMode flow and disagree with what users see later. +- Prefer the smallest `Test-NovaBuild` scope the project already supports before running the full quality loop. - Keep test names explicit about the behavior being proven. - Reuse `*.TestSupport.ps1` helpers where possible. +- For every new or changed `src/**/*.ps1` file, add or update the matching source-mirrored `.Tests.ps1` file. +- Keep test files and helpers compatible with `project.json` `Manifest.PowerShellHostVersion`; if a project targets `5.1`, do not rely on PowerShell 7.x-only syntax, cmdlets, parameters, or APIs in the tests. +- Cover both the normal path and the meaningful unhappy, invalid, or boundary cases that the changed behavior introduces. +- Use mocks or stubs for collaborators when the test needs to isolate behavior or verify side effects. +- Keep tests isolated and order-independent; do not rely on shared mutable state between tests. +- Update tests when production signatures or behavior change instead of leaving stale expectations behind. +- Keep test flows linear and easy to scan; extract setup or assertion helpers when one test starts carrying too many responsibilities. +- Follow `.github/instructions/psscriptanalyzer.instructions.md` when PowerShell tests, test helpers, or build helpers change. Use `./scripts/build/Invoke-ScriptAnalyzerCI.ps1` for the repo-standard analyzer run, and use direct `Invoke-ScriptAnalyzer` only for focused local checks that reuse the repo-approved settings. +- Use broad guardrail, architecture, command-model, or integration tests only for behavior that genuinely spans multiple source files; do not use them as the default place for unit coverage of unrelated source files. ## Repository test structure - `tests/NovaCommandModel*.Tests.ps1` - public command, CLI, and workflow behavior - `tests/ArchitectureGuardrails.Tests.ps1` - layering and adapter boundaries -- `tests/*Coverage*.Tests.ps1` - targeted coverage and regression gaps - `tests/*TestSupport.ps1` - shared helpers and reusable fixtures +- Source-mirrored tests should use `tests/public/.Tests.ps1`, `tests/private//.Tests.ps1`, and `tests/classes/.Tests.ps1` for matching `src/public/`, `src/private/`, and `src/classes/` files. +- Repeated setup belongs in `tests/TestHelpers/` or `tests/*TestSupport.ps1`, not in duplicated blocks across mirrored tests. ## Coverage and CodeScene - CI coverage is generated by `./scripts/build/ci/Invoke-NovaModuleToolsCI.ps1`. -- The Cobertura artifact is reused by the CodeScene PR coverage gate and by the develop/manual CodeScene analysis flow. +- `Test-NovaBuild` runs once and produces a JaCoCo coverage report at `artifacts/coverage.xml`. +- The JaCoCo artifact is reused by the CodeScene PR coverage gate and by the develop/manual CodeScene analysis flow. +- The CodeScene analysis upload sends coverage twice: once for `line-coverage` and once for `branch-coverage`. - If CodeScene flags coverage or duplication, fix the underlying test design instead of suppressing the warning casually. ## Common pitfalls - Many tests expect the built module under `dist/NovaModuleTools`; build first when needed. +- Direct `Invoke-Pester` runs can hide Nova-specific build/import/StrictMode behavior and should not be used as the project test entrypoint. - Some support helpers must be dot-sourced and re-exported inside `BeforeAll`. - Duplicated test setup can lower Code Health even when tests pass. +- Tests that only cover the happy path can miss the edge cases that caused the change in the first place. +- Shared mutable state between tests makes failures order-dependent and unreliable. - Docs-only changes usually do not need executable validation, but workflow/test docs must still be kept accurate. ## Verification -- Targeted Pester file(s) +- `Test-NovaBuild` - `./scripts/build/Invoke-ScriptAnalyzerCI.ps1` when PowerShell code changed - `pwsh -NoLogo -NoProfile -File ./run.ps1` before completion diff --git a/.github/prompts/design-change.prompt.md b/.github/prompts/design-change.prompt.md index 7f5b373c..d438b5a8 100644 --- a/.github/prompts/design-change.prompt.md +++ b/.github/prompts/design-change.prompt.md @@ -1,5 +1,7 @@ # Design a NovaModuleTools change +> Invoke with `@.github/prompts/design-change.prompt.md`. Delegates to the `architect` agent. + Use this prompt with `architect.agent.md` when a change still needs analysis, scoping, and issue drafting before anyone starts editing files. This is a discussion-first prompt. The default behavior is to hold a short design conversation with the user before producing a final scoped solution, implementation handoff, or GitHub issue draft. @@ -49,6 +51,8 @@ Do not produce the full final design package in the first response unless the us ## Finalization output +All finalization output is copy-ready Markdown. Apply the `markdown-authoring` skill (`.github/skills/markdown-authoring/SKILL.md`) for copy-safe UI output, including any required wrapping, and do not add prose outside the final output. + If the user chooses **design package and GitHub issue draft**, return: - a short usage note that explains: @@ -65,8 +69,7 @@ If the user chooses **design package and GitHub issue draft**, return: - Recommended follow-on agent - GitHub issue draft -If unresolved questions still remain, keep them under `Open questions` in the design package and add a short `Open -questions` section inside the GitHub issue draft too. +If unresolved questions still remain, keep them under `Open questions` in the design package and add a short `Open questions` section inside the GitHub issue draft too. If the user chooses **design package only**, return: @@ -85,12 +88,13 @@ In design-package-only mode: - do not include a GitHub issue draft - preserve the settled decisions clearly enough that the user can resume later - end with the next unresolved design decision or a short resume prompt the user can reuse later +- still apply the `markdown-authoring` skill to the final response ## Repository-specific reminders - Preserve the distinction between public PowerShell cmdlets and `% nova` CLI behavior. - Keep contributor docs, command help, website docs, changelog entries, and release notes separated by audience. -- If the final design summary or GitHub issue draft is returned as Markdown or copy-ready UI output, format it according to the `markdown-authoring` skill (`.github/skills/markdown-authoring/SKILL.md`). +- Final design summaries and GitHub issue drafts are always copy-ready Markdown output; apply the `markdown-authoring` skill (`.github/skills/markdown-authoring/SKILL.md`). - Draft issue text in English unless the user explicitly asks for another language. - If the task still has unresolved choices, end the turn with the next best question or the next design decision the user should make. - If unresolved choices remain and you offer finalization anyway, explain what is settled, what is unresolved, and what each finalization option will produce. diff --git a/.github/prompts/fix-ci-failure.prompt.md b/.github/prompts/fix-ci-failure.prompt.md index e639dd5c..a7c667d3 100644 --- a/.github/prompts/fix-ci-failure.prompt.md +++ b/.github/prompts/fix-ci-failure.prompt.md @@ -1,5 +1,7 @@ # Fix NovaModuleTools CI failure +> Invoke with `@.github/prompts/fix-ci-failure.prompt.md`. Delegates to the `powershell-developer` or `test-engineer` agent depending on the failing area. + Investigate and fix a failing NovaModuleTools CI or workflow issue. ## Required inputs diff --git a/.github/prompts/implement-issue.prompt.md b/.github/prompts/implement-issue.prompt.md index b6a915c3..2c50eebc 100644 --- a/.github/prompts/implement-issue.prompt.md +++ b/.github/prompts/implement-issue.prompt.md @@ -1,5 +1,7 @@ # Implement NovaModuleTools issue +> Invoke with `@.github/prompts/implement-issue.prompt.md`. Delegates to the `powershell-developer` agent. + Implement the issue in the NovaModuleTools repository using the repository-local instructions and skills. ## Required inputs @@ -10,19 +12,27 @@ Implement the issue in the NovaModuleTools repository using the repository-local ## Required process -1. If scope, acceptance criteria, or ownership are still unclear, start with `.github/prompts/design-change.prompt.md` - and `architect.agent.md` before implementing. +1. If scope, acceptance criteria, or ownership are still unclear, start with `.github/prompts/design-change.prompt.md` and `architect.agent.md` before implementing. 2. Read `README.md`, `CONTRIBUTING.md`, `.github/copilot-instructions.md`, and `.github/pull_request_template.md`. 3. Inspect the relevant public command, matching private helper domain, tests, and docs. -4. If the issue is release-, workflow-, or coverage-related, also inspect the matching `.github/workflows/*.yml` and - `scripts/build/ci/*.ps1` files. -5. Implement the smallest maintainable fix. -6. Add or update tests. -7. Review `README.md`, `CONTRIBUTING.md`, `CHANGELOG.md`, `RELEASE_NOTE.md`, help docs, and `docs/*.html` as applicable. -8. If a commit message is requested, derive it from `$GIT_BRANCH_NAME` and the implemented change using the repository's Conventional Commit rules. -9. Run the relevant validation, then summarize what changed, why, and how it was verified. -10. If that summary is returned as Markdown or copy-ready UI output, format it according to the `markdown-authoring` - skill (`.github/skills/markdown-authoring/SKILL.md`). +4. If the issue is release-, workflow-, or coverage-related, also inspect the matching `.github/workflows/*.yml` and `scripts/build/ci/*.ps1` files. +5. Preserve the Nova build model: use `project.json` and Nova commands for build/test/package/release behavior, and do not create hand-written source `.psm1` or module `.psd1` files. +6. Inspect `project.json` `Manifest.PowerShellHostVersion` before changing PowerShell code, tests, or examples, and keep the implementation compatible with that target. +7. Implement the smallest maintainable fix. +8. Use `.github/instructions/code-quality-matrix.instructions.md` for changed source/helper scripts and `.github/instructions/testing-policy.instructions.md` for changed tests; keep new or heavily changed code short, single-purpose, low-duplication, and easy to scan unless the scope explicitly justifies otherwise. +9. Follow `.github/instructions/psscriptanalyzer.instructions.md` as the ScriptAnalyzer workflow source of truth. Prefer `./scripts/build/Invoke-ScriptAnalyzerCI.ps1` and `./run.ps1`, and use direct `Invoke-ScriptAnalyzer` only for focused local checks that reuse the repository-approved settings. +10. Do not add PSScriptAnalyzer excluded rules, suppressions, or ad hoc analyzer settings that hide findings; fix analyzer findings in the code. +11. If `run.ps1` or `Invoke-ScriptAnalyzerCI.ps1` reports ScriptAnalyzer findings, fix them before handoff instead of only reporting the failure. +12. Keep file/function ownership explicit: one externally called function per file, with private-file extras limited to related same-file top-level support helpers, keep the file name aligned to the entry function, and do not declare functions inside functions. +13. Before handoff, review every changed or generated text file and normalize it to exactly one trailing newline with no extra blank lines at the bottom. +14. Add or update the matching source-mirrored Pester file for every changed `src/**/*.ps1` file; if the behavior is genuinely cross-cutting, document which integration/guardrail test owns it and why a mirrored unit test is not practical. +15. Validate Nova-managed project tests through `Test-NovaBuild`; do not call `Invoke-Pester` directly because it can bypass Nova's build/import/StrictMode flow. +16. Add or update valid PlatyPS-compatible help under `docs/NovaModuleTools/en-US/` when public commands or public classes change. Use `New-MarkdownCommandHelp` for new help, `Update-MarkdownCommandHelp` after command-surface changes, and `Test-MarkdownCommandHelp` before handoff; do not replace command help with plain Markdown prose. +17. For every new public entry point, create its matching help file immediately in the same change. +18. Review `README.md`, `CONTRIBUTING.md`, `CHANGELOG.md`, `RELEASE_NOTE.md`, help docs, and `docs/*.html` as applicable. +19. If a commit message is requested, derive it from `$GIT_BRANCH_NAME` and the implemented change using the repository's Conventional Commit rules. +20. Run the relevant validation, then summarize what changed, why, and how it was verified. +21. If that summary is returned as Markdown or copy-ready UI output, format it according to the `markdown-authoring` skill (`.github/skills/markdown-authoring/SKILL.md`). ## Repository-specific reminders diff --git a/.github/prompts/improve-test-coverage.prompt.md b/.github/prompts/improve-test-coverage.prompt.md index 246ac6dd..3f8181c7 100644 --- a/.github/prompts/improve-test-coverage.prompt.md +++ b/.github/prompts/improve-test-coverage.prompt.md @@ -1,18 +1,25 @@ # Improve NovaModuleTools test coverage +> Invoke with `@.github/prompts/improve-test-coverage.prompt.md`. Delegates to the `test-engineer` agent. + Improve changed-code coverage in NovaModuleTools without lowering maintainability. ## Required process 1. Identify the exact uncovered file and line or branch. 2. Read the nearby production code and the most relevant existing test/support files. -3. Add the smallest test that proves the missing behavior. -4. If setup is duplicated, refactor the tests before adding more assertions. -5. Re-run the focused tests, then the repository quality loop if code changed. -6. Recheck CodeScene coverage or Code Health if that was the original failure. +3. Place new tests in the source-mirrored path under `tests/` by default: one focused `.Tests.ps1` file per covered `src/**/*.ps1` file. +4. Use an existing guardrail or integration test only when it intentionally owns genuinely cross-cutting behavior, and document that ownership in the handoff. +5. Use `.github/instructions/testing-policy.instructions.md` as the test-design source of truth; keep new or heavily changed tests focused, isolated, and easy to scan. +6. Follow `.github/instructions/psscriptanalyzer.instructions.md` when test code or test helpers change. Prefer `./scripts/build/Invoke-ScriptAnalyzerCI.ps1` for repo-standard analyzer runs, and use direct `Invoke-ScriptAnalyzer` only for focused local checks that reuse the repo-approved settings. +7. Add the smallest test that proves the missing behavior. +8. If setup is duplicated, refactor the tests before adding more assertions. +9. Re-run `Test-NovaBuild`, then the repository quality loop if code changed. Do not validate a Nova-managed project with direct `Invoke-Pester`. +10. Recheck CodeScene coverage or Code Health if that was the original failure. ## Repository-specific reminders - Many tests expect a built `dist/NovaModuleTools` module. - The CI coverage flow writes `artifacts/pester-coverage.cobertura.xml`. +- Use `Test-NovaBuild` as the project test entrypoint; direct `Invoke-Pester` can miss Nova-specific strict-mode behavior. - Do not "fix" coverage by weakening assertions or suppressing CodeScene warnings. diff --git a/.github/prompts/markdown.prompt.md b/.github/prompts/markdown.prompt.md deleted file mode 100644 index 58b92a35..00000000 --- a/.github/prompts/markdown.prompt.md +++ /dev/null @@ -1,55 +0,0 @@ -# Copy-safe Markdown wrapper - -## Purpose - -Use this prompt when the output must be copied directly as Markdown without breaking inner code blocks. - -## Required wrapper - -Wrap the entire response in this exact outer fence: - -~~~ - -~~~ - -The first line must be exactly `~~~`. The last line must be exactly `~~~`. Do not add any text before or after that wrapper. - -## Inner Markdown rules - -Inside the wrapped block: - -- write normal Markdown -- use triple backticks for code examples -- include a language tag when useful -- keep headings, bullets, and fences balanced - -## Why this wrapper is required - -Using `~~~` for the outer wrapper keeps copy-paste output stable when the Markdown itself contains triple-backtick code blocks. - -## Do not - -- do not use triple backticks as the outer wrapper -- do not leave any code fence unclosed -- do not add explanation outside the wrapped block -- do not return malformed Markdown - -## Example - -Expected output shape: - -~~~ -## Example - -Run the build with: - -```powershell -PS> Invoke-NovaBuild -``` - -Or from the CLI: - -```zsh -% nova build -``` -~~~ diff --git a/.github/prompts/prepare-release.prompt.md b/.github/prompts/prepare-release.prompt.md index 0fb297b0..8091f6cc 100644 --- a/.github/prompts/prepare-release.prompt.md +++ b/.github/prompts/prepare-release.prompt.md @@ -1,26 +1,24 @@ -# Prepare a NovaModuleTools release change +# Prepare a NovaModuleTools release + +> Invoke with `@.github/prompts/prepare-release.prompt.md`. Delegates to the `release-manager` agent. Prepare release-related changes in NovaModuleTools without publishing or tagging. ## Required process -1. Read `CHANGELOG.md`, `RELEASE_NOTE.md`, `project.json`, `README.md`, `CONTRIBUTING.md`, - `.github/pull_request_template.md`, and `.github/workflows/Publish.yml`. +1. Read `CHANGELOG.md`, `RELEASE_NOTE.md`, `project.json`, `README.md`, `CONTRIBUTING.md`, `.github/pull_request_template.md`, and `.github/workflows/Publish.yml`. 2. Inspect the touched versioning, package, publish, or release tests. 3. Confirm whether the change affects stable releases, prereleases, or both. 4. Update changelog, release notes, and contributor docs as needed. -5. Use only the official Keep a Changelog section types in `CHANGELOG.md` and `RELEASE_NOTE.md`: `Added`, `Changed`, - `Deprecated`, `Removed`, `Fixed`, and `Security`. +5. Use only the official Keep a Changelog section types in `CHANGELOG.md` and `RELEASE_NOTE.md`: `Added`, `Changed`, `Deprecated`, `Removed`, `Fixed`, and `Security`. - Do not create custom headings such as `Documentation`; place documentation-related release notes under the official type that best matches the actual impact. 6. Check whether `RELEASE_NOTE.md` needs the placeholder rule under `## [Unreleased]`: - - If there are no real public API or workflow changes, ensure `### Added` contains exactly - `No public API or workflow changes in this release. Internal maintenance only.` + - If there are no real public API or workflow changes, ensure `### Added` contains exactly `No public API or workflow changes in this release. Internal maintenance only.` - If there are real release-note entries, remove that placeholder. 7. Keep `RELEASE_NOTE.md` free of compare-link footer URLs. 8. Validate the relevant release or versioning path. 9. Summarize the result using the exact structure from `.github/pull_request_template.md`. -10. Make the summary concise, reviewer-focused, directly reusable, and compliant with the `markdown-authoring` skill - (`.github/skills/markdown-authoring/SKILL.md`) when the output is returned as Markdown. +10. Make the summary concise, reviewer-focused, directly reusable, and compliant with the `markdown-authoring` skill (`.github/skills/markdown-authoring/SKILL.md`) when the output is returned as Markdown. ## Repository-specific reminders @@ -30,5 +28,4 @@ Prepare release-related changes in NovaModuleTools without publishing or tagging - Keep unreleased changelog entries aligned with the final intended behavior, not internal iteration history. - Keep `CHANGELOG.md` exhaustive and keep `RELEASE_NOTE.md` limited to public interface, configuration, and migration changes. - Treat `.github/pull_request_template.md` as the source of truth for release-preparation summaries. -- If the summary must be pasted as one Markdown block in the UI, it should follow the `markdown-authoring` skill - (`.github/skills/markdown-authoring/SKILL.md`). +- If the summary must be pasted as one Markdown block in the UI, it should follow the `markdown-authoring` skill (`.github/skills/markdown-authoring/SKILL.md`). diff --git a/.github/prompts/review-change.prompt.md b/.github/prompts/review-change.prompt.md index 38418c31..7fa8814a 100644 --- a/.github/prompts/review-change.prompt.md +++ b/.github/prompts/review-change.prompt.md @@ -1,16 +1,20 @@ # Review a NovaModuleTools change +> Invoke with `@.github/prompts/review-change.prompt.md`. Delegates to the `reviewer` agent. + Review a NovaModuleTools change set with emphasis on correctness, maintainability, validation, and workflow safety. ## Required process 1. Start with the highest-risk public command, workflow, or release path in the diff. 2. Compare the changed files against the relevant repository instructions and skills. -3. Check whether tests, docs, and changelog updates match the change. -4. Call out the smallest set of meaningful issues first. -5. Note any missing validation or follow-up work. -6. If the review is returned as Markdown or copy-ready UI text, format it according to the `markdown-authoring` skill - (`.github/skills/markdown-authoring/SKILL.md`). +3. Check changed `src/**/*.ps1` against `.github/instructions/code-quality-matrix.instructions.md` and `tests/**/*.ps1` against `.github/instructions/testing-policy.instructions.md`. +4. Check changed PowerShell validation flow against `.github/instructions/psscriptanalyzer.instructions.md`; flag direct analyzer usage that bypasses the repository wrapper or repo-approved settings without a clear reason. +5. Check changed `docs/NovaModuleTools/en-US/*.md` against `.github/instructions/platyps-help.instructions.md` when command help was added or updated; flag files that do not follow the `New-MarkdownCommandHelp` / `Update-MarkdownCommandHelp` / `Test-MarkdownCommandHelp` workflow, miss a new public entry point's matching help file, or break the required PlatyPS section structure. +6. Check whether tests, docs, and changelog updates match the change, and flag Nova-managed validation that bypasses `Test-NovaBuild` with direct `Invoke-Pester`. +7. Call out the smallest set of meaningful issues first. +8. Note any missing validation or follow-up work. +9. If the review is returned as Markdown or copy-ready UI text, format it according to the `markdown-authoring` skill (`.github/skills/markdown-authoring/SKILL.md`). ## Repository-specific reminders diff --git a/.github/skills/building-maintainable-code/SKILL.md b/.github/skills/building-maintainable-code/SKILL.md new file mode 100644 index 00000000..5ac612ce --- /dev/null +++ b/.github/skills/building-maintainable-code/SKILL.md @@ -0,0 +1,235 @@ +--- +name: building-maintainable-code +description: Use when writing or refactoring NovaModuleTools PowerShell code, which should always follow the maintainability guidelines. +--- + +# Skill: Building maintainable code + +## When to use + +Use this skill when: + +- adding a new public command or private helper to NovaModuleTools +- refactoring a function, file, or domain folder that has grown over time +- a `code_health_review`, reviewer, or `./run.ps1` run flags maintainability problems +- you want a concrete, PowerShell-aware playbook for the guidelines + +Do not use this skill for: + +- test-specific guidance — use the `pester-testing` skill +- release/changelog work — use the `release-and-changelog` skill +- measuring or driving a single file's score across steps — use `guiding-refactoring-with-code-health` for that + +The companion instruction file is `.github/instructions/code-quality-matrix.instructions.md`. This skill is the actionable workflow that implements those rules. + +## Relevant files and commands + +- `src/public/*.ps1` and `src/private//*.ps1` +- `tests/ArchitectureGuardrails.Tests.ps1` +- `pwsh -NoLogo -NoProfile -File ./run.ps1` +- `./scripts/build/Invoke-ScriptAnalyzerCI.ps1` +- `Test-NovaBuild` + +## Guideline order and precedence + +Apply lower-level guidelines first. Unit-level structure fixes (Guidelines 1–4) usually make the component-level work (5–8) smaller and safer. + +1. Write short units of code +2. Write simple units of code +3. Write code once +4. Keep unit interfaces small +5. Separate concerns in modules +6. Couple architecture components loosely +7. Keep architecture components balanced +8. Keep your codebase small +9. Automate tests +10. Write clean code + +## Thresholds at a glance + +| Guideline | PowerShell threshold | +| --- | --- | +| 1 Short units | ≤ 15 lines per function body (excluding `function`/`}`, `param(...)`, blank lines) | +| 2 Simple units | ≤ 4 branch points per function (cyclomatic complexity ≤ 5) | +| 3 Write once | no identical block ≥ 6 functional lines repeated anywhere | +| 4 Small interfaces | ≤ 4 parameters per function (`[CmdletBinding()]` common parameters not counted) | +| 5 Separate concerns | one externally called function per file, matching the file name | +| 6 Loose coupling | infrastructure only via approved private adapters | +| 7 Balanced components | no `src/private//` absorbing unrelated responsibilities | +| 8 Small codebase | no dead/commented-out code; reuse over custom utilities | +| 9 Automate tests | source-mirrored Pester for every changed `src/**/*.ps1` | +| 10 Clean code | no bad comments, magic values, swallowed exceptions; single trailing newline | + +## Implementation playbook + +Follow these steps for any non-trivial PowerShell change. + +1. Read the changed function and surrounding file. Note where it sits in `src/public/`, `src/private//`, or `scripts/`. +2. For each new or heavily changed function, walk the checklist below in order. +3. If a step requires a refactor, make it the smallest structural step that fixes the specific finding. Do not bundle unrelated cleanup. +4. After meaningful steps, run `./run.ps1` (analyzer → build → `Test-NovaBuild`). For risk-bearing files, also run `code_health_review` from the `safeguarding-ai-generated-code` skill. +5. Before handoff, normalize every changed text file to exactly one trailing newline. + +### Step 1 — Short units (≤ 15 lines) + +Counting rule: only the body lines count. Exclude `function`, opening `{`, closing `}`, `param(...)`, attribute lines, and blank lines. + +Refactor options in PowerShell: + +- Extract the most distinct top-of-function block into a named helper. Place it as a sibling top-level function in the same private file if it belongs to the entry function. +- Replace inline preparation with `Resolve-*`, `Get-*Context`, or `Build-*Request` helpers that return the prepared object. +- Move repeated formatting into `Format-*` helpers. + +Example: + +```powershell +function Invoke-NovaRelease { + [CmdletBinding(SupportsShouldProcess)] + param( + [Parameter(Mandatory)][string]$Version, + [switch]$OverrideWarning + ) + + $context = Resolve-NovaReleaseContext -Version $Version -OverrideWarning:$OverrideWarning + Assert-NovaReleasePreconditions -Context $context + if (-not $PSCmdlet.ShouldProcess($context.Target, $context.Operation)) { + return + } + + Publish-NovaReleaseArtifacts -Context $context + Write-NovaReleaseSummary -Context $context +} +``` + +### Step 2 — Simple units (≤ 4 branch points) + +Counting rule: 1 base + each `if` / `elseif` / `switch` case body / `-and` / `-or` / ternary / `while` / `for` / `foreach` / `catch`. + +Refactor options in PowerShell: + +- Dispatch hashtable: + + ```powershell + $script:NovaCommandMap = @{ + build = { param($Args) Invoke-NovaBuild @Args } + test = { param($Args) Test-NovaBuild @Args } + package = { param($Args) New-NovaPackage @Args } + } + + function Invoke-NovaCli { + param( + [Parameter(Mandatory)][string]$Command, + [hashtable]$Args = @{} + ) + + $handler = $script:NovaCommandMap[$Command] + if ($null -eq $handler) { + Stop-NovaOperation -Message "Unknown command '$Command'." -ErrorId 'Nova.Cli.UnknownCommand' -Category InvalidArgument -TargetObject $Command + } + + & $handler $Args + } + ``` + +- Early returns instead of nested `if/else`. +- PowerShell classes when several branches behave like the same operation on different data. + +### Step 3 — Write once (no clones ≥ 6 lines) + +- If the same block lives in two files, extract it into `src/private//.ps1` and call it from both. +- For tests, extract into `tests/TestHelpers/*.ps1` or `tests/*TestSupport.ps1` rather than copying `BeforeAll` blocks. +- For data variations, parameterize. For step variations, pass a small scriptblock. + +### Step 4 — Small interfaces (≤ 4 parameters) + +If a function needs more than 4 inputs, bundle the related ones: + +```powershell +function New-NovaTestWorkflowContextOption { + [CmdletBinding()] + param( + [Parameter(Mandatory)][string]$TestResultPath, + [Parameter(Mandatory)][string]$CoverageOutputPath, + [double]$CoveragePercentTarget, + [string[]]$IncludePath + ) + + return [pscustomobject]@{ + TestResultPath = $TestResultPath + CoverageOutputPath = $CoverageOutputPath + CoveragePercentTarget = $CoveragePercentTarget + IncludePath = $IncludePath + } +} + +function Invoke-NovaTestWorkflow { + [CmdletBinding()] + param( + [Parameter(Mandatory)][pscustomobject]$WorkflowContext + ) + + # one shaped input instead of seven loose parameters +} +``` + +Use parameter sets only for genuinely different calling shapes, not to hide 8 parameters in one signature. + +### Step 5 — Separate concerns in modules + +- One externally called function per file, matching the file name. +- Helpers used only inside the file stay as sibling top-level functions in the same file. Never nest functions. +- When a private file mixes lookup, mutation, formatting, validation, and transport, split it by concern. + +### Step 6 — Loose component coupling + +- Direct `git`, `Invoke-WebRequest`, `Update-Module`, `$env:*`, file IO calls belong only inside their approved private helpers. `tests/ArchitectureGuardrails.Tests.ps1` is the authoritative boundary. +- Hide provider-specific branching behind a small adapter surface. +- Drop pass-through helpers that only forward parameters and add nothing. + +### Step 7 — Balanced components + +- If `src/private//` keeps growing because no other folder fits, propose a new domain folder rather than overloading the existing one. +- Keep workflow context objects narrow per workflow. + +### Step 8 — Small codebase + +- Delete dead code, obsolete helpers, and commented-out code in the same change. Use history as the safety net. +- Prefer existing repo helpers and well-known modules before adding a custom utility. +- Apply the same discipline to scaffold templates and Agentic Copilot resources; they multiply across every generated project. + +### Step 9 — Automate tests + +- Add or update one source-mirrored `tests//.Tests.ps1` for every changed `src/**/*.ps1` file. +- Cover happy path plus the meaningful unhappy/invalid/boundary cases that the change introduces. +- Validate with `Test-NovaBuild`. Do not call `Invoke-Pester` directly. +- For full rules, follow the `pester-testing` skill and `.github/instructions/testing-policy.instructions.md`. + +### Step 10 — Clean code + +Run this short pass before handoff on every changed source file: + +- replace magic literals with named constants or lookup tables +- remove bad comments, commented-out code, and dead branches +- shorten or rename overly long or multi-responsibility identifiers +- replace broad `catch { }` blocks with specific catches that add context, or remove the swallowing entirely +- confirm a single trailing newline on every changed text file + +## Common pitfalls + +- Counting only line numbers as the goal. The point is shape, not length; a 14-line function that does 5 things is still wrong. +- Splitting one large function into several equally tangled ones. Each extracted helper must have a clear single responsibility. +- Replacing duplication with overly clever abstractions. Prefer a small, named helper that does exactly the shared step. +- Hiding parameters in `[hashtable]$Options` without defining the shape. Use `[pscustomobject]` or a class so the contract is visible. +- Splitting files by file count rather than by concern. Two files that still mix the same concerns are no improvement over one. +- Adding adapters that only forward parameters. An adapter must add policy, validation, translation, or abstraction. +- Skipping the test mirror for a "trivial" change. Trivial changes are the ones whose regressions are hardest to spot later. +- Leaving "leftover" commented-out code "for later." Later is the next bad merge conflict. +- Treating Code Health 9.x as the goal. Aim for 10.0 on touched files in this repository. + +## Verification + +- `pwsh -NoLogo -NoProfile -File ./run.ps1` +- `./scripts/build/Invoke-ScriptAnalyzerCI.ps1` when iterating quickly on PowerShell changes +- `Test-NovaBuild` for behavior validation +- `code_health_review` and `pre_commit_code_health_safeguard` from `safeguarding-ai-generated-code` before suggesting a commit +- `code_health_review` paired with `guiding-refactoring-with-code-health` when iterating on a single unhealthy file diff --git a/.github/skills/codescene-quality/SKILL.md b/.github/skills/codescene-quality/SKILL.md index a16ab366..76c4a17f 100644 --- a/.github/skills/codescene-quality/SKILL.md +++ b/.github/skills/codescene-quality/SKILL.md @@ -17,7 +17,6 @@ Use the narrower sibling skills when the task is more specific: ## Relevant files and tools - `tests/ArchitectureGuardrails.Tests.ps1` -- `tests/*Coverage*.Tests.ps1` - `tests/*TestSupport.ps1` - `.github/actions/check-coverage/action.yml` - `scripts/build/ci/Invoke-NovaModuleToolsCI.ps1` diff --git a/.github/skills/docs-site-html/SKILL.md b/.github/skills/docs-site/SKILL.md similarity index 98% rename from .github/skills/docs-site-html/SKILL.md rename to .github/skills/docs-site/SKILL.md index 9c3b32a5..fa788890 100644 --- a/.github/skills/docs-site-html/SKILL.md +++ b/.github/skills/docs-site/SKILL.md @@ -1,5 +1,5 @@ --- -name: docs-site-html +name: docs-site description: Guidance for NovaModuleTools website documentation so docs/*.html stay accurate and clearly separated from cmdlet help and contributor docs. --- diff --git a/.github/skills/markdown-authoring/SKILL.md b/.github/skills/markdown-authoring/SKILL.md index e8709f9e..75766e92 100644 --- a/.github/skills/markdown-authoring/SKILL.md +++ b/.github/skills/markdown-authoring/SKILL.md @@ -38,6 +38,26 @@ Use this skill when producing Markdown files in the repository or Markdown outpu - For inner code examples, use triple backticks and include a language when helpful. - Never use triple backticks as the outer wrapper when the content itself may already contain fenced code blocks. +## Copy-safe wrapper example + +Expected output shape when the entire response must be a single copy-ready Markdown block: + +~~~ +## Example + +Run the build with: + +```powershell +PS> Invoke-NovaBuild +``` + +Or from the CLI: + +```zsh +% nova build +``` +~~~ + ## Common pitfalls - Breaking copy-paste output by mixing outer and inner triple-backtick fences diff --git a/.github/skills/pester-testing/SKILL.md b/.github/skills/pester-testing/SKILL.md index 97c7b229..d90009ae 100644 --- a/.github/skills/pester-testing/SKILL.md +++ b/.github/skills/pester-testing/SKILL.md @@ -13,7 +13,7 @@ Use this skill when adding tests, closing coverage gaps, fixing regressions, or - `tests/*.Tests.ps1` - `tests/*TestSupport.ps1` -- `pwsh -NoLogo -NoProfile -Command "Invoke-Pester -Path ./tests/.Tests.ps1 -Output Detailed"` +- `Test-NovaBuild` - `pwsh -NoLogo -NoProfile -File ./run.ps1` - `./scripts/build/ci/Invoke-NovaModuleToolsCI.ps1 -OutputDirectory ./artifacts` @@ -22,17 +22,27 @@ Use this skill when adding tests, closing coverage gaps, fixing regressions, or - Match existing `Describe` / `It` naming style. - Prefer support helpers for repeated setup. - Build/import the dist module when the test file expects it. +- Use `Test-NovaBuild` as the authoritative test entrypoint in Nova-managed projects. Do not validate with direct `Invoke-Pester`, because it can miss the Nova build/import/StrictMode flow. - Add coverage for both happy paths and explicit warnings/errors when behavior changed. +- For every new or changed `src/**/*.ps1` file, add or update one focused test file that mirrors the source path under `tests/`. +- Keep test files and helpers compatible with `project.json` `Manifest.PowerShellHostVersion`; if a project targets `5.1`, do not introduce PowerShell 7.x-only syntax, cmdlets, parameters, or APIs in the tests. +- Use `.github/instructions/testing-policy.instructions.md` as the test-design source of truth. Cover normal, boundary, and unhappy paths; isolate collaborators with mocks/stubs where needed; and extract setup or assertion helpers when a test stops being easy to scan. +- Keep shared setup in `tests/TestHelpers/` or `*TestSupport.ps1`; do not hide unrelated source-file coverage in broad catch-all test files. +- If a mirrored test is not practical because the behavior is genuinely cross-cutting, document the reason in the handoff and point to the owning integration or guardrail test. ## Common pitfalls - Forgetting that many tests assume `dist/NovaModuleTools` already exists - Duplicating setup instead of extending `*.TestSupport.ps1` - Exporting helper functions at the wrong time in test lifecycle +- Validating a Nova-managed project with direct `Invoke-Pester` instead of `Test-NovaBuild` - Passing tests while still degrading Code Health through duplication +- Grouping unrelated source files into one large test file when a source-mirrored layout would make ownership clearer +- Adding source files without a matching mirrored test or an explicit cross-cutting-test justification +- Ignoring boundary/unhappy-path coverage or test isolation and relying on happy-path-only verification ## Verification -- Run the touched test file(s) directly first +- Run `Test-NovaBuild` - Run `./run.ps1` before finishing code changes - If coverage is the goal, inspect `artifacts/pester-coverage.cobertura.xml` via the CI helper flow diff --git a/.github/skills/powershell-module-development/SKILL.md b/.github/skills/powershell-module-development/SKILL.md index 12b066a1..a0e84f51 100644 --- a/.github/skills/powershell-module-development/SKILL.md +++ b/.github/skills/powershell-module-development/SKILL.md @@ -25,9 +25,22 @@ Use this skill when changing public commands, private helpers, CLI routing suppo - Keep public commands thin and delegating. - Put implementation detail in the correct private domain folder. -- Preserve native PowerShell semantics and Nova naming patterns. +- Treat `project.json` as the source of truth for Nova build, package, manifest, and release metadata. +- Read `project.json` `Manifest.PowerShellHostVersion` before changing PowerShell code, tests, or examples, and keep new work compatible with that target. A `5.1` project must not receive PowerShell 7.x-only syntax, cmdlets, parameters, or APIs unless the change explicitly adds guarded compatibility handling. +- Do not create or maintain hand-written module `.psm1` or module `.psd1` files in source; Nova generates those files under `dist/NovaModuleTools/`. +- Preserve native PowerShell semantics. Keep Nova naming patterns on public commands, and give private helpers clear implementation-focused names instead of public-style `Invoke-Nova*`, `Get-Nova*`, or `Update-Nova*` naming. +- Keep one externally called function per file and match the file name to that function. In `src/private/`, additional related functions may stay only as same-file top-level support helpers called by that file's entry function; do not declare functions inside functions. +- Use `.github/instructions/code-quality-matrix.instructions.md` as the best-effort source-code maintainability guidance. Keep new or heavily changed code short, single-purpose, low-duplication, lightly nested, and split by clear responsibility; group related inputs instead of growing long parameter lists. - Reuse existing workflow-context helpers and shared adapters. - Follow the repository's PowerShell style rules: 4-space indentation, same-line opening braces, restrained blank lines, full cmdlet names, and readable operator spacing. +- Follow `.github/instructions/psscriptanalyzer.instructions.md` as the ScriptAnalyzer workflow source of truth. Prefer `./scripts/build/Invoke-ScriptAnalyzerCI.ps1` and `./run.ps1`, and use direct `Invoke-ScriptAnalyzer` only for focused local checks or deliberate analyzer-tooling work. +- Keep ScriptAnalyzer strict: do not add excluded rules, suppression attributes, or settings that hide analyzer findings. +- Keep `run.ps1`-style local checks ordered as ScriptAnalyzer first, then `Invoke-NovaBuild`, then `Test-NovaBuild`. +- If `run.ps1` or `Invoke-ScriptAnalyzerCI.ps1` reports ScriptAnalyzer findings, fix them before handoff instead of just reporting the failure. +- Before handoff, review every changed or generated text file and normalize it to exactly one trailing newline with no extra blank lines at the end. +- Add or update valid PlatyPS-compatible help under `docs/NovaModuleTools/en-US/` when public commands or public classes change. Always build and import the dist module first (`Import-Module ./dist/NovaModuleTools/NovaModuleTools.psd1 -Force`) before running `New-MarkdownCommandHelp` or `Update-MarkdownCommandHelp`, so PlatyPS writes the module name — not the command name — into `external help file` and `Module Name`. Use `Test-MarkdownCommandHelp` to validate structure before handoff instead of writing plain Markdown from scratch. +- For every new public `src/public/*.ps1` file, create the matching help file immediately in the same change. +- Add or update the source-mirrored Pester test file for every changed `src/**/*.ps1` file. ## Common pitfalls @@ -35,9 +48,20 @@ Use this skill when changing public commands, private helpers, CLI routing suppo - Mixing CLI flag spellings into PowerShell command output - Calling `git`, `Invoke-WebRequest`, `Update-Module`, or `$env:` from the wrong layer - Replacing explicit warning opt-ins with generic force semantics +- Creating a root module `.psm1` or module manifest `.psd1` by hand instead of letting Nova generate them from `project.json` +- Grouping two externally called private helpers in one file instead of splitting them into separate same-named files +- Declaring helper functions inside another function instead of keeping related private helpers as sibling top-level functions in the file +- Ignoring the source-code guidance and letting new or heavily changed functions grow long, deeply nested, duplicated, or multi-purpose without justification +- Writing plain Markdown under `docs/NovaModuleTools/en-US/` that lacks YAML metadata or the PlatyPS structure expected by `Import-MarkdownCommandHelp` +- Editing PlatyPS YAML and section structure by hand when `New-MarkdownCommandHelp` or `Update-MarkdownCommandHelp` should have regenerated it +- Generating help markdown without the built module imported, which causes `external help file` to default to the command name and produces per-command XML files instead of a single `-Help.xml` +- Adding a new public entry point without the matching help file in `docs/NovaModuleTools/en-US/` +- Bypassing the repository analyzer wrapper/settings with ad hoc `Invoke-ScriptAnalyzer`, `-EnableExit`, or broad rule-exclusion changes +- Ignoring the project's `Manifest.PowerShellHostVersion` target and introducing PowerShell 7.x-only features into a `5.1` project +- Excluding PSScriptAnalyzer rules instead of fixing the code that violates them ## Verification -- Targeted Pester file(s) for the changed behavior +- `Test-NovaBuild` for the changed behavior - `tests/ArchitectureGuardrails.Tests.ps1` implications checked - `pwsh -NoLogo -NoProfile -File ./run.ps1` diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index a53c1b3e..b944e41d 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -119,7 +119,7 @@ jobs: with: access-token: ${{ secrets.CS_ACCESS_TOKEN }} project-url: ${{ format('{0}/v2/projects/{1}', vars.CS_URL, vars.CS_PROJECT_ID) }} - coverage-files: '**/pester-coverage.cobertura.xml' + coverage-files: '**/coverage.xml' codescene-analysis: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 579a95d4..8ba952df 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,7 @@ -temp/ -justfile -testResults.xml -node_modules/ - # CI/local test artifacts +testResults.xml +coverage.xml artifacts/ dist/ run.ps1 reload.ps1 -.tmp-nova-bin/ -/*plan*.md -/summary.md -/coverage.xml -/pr-descriptions/ diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..8801c37d --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,67 @@ + + +# NovaModuleTools Copilot instructions + +## Purpose + +Index of repository-wide Copilot guidance for NovaModuleTools. This file is intentionally thin. Canonical rule text lives in `.github/instructions/` (path-scoped, auto-loaded by Copilot) and how-to guidance lives in `.github/skills/`. + +## Start here + +For non-trivial changes, read in this order: + +1. `README.md` +2. `CONTRIBUTING.md` +3. `.github/pull_request_template.md` +4. `.github/instructions/repository-conventions.instructions.md` — cross-cutting rules +5. The topic-scoped instruction file(s) that match the paths you are touching +6. The skill listed under that topic in the task map below + +For new or not-yet-scoped work, use the `architect` agent with `.github/prompts/design-change.prompt.md`. The architect flow is discussion-first: clarify the request, explore options, and only finalize a scoped solution or issue draft after the discussion is done. + +## Repository map + +- `src/public/` — public PowerShell commands; one top-level function per file, file name matches function name +- `src/private/` — domain-grouped helpers (`build/`, `cli/`, `package/`, `quality/`, `release/`, `scaffold/`, `shared/`, `update/`); one externally called helper per file +- `tests/` — Pester tests and shared test-support scripts +- `scripts/build/` — local analyzer and build helpers +- `scripts/build/ci/` — CI coverage, CodeScene, and artifact helpers +- `.github/workflows/` — GitHub Actions CI, analyzer, dependency review, publish automation +- `.github/actions/` — reusable workflow actions used by release and coverage flows +- `docs/NovaModuleTools/en-US/` — PlatyPS command help source +- `docs/*.html` — end-user GitHub Pages content +- `.github/instructions/` — canonical rules, path-scoped via `applyTo:` +- `.github/skills/` — how-to playbooks invoked through the `skill` tool +- `.github/agents/` — role definitions for specialized agents +- `.github/prompts/` — reusable task prompts (not auto-loaded; invoke explicitly with `@.github/prompts/.prompt.md`) + +## Task map + +The table below shows how to route work. Prompts are the task entry points; each prompt delegates to its agent, which uses the listed skills, which in turn enforce the listed instructions. + +| Task | Prompt | Agent | Primary skills | Primary instructions | +| ----------------------------- | ------------------------------------------ | ---------------------- | ------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------- | +| Design or scope a change | `design-change.prompt.md` | `architect` | `powershell-module-development`, `github-actions`, `release-and-changelog`, `markdown-authoring` | `repository-conventions`, `code-quality-matrix` | +| Implement an issue | `implement-issue.prompt.md` | `powershell-developer` | `powershell-module-development`, `pester-testing`, `building-maintainable-code`, `codescene-quality`, `safeguarding-ai-generated-code` | `repository-conventions`, `code-quality-matrix`, `psscriptanalyzer`, `powershell-coding-standards`, `platyps-help` | +| Review a change | `review-change.prompt.md` | `reviewer` | `codescene-quality`, `safeguarding-ai-generated-code`, `building-maintainable-code`, `docs-site`, `markdown-authoring`, `pester-testing`, `release-and-changelog`, `github-actions` | All `.github/instructions/*.instructions.md` | +| Improve test coverage | `improve-test-coverage.prompt.md` | `test-engineer` | `pester-testing`, `building-maintainable-code`, `codescene-quality`, `github-actions`, `guiding-refactoring-with-code-health`, `safeguarding-ai-generated-code` | `testing-policy`, `psscriptanalyzer` | +| Prepare a release | `prepare-release.prompt.md` | `release-manager` | `release-and-changelog`, `markdown-authoring` | `release-policy`, `repository-conventions` | +| Fix a CI failure | `fix-ci-failure.prompt.md` | `powershell-developer` (or `test-engineer`) | `github-actions`, `pester-testing` | `testing-policy`, `psscriptanalyzer`, `repository-conventions` | +| Update website docs | (no dedicated prompt — invoke agent) | `docs-site` | `docs-site`, `markdown-authoring` | `documentation-separation` | + +## Notation + +- Skills referenced as `/skill-name` in agent files map 1-to-1 to the `name:` field in `.github/skills//SKILL.md`. The runtime invokes them through the `skill` tool with the bare name. +- Prompts are referenced by path. Custom prompts are not auto-loaded by the Copilot CLI; invoke them explicitly with `@.github/prompts/.prompt.md`. +- Instructions auto-load when their `applyTo:` glob matches a file in the change set. + +## Related guidance + +- Cross-cutting rules: `.github/instructions/repository-conventions.instructions.md` +- Source code maintainability: `.github/instructions/code-quality-matrix.instructions.md` + `building-maintainable-code` skill +- Testing: `.github/instructions/testing-policy.instructions.md` + `pester-testing` skill +- PSScriptAnalyzer workflow: `.github/instructions/psscriptanalyzer.instructions.md` +- PowerShell coding standards: `.github/instructions/powershell-coding-standards.instructions.md` +- PlatyPS help generation: `.github/instructions/platyps-help.instructions.md` +- Release flow: `.github/instructions/release-policy.instructions.md` + `release-and-changelog` skill +- Documentation separation: `.github/instructions/documentation-separation.instructions.md` + `docs-site` skill diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e67d2f2..113f5691 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,29 +1,52 @@ # Changelog -All notable changes to this project will be documented in this file and **PREVIEW / UNRELEASED** changes will be included in the next **stable** release! - +All notable changes to this project will be documented in this file and **UNRELEASED** changes will be included in the next **stable** release! The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] - ### Added +- `Initialize-NovaModule` and `% nova init` now offer an optional interactive **Agentic Copilot** starter package for both the minimal and example scaffold flows. + - The new prompt appears after the Git question, defaults to `No`, and adds one shared Nova-maintained starter tree when enabled. + - Example scaffolds now merge the existing example README with the Agentic starter README instead of flattening the example guide into the generic starter file. + - The starter tree is now generated from a filtered mirror of Nova's own agentic `.github/` files, with a dedicated sync script and drift test so future scaffolds and `dist` stay aligned with the maintained source guidance. + - The generated architect/design prompt now requires final design packages and issue/work item drafts to be returned as copy-ready Markdown using the project Markdown authoring guidance. + - The generated guidance now explicitly keeps Agentic Copilot projects on the Nova build model, treats `.psm1` / `.psd1` files as generated `dist` output, requires project test validation to run through `Test-NovaBuild` instead of direct `Invoke-Pester`, requires PlatyPS-compatible help for public commands/classes, expects one focused source-mirrored test file for every new or changed `src/**/*.ps1` file, tells agents to honor `project.json` `Manifest.PowerShellHostVersion` when writing PowerShell code and tests, and now asks for a short project name so placeholders such as `Invoke-*` can be replaced in the generated starter files. + - The generated guidance now keeps local `run.ps1` quality loops ordered as ScriptAnalyzer, `Invoke-NovaBuild`, then `Test-NovaBuild`, and tells agents to fix ScriptAnalyzer findings reported by `run.ps1` instead of excluding, suppressing, or handing them off unresolved. + - The generated guidance now points agents to the documented PSScriptAnalyzer workflow, using `./scripts/build/Invoke-ScriptAnalyzerCI.ps1` and `./run.ps1` as the normal entrypoints and reserving direct `Invoke-ScriptAnalyzer` for focused local checks that reuse repo-approved settings. + - The generated PowerShell guidance now requires public files to keep one top-level function per file, requires private files to keep at most one externally called function per file, keeps any extra private functions limited to related same-file top-level support helpers whose file names match the owning function, forbids nested function declarations inside PowerShell functions, limits the `Invoke-*` / `Get-*` / `Update-*` naming guidance to public commands, and tells private helpers to avoid those public-style names in favor of clear implementation-focused helper names. + - The generated guidance now expresses PowerShell source/helper-script maintainability rules through `code-quality-matrix.instructions.md` and keeps test-specific design guidance in the testing instruction/skill files. + - The generated guidance now requires `docs//en-US/*.md` to stay valid PlatyPS help with YAML metadata and build-compatible structure, tells agents to use the documented `New-MarkdownCommandHelp` / `Update-MarkdownCommandHelp` / `Test-MarkdownCommandHelp` workflow instead of replacing command help with plain Markdown that breaks `nova build`, and requires a matching help file for every new public entry point in the same change. + - The generated PowerShell guidance now requires agents to review every changed or generated text file before handoff and normalize the file ending to exactly one trailing newline with no extra blank lines at the bottom. + - The starter now also ships a generated `scripts/build/Test-TextFileFormatting.ps1` helper and, when project tests are enabled, a `tests/TextFileFormatting.Tests.ps1` guardrail so trailing blank-line violations fail `Test-NovaBuild` instead of relying on instructions alone. + - When Git is enabled during either scaffold flow, Nova now creates or updates a default `.gitignore` in the generated project root and appends only the missing Nova-managed artifact entries instead of overwriting existing ignore rules. + - `Initialize-NovaModule` and `% nova init` now check for newer NovaModuleTools releases before the first interactive scaffold question and reuse the same non-blocking update warning behavior already used by build. +- `Test-NovaBuild` and `% nova test` now enforce `Pester.CodeCoverage.CoveragePercentTarget` from `project.json` when `CodeCoverage.Enabled` is `true`, failing the test run when measured coverage drops below the configured target. + ### Changed +- The architect/design flow now surfaces settled vs unresolved design items before finalization, offers explicit choices for full finalization vs design-package-only handoff, clarifies how to use design notes versus the paste-ready GitHub issue draft, and requires finalization output to follow the project Markdown authoring guidance. +- `ProjectTemplate.json` and the packaged example `project.json` now include Nova's default Pester `CodeCoverage` block with `Enabled=false`, shared `src/` coverage paths, JaCoCo output, and a `90` percent target so new projects can opt into coverage without hand-authoring the configuration. +- `Invoke-NovaModuleToolsCI.ps1` now delegates the full test run to a single `Test-NovaBuild` call; the previous second `Invoke-Pester` pass and post-run Cobertura source-path remapping step have been removed. +- CodeScene coverage upload now uses JaCoCo format instead of Cobertura and uploads both `line-coverage` and `branch-coverage` metrics in a single CI run; the helper script auto-discovers `artifacts/coverage.xml` instead of scanning for `*.cobertura.xml` files. +- `Tests.yml` coverage-gate step now matches `**/coverage.xml` instead of `**/pester-coverage.cobertura.xml` to align with the new JaCoCo artifact path. -- The architect/design flow now surfaces settled vs unresolved design items before finalization, offers explicit choices for full finalization vs design-package-only handoff, and clarifies how to use design notes versus the paste-ready GitHub issue draft. ### Deprecated + ### Removed + ### Fixed +- `Test-NovaBuild` and `% nova test` no longer emit `Remove-Item -Recurse` progress bars during the Pester run; `$global:ProgressPreference` is saved and restored around the test execution so CI logs stay clean. +- Code coverage in `Test-NovaBuild` now runs against the built `dist//.psm1` file instead of source files, so measured coverage percentages and line numbers align with the deployed module. + ### Security -## [2.4.0] - 2026-05-10 +## [2.4.0] - 2026-05-10 ### Added - - Added a repository-local agentic coding setup under `.github/` for Copilot/AI-assisted repository work. - Includes repository instructions, focused agent role definitions, repo-specific skills, and reusable task prompts. - Aligns the agent guidance with Nova's existing PowerShell, Pester, CodeScene, GitHub Actions, and release conventions. @@ -46,10 +69,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), - `CHANGELOG.md` remains the exhaustive release history. - `RELEASE_NOTE.md` now captures only public cmdlet, CLI, configuration, and migration-impacting changes, including backfilled summaries for the existing released versions in `CHANGELOG.md`. - `Tests.yml` now validates both files, and `Publish.yml` now finalizes both files during stable release preparation. - - The public release-notes page now renders `RELEASE_NOTE.md` instead of the full changelog feed. + - The public release-notes page now renders `RELEASE_NOTE.md` instead of the full changelog feed. -### Changed +### Changed - `Package.Latest` now supports policy values: `"never"`, `"stable"`, and `"always"`. - `"stable"` keeps the floating `latest` alias pinned to stable package versions. - Legacy boolean values still work for now and map to `"always"` / `"never"` for backward compatibility. @@ -57,70 +80,63 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), - `CHANGELOG.md` remains the exhaustive release history. - `RELEASE_NOTE.md` now captures only public cmdlet, CLI, configuration, and migration-impacting changes, including backfilled summaries for the existing released versions in `CHANGELOG.md`. - `Tests.yml` now validates both files, and `Publish.yml` now finalizes both files during stable release preparation. - - The public release-notes page now renders `RELEASE_NOTE.md` instead of the full changelog feed. + - The public release-notes page now renders `RELEASE_NOTE.md` instead of the full changelog feed. -### Deprecated +### Deprecated - Boolean `Package.Latest` values are deprecated and will be removed in the next major version. -### Removed +### Removed - Removed the repository's Codecov integration in favor of CodeScene-only coverage reporting. - `Tests.yml` no longer uploads CI coverage results to Codecov. - The standalone `codecov.yml` configuration has been removed from the repository. -### Fixed +### Fixed - Clarified contributor release/test guidance in `README.md` so repository and CI test runs still install `Pester 5.7.1` explicitly, while the published `NovaModuleTools` manifest continues to declare that dependency for installed workflows. -## [2.3.1] - 2026-05-08 +## [2.3.1] - 2026-05-08 ### Fixed - - Fixed `nova bump` and `Update-NovaModuleVersion` so nested project folders now reuse parent Git repository history for bump inference instead of silently falling back to `Patch`. - Fixed `nova bump` and `Update-NovaModuleVersion` so non-git bump flows now stop with a clear override-warning requirement instead of silently presenting `Patch | Commits: 0` as if it were an inferred result. -## [2.3.0] - 2026-05-06 +## [2.3.0] - 2026-05-06 ### Changed - - Make prerelease self-update confirmation default to `No`. - `Update-NovaModuleTool`, `Update-NovaModuleTools`, and `% nova update` now require an explicit `Y` before a prerelease self-update continues, so pressing Enter cancels the update instead of accepting it. - Render bold text in white across the hosted HTML documentation. - Emphasized `` and `` text now stands out more clearly when scanning docs pages. -### Fixed +### Fixed - Restore Nova-managed project test runs in CI/CD after `2.2.0` dropped the implicit `Pester` dependency. - CI/CD environments no longer need custom logic to install `Pester` themselves before running project tests. - Published `NovaModuleTools` manifests once again pull in `Pester 5.7.1` implicitly so existing CI/CD test flows keep working without extra installation logic. - - `Test-NovaBuild` fails with a clear dependency error when `Pester` is not installed. + - `Test-NovaBuild` fails with a clear dependency error when `Pester` is not installed. -## [2.2.0] - 2026-05-06 [YANKED] +## [2.2.0] - 2026-05-06 [YANKED] This release was yanked because it removed the implicit `Pester` dependency, before Nova's CI/CD test flow installed `Pester` explicitly. Projects using `NovaModuleTools 2.2.0` could fail to run tests in CI/CD unless maintainers added their own `Pester` installation step. The regression was fixed in `2.3.0`. - ### Changed - - Align `Invoke-NovaRelease` PowerShell parameters with `Publish-NovaModule` and `% nova release`. - PowerShell release scripts can now pass `-Local`, `-Repository`, `-ModuleDirectoryPath`, and `-ApiKey` directly. - - Deprecated `-PublishOption` usage should be changed in existing CI/CD automation as soon as possible. - -Keep stable `Update-NovaModuleVersion` / `% nova bump` releases on the SemVer major-zero development line. - When the current stable version is `0.y.z` and commit history implies a breaking change, Nova now plans the next minor version instead of auto-jumping to `1.0.0`. - + - Deprecated `-PublishOption` usage should be changed in existing CI/CD automation as soon as possible. Keep stable `Update-NovaModuleVersion` / `% nova bump` releases on the SemVer major-zero development line. - When the current stable version is `0.y.z` and commit history implies a breaking change, Nova now plans the next minor version instead of auto-jumping to `1.0.0`. - Stable `0.y.z` bump results now print one warning about manually setting `1.0.0` once the software is stable, while breaking-change bumps still report the detected `Major` label. - Make `Update-NovaModuleVersion -Preview` / `% nova bump --preview` enter the preview track deterministically from stable versions. - Stable versions now always become the next patch preview, for example `0.2.0 -> 0.2.1-preview`, instead of reusing semantic history inference for the semantic core. - Existing prerelease versions still keep their current semantic core and continue the prerelease sequence. - Running the bump without `-Preview` still finalizes or advances prerelease versions by Nova's normal semantic rules. -### Deprecated +### Deprecated - `Invoke-NovaRelease` parameters that differ from `Publish-NovaModule` and `% nova release` such as `-Local`, `-Repository`, `-ModuleDirectoryPath`, and `-ApiKey` are now the primary PowerShell release parameters, while `-PublishOption` is deprecated and will be removed in the next major version. -### Fixed +### Fixed - Fix the release workflow so repository publish steps run against the freshly built `dist/` module in each CI PowerShell process. - `Publish.yml` now imports the built module before `Invoke-NovaRelease` and `Publish-NovaModule`, which avoids missing private helper failures when the runner also has an older installed `NovaModuleTools` version available for autoload. - Fix the command-line test workflow wording in `docs/core-workflows.html` so the CLI preview flag is shown as @@ -144,10 +160,9 @@ Keep stable `Update-NovaModuleVersion` / `% nova bump` releases on the SemVer ma - Invalid module names now show the validation message inline instead of failing after the full questionnaire. - Standard and example scaffold flows now share the same retry-first validation behavior through the common prompt path. -## [2.1.0] - 2026-04-29 +## [2.1.0] - 2026-04-29 ### Added - - Add `Install-NovaCli` and a packaged `nova` launcher so macOS and Linux users can install and run `nova` directly from zsh or bash. - `nova` now remains the launcher-facing CLI surface, while `Invoke-NovaCli` stays the explicit PowerShell cmdlet entrypoint instead of exporting a `nova` PowerShell alias. - Add optional `Preamble` support in `project.json` to write module-level setup lines at the top of generated `.psm1` @@ -203,14 +218,14 @@ Keep stable `Update-NovaModuleVersion` / `% nova bump` releases on the SemVer ma - The `nova` launcher now supports `--continuous-integration` / `-i` on `nova build`, `nova bump`, `nova publish`, and `nova release` while keeping `nova version -i` dedicated to the installed-version view. - Build re-activates the freshly built module after the build succeeds, bump re-activates it before the version update starts, and publish/release restore the built module again after publish completes. - Repository publish no longer forces verbose `Publish-PSResource` output unless verbose logging was explicitly requested. - - CI bump now reuses the already activated built-module command when the current session is already running from - `dist/`, so publish-then-bump prerelease automation can continue in the same session without losing private helper bindings. + - CI bump now reuses the already activated built-module command when the current session is already running from + `dist/`, so publish-then-bump prerelease automation can continue in the same session without losing private helper bindings. - `Update-NovaModuleVersion -ContinuousIntegration` now also falls back to a patch bump when `HEAD` already matches the latest tag, so release automation can prepare the next prerelease version without requiring an extra commit. - Keep standalone `nova bump` output stable by formatting version-update results in the CLI layer instead of relying on PowerShell's default object rendering. - `nova bump --what-if` and `% run.ps1` now surface a predictable summary for previous version, new version, label, and commit count. -### Changed +### Changed - Change the project to a Nova command model, replacing the previous mixed MT/Nova workflow. - All public commands are now Nova commands, and the `nova` CLI / `Invoke-NovaCli` command surface is the primary entry point for all operations. - Change `nova` help to a dedicated CLI-native help system with both short and long command help forms. @@ -226,13 +241,13 @@ Keep stable `Update-NovaModuleVersion` / `% nova bump` releases on the SemVer ma - Change `CopyResourcesToModuleRoot` to the canonical project setting name while keeping the default value `false`. - Change `Publish-NovaModule -Local` and `% nova publish --local` so a successful local publish also reloads the published module from the local install path into the active PowerShell session. -### Removed +### Removed - **BREAKING CHANGE**: Remove the legacy `MT` commands and MT-branded command documentation in favor of the Nova command model. - All public commands are now Nova commands, and the `nova` CLI / `Invoke-NovaCli` command surface is the primary entry point for all operations. -### Fixed +### Fixed - Fix unsupported `nova` help invocations so they now return Nova's structured CLI validation error instead of a PowerShell parameter-binding failure. - Keep manifest/package helper edge cases aligned with their intended behavior. - Manifest settings resolution now accepts ordered dictionary metadata shapes in addition to plain hashtables. @@ -241,10 +256,9 @@ Keep stable `Update-NovaModuleVersion` / `% nova bump` releases on the SemVer ma - Fix semantic-release PSGallery publishing on fresh CI runners by bootstrapping the PSResourceGet repository store before `Publish-PSResource` runs. -## [1.9.1] - 2026-04-10 +## [1.9.1] - 2026-04-10 ### Added - - Nova command model and CLI entrypoint: - New root command: `nova` - New public commands: `Get-NovaProjectInfo`, `Invoke-NovaBuild`, `Invoke-NovaCli`, `Invoke-NovaRelease`, `Initialize-NovaModule`, `Publish-NovaModule`, `Test-NovaBuild`, `Update-NovaModuleVersion` @@ -253,122 +267,113 @@ Keep stable `Update-NovaModuleVersion` / `% nova bump` releases on the SemVer ma - New GitHub workflow: Dependency Review (`.github/workflows/dependency-review.yml`). - New GitHub workflow: PowerShell code quality (`.github/workflows/powershell.yml`). -### Changed +### Changed - Updated test workflow triggers in `.github/workflows/Tests.yml` to improve branch/PR coverage. - Updated README module naming references to `NovaModuleTools`. - Source alignment updates to match installed `NovaModuleTools` v`1.8.0` behavior for compatibility. -### Deprecated +### Deprecated - `MT` commands and MT-branded command documentation in favor of the Nova command model. -### Fixed +### Fixed - Resource lookup compatibility in `Get-ResourceFilePath` for source/dist execution contexts. -## [1.8.0] - 2026-04-08 +## [1.8.0] - 2026-04-08 ### Added - - Project settings: - `BuildRecursiveFolders` (default `true`): recursive discovery for `src/classes`, `src/private` and `tests`. - `SetSourcePath` (default `true`): include `# Source: ` before each concatenated source file in generated `dist//.psm1`. - `FailOnDuplicateFunctionNames` (default `true`): fail build when duplicate top-level function names exist in generated `dist//.psm1`. - - Missing values for these settings are now treated as `true`. - - The rebranded `NovaModuleTools` module now uses its own module `GUID`. + - Missing values for these settings are now treated as `true`. + - The rebranded `NovaModuleTools` module now uses its own module `GUID`. -### Changed +### Changed - Build determinism: files are processed in a deterministic order by relative path (case-insensitive), and load order is always `classes → public → private`. -## [1.3.0] - 2025-09-23 +## [1.3.0] - 2025-09-23 - Added support for `ps1xml1` format data. Place it in resources folder with `Name.format.ps1xml` to be automatically added as format file and imported in module manifest -## [1.2.0] - 2025-09-17 +## [1.2.0] - 2025-09-17 ### Added - - Added support for classes directory inside src - Initialize-NovaModule generates classes directory during fresh project - `classes` directory should include `.ps1` files which contain enums and classes -### Fixed +### Fixed - Version upgrade using update-mtmoduleversion now support build tags. Improvements to semver versioning. -## [1.1.3] - 2025-09-14 +## [1.1.3] - 2025-09-14 ### Added - - Now supports preview tag in Update-NovaModuleVersion - Now supports semver naming in both project.json and modulemanifest - Module build supports `preview` or `prerelease` tag - Preview version looks like `1.2.3-preview` -## [1.1.0] - 2025-08-28 +## [1.1.0] - 2025-08-28 ## Added - - Now Module manifest includes `AliasesToExport`. This helps loading aliases without explicitly importing modules to session. - thanks to @djs-zmtc for suggesting the feature -## [1.0.0] - 2025-03-11 +## [1.0.0] - 2025-03-11 ### Added - - New optional project setting `CopyResourcesToModuleRoot`. Setting to true places resource files in the root directory of module. Default is `false` to provide backward compatibility. Thanks to @[BrooksV](https://github.com/BrooksV) -### Fixed +### Fixed - **BREAKING CHANGE**: Typo corrected: ProjecUri to ProjectUri. Existing projects require manual update. -## [0.0.9] - 2024-07-17 +## [0.0.9] - 2024-07-17 ### Fixed - - Fixed #7, Invoke build should not through for empty tags -## [0.0.7] - 2024-07-17 +## [0.0.7] - 2024-07-17 ### Added - - Now "Manifest" section of project JSON supports all Manifest parameters, use exact name of parameter (from New-ModuleManifest) as key in JSON -## Fixed +## Fixed - Fixed the example project README so it no longer suggests that `example/` includes a `run.ps1` helper script; it now points users to building `NovaModuleTools` from the repository root or using the Gallery workflow. - Corrected typo in ProjectUri from `ProjecUri` to correct spelling. -## [0.0.6] - 2024-07-08 +## [0.0.6] - 2024-07-08 ### Added - - `Test-NovaBuild` now supports including and excluding tags -### Fixed +### Fixed - Code cleanup -## [0.0.5] - 2024-07-05 +## [0.0.5] - 2024-07-05 ### Added - - More verbose info during MTModule creation -### Fixed +### Fixed - Issue #2 : Git initialization implemented - Issue #1 : Doesn't create empty `tests` folder when user chooses `no` to tests -## [0.0.4] - 2024-06-25 +## [0.0.4] - 2024-06-25 ### Added - - First release to `psgallery` - All basic functionality of Module is ready + [Unreleased]: https://github.com/stiwicourage/NovaModuleTools/compare/2.4.0...HEAD [2.4.0]: https://github.com/stiwicourage/NovaModuleTools/compare/2.3.1...2.4.0 [2.3.1]: https://github.com/stiwicourage/NovaModuleTools/compare/2.3.0...2.3.1 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bb86abca..b89c7774 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -45,7 +45,7 @@ when your Copilot session starts from the NovaModuleTools repository root. When you are shaping a new change, start with `architect.agent.md` and `design-change.prompt.md` so the first phase is a design conversation: analysis, clarifying questions, and solution options before any final scoped proposal or GitHub issue draft is produced. Proposed out-of-scope boundaries should be confirmed by the user before they become part of the final scope. When unresolved design questions still remain, architect should summarize what is settled vs unresolved before asking whether to finalize, and it should support either a full issue-ready handoff or a resumable design-package-only handoff. Use `implement-issue.prompt.md` after the change is already scoped. -Pull requests against `main` and `develop` also run a CodeScene coverage-gate check when CI has produced the Cobertura coverage artifact, so PRs can be blocked when changed code falls below the configured coverage threshold. +Pull requests against `main` and `develop` also run a CodeScene coverage-gate check when CI has produced the JaCoCo coverage artifact, so PRs can be blocked when changed code falls below the configured coverage threshold. **Before opening a pull request, please run the local quality flow from the repository root:** @@ -64,12 +64,12 @@ Import-Module $distModuleDir -Force Test-NovaBuild ``` -If you are working on the CodeScene integration, the CI coverage helper writes the Cobertura artifact that the CodeScene upload step consumes: +If you are working on the CodeScene integration, the CI coverage helper writes the JaCoCo artifact that the CodeScene upload step consumes: - generate coverage with `./scripts/build/ci/Invoke-NovaModuleToolsCI.ps1` - pull requests then download that uploaded artifact and run the CodeScene coverage-gate check through `.github/actions/check-coverage` - then upload/trigger with `./scripts/build/ci/Invoke-CodeSceneAnalysis.ps1 -UploadCoverage -TriggerAnalysis` -- the upload helper auto-discovers a single `artifacts/*.cobertura.xml` file unless you pass `-CoveragePath` +- the upload helper auto-discovers `artifacts/coverage.xml` unless you pass `-CoveragePath` - if upload succeeds but `-TriggerAnalysis` fails with a project-owner OAuth error, re-authorize the repository in CodeScene for the project owner; that failure is separate from `CS_ACCESS_TOKEN` Please also make sure your contribution includes the right kind of follow-up work: @@ -80,6 +80,8 @@ Please also make sure your contribution includes the right kind of follow-up wor - update `CHANGELOG.md` when the change is relevant to users, maintainers, or future contributors - update `RELEASE_NOTE.md` when the change affects public cmdlet usage, CLI usage, configuration semantics, or migration expectations - keep `src/resources/example/` useful if your change affects the real-world project layout or workflow +- run `./scripts/build/Sync-AgenticCopilotScaffold.ps1` when `.github/agents/`, `.github/instructions/`, + `.github/skills/`, `.github/prompts/`, or `.github/copilot-instructions.md` changes should flow into future Agentic Copilot scaffolds Documentation ownership is intentionally split: diff --git a/README.md b/README.md index b0370f41..63aa509a 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ![WorkFlow Status][WorkFlowStatus] [![Keep a Changelog][changelog-badge]][changelog] -NovaModuleTools is an enterprise-focused evolution of ModuleTools for structured PowerShell module development, repository automation, and maintainable Nova workflows. +NovaModuleTools is an enterprise-focused build tool for Agentic Copilot PowerShell module development, repository automation, and maintainable Nova workflows. This README is the single developer-documentation entry point for the repository. @@ -55,8 +55,9 @@ Repository-local Copilot/AI guidance now lives under: - `.github/instructions/` - path-specific Copilot instructions stored as `*.instructions.md` - `.github/agents/` - focused agent roles for architecture, implementation, testing, release, and review work - `.github/skills/` - repo-specific Copilot skills stored as `/SKILL.md` -- `.github/prompts/` - reusable task prompts such as design framing, issue implementation, CI fixes, coverage work, and release prep; prompt files are referenced explicitly in chat, not auto-loaded like instructions or skills +- `.github/prompts/` - reusable task prompts such as design framing, issue implementation, CI fixes, coverage work, and release prep; prompt files are referenced explicitly in chat as `@.github/prompts/.prompt.md` rather than auto-loaded like instructions or skills - `CHANGELOG.md` and `RELEASE_NOTE.md` - exhaustive release history plus interface-focused release summaries +- `AGENTS.md` - generated mirror of `.github/copilot-instructions.md` for tooling that reads `AGENTS.md` (Codex, Cursor); regenerate with `./scripts/build/Sync-AgenticCopilotScaffold.ps1` after touching the Copilot guidance The files under `.github/agents/` are valid Copilot custom agent profiles and should be available from `/agent` when Copilot is started from the NovaModuleTools repository root. @@ -261,6 +262,8 @@ Notes: - `Test-NovaBuild` validates the built module output, not just loose source files - it writes NUnit XML to `artifacts/TestResults.xml` - it respects `BuildRecursiveFolders` when discovering tests +- if `project.json` sets `Pester.CodeCoverage.CoveragePercentTarget`, `Test-NovaBuild` fails when the measured coverage percentage is lower than that configured target +- new template and packaged example `project.json` files already include an opt-in `Pester.CodeCoverage` block with `Enabled=false`, JaCoCo output in `artifacts/coverage.xml`, and a `90` percent target so projects can enable coverage when they are ready - contributor and CI environments should still install `Pester 5.7.1` explicitly before running `Test-NovaBuild` - the published `NovaModuleTools` manifest also declares `Pester 5.7.1`, so installed end-user workflows can still resolve that dependency automatically @@ -411,11 +414,9 @@ PS> ./scripts/build/ci/Invoke-NovaModuleToolsCI.ps1 That flow builds the module, runs ScriptAnalyzer, executes one coverage-enabled Pester run using the same Nova test workflow configuration, and emits CI-friendly reports such as: - `artifacts/novamoduletools-nunit.xml` -- `artifacts/pester-junit.xml` -- `artifacts/pester-coverage.cobertura.xml` -- `artifacts/coverage-low.txt` +- `artifacts/coverage.xml` -The `Tests.yml` workflow reuses that Cobertura artifact for the pull-request CodeScene coverage-gate check and for the develop/manual CodeScene upload-and-analysis flow. The CodeScene pull-request gate downloads the uploaded artifact and runs `cs-coverage check`, while the develop/manual CodeScene step uploads coverage through `scripts/build/ci/Invoke-CodeSceneAnalysis.ps1` before it triggers a follow-up analysis run. If coverage upload succeeds but the trigger fails with an OAuth/project-owner error, fix the repository authorization in CodeScene for the project owner. That trigger-side repository authorization is separate from `CS_ACCESS_TOKEN`. +The `Tests.yml` workflow reuses that JaCoCo artifact for the pull-request CodeScene coverage-gate check and for the develop/manual CodeScene upload-and-analysis flow. The CodeScene pull-request gate downloads the uploaded artifact and runs `cs-coverage check`, while the develop/manual CodeScene step uploads coverage through `scripts/build/ci/Invoke-CodeSceneAnalysis.ps1` before it triggers a follow-up analysis run. If coverage upload succeeds but the trigger fails with an OAuth/project-owner error, fix the repository authorization in CodeScene for the project owner. That trigger-side repository authorization is separate from `CS_ACCESS_TOKEN`. ### Recommended local quality loop @@ -504,8 +505,14 @@ Packaged resources that ship with the module, including: - schemas - the standalone `nova` launcher - the packaged example project under `src/resources/example/` +- the Agentic Copilot starter package under `src/resources/agentic-copilot/` -The example project is both a shipped resource and a maintained working reference. +The example project is both a shipped resource and a maintained working reference. The Agentic Copilot starter package is generated from Nova's repository-local agentic guidance, including Nova build/test/package expectations, `project.json` `Manifest.PowerShellHostVersion` compatibility guidance, generated `dist` module files, command-help ownership, source-mirrored test guidance, Test-NovaBuild-only project test guidance that forbids direct `Invoke-Pester` so agent validation matches Nova's build/import/StrictMode flow, guidance that ScriptAnalyzer findings reported by `run.ps1` must be fixed before handoff, explicit PSScriptAnalyzer workflow guidance for `./scripts/build/Invoke-ScriptAnalyzerCI.ps1`, `./run.ps1`, and focused `Invoke-ScriptAnalyzer` usage, explicit public/private PowerShell file ownership rules, best-effort source/helper-script maintainability guidance plus separate test-design guidance that live in Agentic Copilot files, a generated +`scripts/build/Test-TextFileFormatting.ps1` helper and matching `tests/TextFileFormatting.Tests.ps1` guardrail when Pester is enabled so extra blank lines at EOF fail the project test flow, and explicit valid-PlatyPS help guidance for +`docs//en-US/*.md` that uses the documented `New-MarkdownCommandHelp` / `Update-MarkdownCommandHelp` / +`Test-MarkdownCommandHelp` workflow and requires a matching help file for every new public entry point in the same change, and a strict file-ending rule for changed or generated text files. When the init flow adds that starter package, it also asks for a short project name so scaffolded guidance can replace placeholders such as `Invoke-*`. Run +`./scripts/build/Sync-AgenticCopilotScaffold.ps1` after changing `.github/agents/`, `.github/instructions/`, +`.github/skills/`, `.github/prompts/`, or `.github/copilot-instructions.md` so future scaffolds and `dist` stay in sync. ### Test layout @@ -563,8 +570,8 @@ At a minimum, contributor changes are expected to keep these workflows healthy: Repository scripts under `scripts/build/ci/` provide local parity for CI-oriented reporting. When CodeScene coverage upload is needed, run -`scripts/build/ci/Invoke-CodeSceneAnalysis.ps1 -UploadCoverage -TriggerAnalysis`. That script auto-discovers a single `*.cobertura.xml` file under `artifacts/` unless you pass `-CoveragePath` -explicitly. The repository `Tests.yml` workflow now also downloads that same Cobertura artifact during pull requests and runs the CodeScene coverage-gate check before merge. If `-TriggerAnalysis` fails after a successful upload, review the CodeScene response body: repository OAuth problems for the project owner must be fixed in CodeScene itself and are not solved by rotating `CS_ACCESS_TOKEN` alone. +`scripts/build/ci/Invoke-CodeSceneAnalysis.ps1 -UploadCoverage -TriggerAnalysis`. That script auto-discovers `artifacts/coverage.xml` unless you pass `-CoveragePath` +explicitly. The repository `Tests.yml` workflow also downloads that same JaCoCo artifact during pull requests and runs the CodeScene coverage-gate check before merge. If `-TriggerAnalysis` fails after a successful upload, review the CodeScene response body: repository OAuth problems for the project owner must be fixed in CodeScene itself and are not solved by rotating `CS_ACCESS_TOKEN` alone. ### Build and test automation @@ -577,7 +584,7 @@ The normal repository workflow is: When you test local publish behavior during development, remember that `Publish-NovaModule -Local` reloads the published module from the local install directory into the current PowerShell session. Re-import `dist/` if your next step depends on the built-but-unpublished output instead. -The CI helper flow also produces JUnit and Cobertura artifacts for external systems, including the coverage file that the CodeScene workflow gate and upload steps consume. +The CI helper flow also produces a JaCoCo coverage artifact that the CodeScene workflow gate and upload steps consume. ### Release automation diff --git a/RELEASE_NOTE.md b/RELEASE_NOTE.md index ab9f8e4b..7d24b580 100644 --- a/RELEASE_NOTE.md +++ b/RELEASE_NOTE.md @@ -1,62 +1,65 @@ # Release notes This file summarizes public cmdlet, CLI, configuration, and migration changes for NovaModuleTools. -`CHANGELOG.md` remains the exhaustive record of all changes in each release. **PREVIEW / UNRELEASED** -changes will be included in the next **stable** release! +`CHANGELOG.md` remains the exhaustive record of all changes in each release. **UNRELEASED** changes will be included in the next **stable** release! ## [Unreleased] - ### Added +- `Initialize-NovaModule` and `% nova init` now offer an optional **Agentic Copilot** starter package in both the minimal and example interactive scaffold flows. + - The starter package follows a filtered mirror of Nova's maintained agentic guidance so newly scaffolded projects receive a broader Nova-style agentic baseline without Nova-specific surfaces. +- `Test-NovaBuild` and `% nova test` now enforce `Pester.CodeCoverage.CoveragePercentTarget` from `project.json` when `CodeCoverage.Enabled` is `true`, so coverage gates work without extra external tooling. ### Changed +- New projects now start with Nova's default Pester `CodeCoverage` block in both the minimal template and packaged example `project.json`, with `Enabled=false`, shared `src/` coverage paths, JaCoCo output, and a `90` percent target ready to opt into. + ### Deprecated + ### Removed + ### Fixed +- Code coverage in `Test-NovaBuild` now runs against the built `dist/` module instead of source files, so reported coverage percentages and line numbers match the deployed module. +- `Test-NovaBuild` and `% nova test` no longer emit `Remove-Item` progress bars during the Pester run. + ### Security -## [2.4.0] - 2026-05-10 +## [2.4.0] - 2026-05-10 ### Changed - - `Package.Latest` in `project.json` now accepts the policy values `"never"`, `"stable"`, and `"always"`. - Use `"stable"` when the floating `latest` package alias should follow stable package versions only. ### Deprecated - - Boolean `Package.Latest` values are deprecated and still map to `"always"` / `"never"` for now. - Migrate to the string-based policy values before the next major version. -## [2.3.1] - 2026-05-08 +## [2.3.1] - 2026-05-08 ### Fixed - - `nova bump` and `Update-NovaModuleVersion` now reuse parent Git repository history when a project lives in a nested folder, instead of falling back to `Patch`. - Non-git bump flows now stop with a clear override-warning requirement instead of presenting `Patch | Commits: 0` as if the value had been inferred automatically. -## [2.3.0] - 2026-05-06 +## [2.3.0] - 2026-05-06 ### Changed - - Prerelease self-update confirmation now defaults to `No`. - `Update-NovaModuleTool`, `Update-NovaModuleTools`, and `% nova update` now require an explicit `Y` before a prerelease self-update continues. -### Fixed +### Fixed - Nova-managed CI/CD test flows now pull in `Pester 5.7.1` again through the published `NovaModuleTools` manifest. - Existing CI/CD workflows no longer need their own `Pester` installation step just to keep project tests working. - `Test-NovaBuild` now fails with a clear dependency error when `Pester` is missing. + ## [2.2.0] - 2026-05-06 [YANKED] +This release was yanked because it removed the implicit `Pester` dependency before Nova's CI/CD test flow installed `Pester` explicitly. Projects using `NovaModuleTools 2.2.0` could fail to run tests in CI/CD unless maintainers added their own `Pester` installation step. The regression was fixed in `2.3.0`. -This release was yanked because it removed the implicit `Pester` dependency before Nova's CI/CD test flow installed -`Pester` explicitly. Projects using `NovaModuleTools 2.2.0` could fail to run tests in CI/CD unless maintainers added their own `Pester` installation step. The regression was fixed in `2.3.0`. ### Changed - - `Invoke-NovaRelease` now aligns with `Publish-NovaModule` and `% nova release` by accepting `-Local`, `-Repository`, `-ModuleDirectoryPath`, and `-ApiKey` directly. - Existing automation should move away from deprecated `-PublishOption` usage. @@ -65,13 +68,11 @@ This release was yanked because it removed the implicit `Pester` dependency befo - `Update-NovaModuleVersion -Preview` and `% nova bump --preview` now enter the preview track deterministically from stable versions. - Stable versions always become the next patch preview, for example `0.2.0 -> 0.2.1-preview`. -## [2.1.0] - 2026-04-29 +## [2.1.0] - 2026-04-29 ### Added - - `Install-NovaCli` and a packaged `nova` launcher now let macOS and Linux users install and run `nova` directly from zsh or bash. -- Mutating Nova commands now support native `-WhatIf` / `-Confirm`, and the routed CLI now supports `--what-if`, - `--confirm`, and `--verbose` without dropping into PowerShell's `Suspend` prompt. +- Mutating Nova commands now support native `-WhatIf` / `-Confirm`, and the routed CLI now supports `--what-if`, `--confirm`, and `--verbose` without dropping into PowerShell's `Suspend` prompt. - Self-update support is now available through `Update-NovaModuleTool`, `Update-NovaModuleTools`, and `nova update`, with matching notification preference commands and CLI routes. - `nova version --installed` / `-i` now shows the installed NovaModuleTools version beside the current project version. - `Test-NovaBuild -Build` and `nova test --build` can now rebuild the project before running Pester. @@ -79,121 +80,108 @@ This release was yanked because it removed the implicit `Pester` dependency befo - `New-NovaModulePackage` / `nova package` and `Deploy-NovaPackage` / `nova deploy` now add generic package build and raw upload workflows. - `-SkipTests` / `--skip-tests` and `-ContinuousIntegration` / `--continuous-integration` now support CI-oriented package, publish, release, and versioning flows. -### Changed +### Changed - Nova now uses the Nova command model and a CLI-native help system as the primary workflow surface. - `Publish-NovaModule -Local` and `nova publish --local` now reload the published module from the local install path into the current PowerShell session. -### Removed +### Removed - **BREAKING CHANGE**: Legacy `MT` commands were removed in favor of the Nova command model. - **BREAKING CHANGE**: `New-NovaModule` was renamed to `Initialize-NovaModule` without compatibility aliases. -### Fixed +### Fixed - Invalid `nova help` invocations now return Nova's structured CLI validation errors. - Empty or unsupported `project.json` configuration now fails fast with clearer validation messages. -## [1.9.1] - 2026-04-10 +## [1.9.1] - 2026-04-10 ### Added - - Introduced the Nova command model and the `nova` root command together with the core public NovaModuleTools cmdlets. -### Deprecated +### Deprecated - `MT` commands and MT-branded documentation were deprecated in favor of the Nova command model. -### Fixed +### Fixed - Resource lookup now behaves correctly when commands run from source or built `dist/` module contexts. -## [1.8.0] - 2026-04-08 +## [1.8.0] - 2026-04-08 ### Added - - Added `BuildRecursiveFolders`, `SetSourcePath`, and `FailOnDuplicateFunctionNames` project settings for more explicit build control. -### Changed +### Changed - Build output is now generated in a deterministic file order, with `classes -> public -> private` load sequencing. -## [1.3.0] - 2025-09-23 +## [1.3.0] - 2025-09-23 ### Added - - Resource format files named `Name.format.ps1xml` are now imported automatically through the generated module manifest. -## [1.2.0] - 2025-09-17 +## [1.2.0] - 2025-09-17 ### Added - - Added `src/classes` support, and `Initialize-NovaModule` now creates the classes directory for new projects. -### Fixed +### Fixed - Version updates now support build tags and improved semantic-version handling. -## [1.1.3] - 2025-09-14 +## [1.1.3] - 2025-09-14 ### Added - - `Update-NovaModuleVersion` now supports preview tags, and project/build metadata now follows semver naming more consistently. - Preview builds can now use `preview` or `prerelease` labels, for example `1.2.3-preview`. -## [1.1.0] - 2025-08-28 +## [1.1.0] - 2025-08-28 ### Added - - Generated module manifests now include `AliasesToExport`, so exported aliases load without extra manual import work. -## [1.0.0] - 2025-03-11 +## [1.0.0] - 2025-03-11 ### Added - - Added the optional `CopyResourcesToModuleRoot` project setting so resource files can be copied to the module root when needed. -### Fixed +### Fixed - **BREAKING CHANGE**: `ProjecUri` was corrected to `ProjectUri`, and existing projects need a manual setting update. -## [0.0.9] - 2024-07-17 +## [0.0.9] - 2024-07-17 ### Fixed - - `Invoke-NovaBuild` no longer fails when tag filters are empty. -## [0.0.7] - 2024-07-17 +## [0.0.7] - 2024-07-17 ### Added - - The `Manifest` section in `project.json` now supports the full set of `New-ModuleManifest` parameters. -### Fixed +### Fixed - The example project README now points users to the supported repository-root and Gallery workflows. - Corrected the `ProjectUri` setting name in project metadata guidance. -## [0.0.6] - 2024-07-08 +## [0.0.6] - 2024-07-08 ### Added - - `Test-NovaBuild` now supports include/exclude tag filtering. -## [0.0.5] - 2024-07-05 +## [0.0.5] - 2024-07-05 ### Added - - Module initialization now prints more progress detail while a project is being created. -### Fixed +### Fixed - New projects now initialize Git automatically when requested. - Skipping tests during project creation no longer leaves behind an empty `tests` folder. -## [0.0.4] - 2024-06-25 +## [0.0.4] - 2024-06-25 ### Added - - First PowerShell Gallery release of NovaModuleTools with the initial module workflow support. - diff --git a/docs/NovaModuleTools/en-US/Deploy-NovaPackage.md b/docs/NovaModuleTools/en-US/Deploy-NovaPackage.md index 666d837a..aaa4dc8e 100644 --- a/docs/NovaModuleTools/en-US/Deploy-NovaPackage.md +++ b/docs/NovaModuleTools/en-US/Deploy-NovaPackage.md @@ -27,27 +27,20 @@ PS> Deploy-NovaPackage [[-PackagePath] ] [[-PackageType] ] [ `Deploy-NovaPackage` uploads existing package artifacts that were generated by `New-NovaModulePackage`. -When `-PackagePath` is omitted, the command resolves artifacts from the configured package output directory. It uses the -current package model, which means it can upload `.nupkg`, `.zip`, or both, depending on `Package.Types` and the files -present in the output directory. +When `-PackagePath` is omitted, the command resolves artifacts from the configured package output directory. It uses the current package model, which means it can upload `.nupkg`, `.zip`, or both, depending on `Package.Types` and the files present in the output directory. If you customize `Package.PackageFileName`, you can keep upload discovery aligned by updating `Package.FileNamePattern` as well. When `Package.AddVersionToFileName` is `true`, Nova appends `.` from `project.json` to the configured package file base name before it discovers or uploads matching artifacts. -When multiple matching artifacts exist for a selected package type, `Deploy-NovaPackage` uploads all of them. That -includes versioned and `latest` variants such as `NovaModuleTools.2.0.0-preview6.nupkg` and +When multiple matching artifacts exist for a selected package type, `Deploy-NovaPackage` uploads all of them. That includes versioned and `latest` variants such as `NovaModuleTools.2.0.0-preview6.nupkg` and `NovaModuleTools.latest.nupkg`. -Use `-Url` when CI/CD or an ad-hoc script should upload directly to a raw endpoint. Use `-Repository` when you want the -command to resolve the upload target from `Package.Repositories` in `project.json`. Generic package-level defaults such -as `Package.RepositoryUrl`, `Package.UploadPath`, `Package.Headers`, and `Package.Auth` are also supported. +Use `-Url` when CI/CD or an ad-hoc script should upload directly to a raw endpoint. Use `-Repository` when you want the command to resolve the upload target from `Package.Repositories` in `project.json`. Generic package-level defaults such as `Package.RepositoryUrl`, `Package.UploadPath`, `Package.Headers`, and `Package.Auth` are also supported. -This command is intentionally separate from `Publish-NovaModule`. `Deploy-NovaPackage` performs raw HTTP artifact -uploads, while `Publish-NovaModule` remains focused on PowerShell repository publishing. +This command is intentionally separate from `Publish-NovaModule`. `Deploy-NovaPackage` performs raw HTTP artifact uploads, while `Publish-NovaModule` remains focused on PowerShell repository publishing. -When you run `Deploy-NovaPackage -Confirm`, PowerShell uses its native confirmation prompt against the full resolved -upload set instead of prompting once per artifact. +When you run `Deploy-NovaPackage -Confirm`, PowerShell uses its native confirmation prompt against the full resolved upload set instead of prompting once per artifact. ## EXAMPLES @@ -57,8 +50,7 @@ upload set instead of prompting once per artifact. PS> Deploy-NovaPackage -Repository LocalNexus ``` -Resolves the current project's package artifacts from the configured package output directory and uploads them to the -raw repository named `LocalNexus` from `Package.Repositories`. +Resolves the current project's package artifacts from the configured package output directory and uploads them to the raw repository named `LocalNexus` from `Package.Repositories`. ### EXAMPLE 2 @@ -74,8 +66,7 @@ Previews the raw package upload flow and the resolved destination URLs without u PS> Deploy-NovaPackage -Url 'https://packages.example/raw/' -Token $env:NOVA_PACKAGE_TOKEN ``` -Uploads the matching package artifacts directly to the provided raw endpoint and sends the resolved authentication -header. +Uploads the matching package artifacts directly to the provided raw endpoint and sends the resolved authentication header. ### EXAMPLE 4 @@ -113,8 +104,7 @@ Uses PowerShell's native confirmation prompt for the full resolved upload set be ### -PackagePath -Optional explicit package file path list. When omitted, the command resolves matching artifacts from the configured -package output directory. +Optional explicit package file path list. When omitted, the command resolves matching artifacts from the configured package output directory. ```yaml Type: System.String[] @@ -362,8 +352,7 @@ You can't pipe objects to this cmdlet. ### System.Management.Automation.PSCustomObject -Returns one upload result object per uploaded package artifact, including the package type, source package path, -repository name, upload URL, and HTTP status code. +Returns one upload result object per uploaded package artifact, including the package type, source package path, repository name, upload URL, and HTTP status code. ## NOTES diff --git a/docs/NovaModuleTools/en-US/Get-NovaProjectInfo.md b/docs/NovaModuleTools/en-US/Get-NovaProjectInfo.md index 4c6cb2fc..9f6beab3 100644 --- a/docs/NovaModuleTools/en-US/Get-NovaProjectInfo.md +++ b/docs/NovaModuleTools/en-US/Get-NovaProjectInfo.md @@ -37,8 +37,7 @@ PS> Get-NovaProjectInfo [-Installed] [] ## DESCRIPTION -`Get-NovaProjectInfo` reads the `project.json` file in a NovaModuleTools project and returns a project information -object with: +`Get-NovaProjectInfo` reads the `project.json` file in a NovaModuleTools project and returns a project information object with: - the raw project metadata - normalized project paths such as `src/`, `tests/`, `docs/`, and `dist/` @@ -49,8 +48,7 @@ Use this command from scripts, tests, or troubleshooting when you want one objec When you use `-Version`, the command returns only the project version string instead of the full project object. -When you use `-Installed`, the command returns the installed `NovaModuleTools` module name and version string instead of -project metadata. +When you use `-Installed`, the command returns the installed `NovaModuleTools` module name and version string instead of project metadata. ## EXAMPLES diff --git a/docs/NovaModuleTools/en-US/Get-NovaUpdateNotificationPreference.md b/docs/NovaModuleTools/en-US/Get-NovaUpdateNotificationPreference.md index a10376fa..16309cc1 100644 --- a/docs/NovaModuleTools/en-US/Get-NovaUpdateNotificationPreference.md +++ b/docs/NovaModuleTools/en-US/Get-NovaUpdateNotificationPreference.md @@ -28,8 +28,7 @@ PS> Get-NovaUpdateNotificationPreference [] `Get-NovaUpdateNotificationPreference` returns the current user preference that controls whether `Update-NovaModuleTool` / `Update-NovaModuleTools` may select prerelease versions of `NovaModuleTools`. -The same stored preference is also used by `Update-NovaModuleTool` (alias: `Update-NovaModuleTools`) when it decides -whether a prerelease self-update is eligible. +The same stored preference is also used by `Update-NovaModuleTool` (alias: `Update-NovaModuleTools`) when it decides whether a prerelease self-update is eligible. Stable self-updates remain available and do not require prerelease eligibility. @@ -41,8 +40,7 @@ Stable self-updates remain available and do not require prerelease eligibility. PS> Get-NovaUpdateNotificationPreference ``` -Shows whether prerelease self-updates are currently enabled, whether stable self-updates remain available, and where the -preference is stored. +Shows whether prerelease self-updates are currently enabled, whether stable self-updates remain available, and where the preference is stored. ### EXAMPLE 2 @@ -75,14 +73,11 @@ Returns the prerelease self-update state, the always-available stable-update sta ## NOTES -Use `Set-NovaUpdateNotificationPreference -DisablePrereleaseNotifications` to stop prerelease self-updates from being -eligible. +Use `Set-NovaUpdateNotificationPreference -DisablePrereleaseNotifications` to stop prerelease self-updates from being eligible. Use `Set-NovaUpdateNotificationPreference -EnablePrereleaseNotifications` to allow prerelease self-updates again. -When prerelease notifications are enabled again, `Update-NovaModuleTool` / `Update-NovaModuleTools` may again select a -prerelease target. Prerelease self-updates still require explicit confirmation before the update proceeds, and that -confirmation defaults to `No` so pressing Enter cancels the update. +When prerelease notifications are enabled again, `Update-NovaModuleTool` / `Update-NovaModuleTools` may again select a prerelease target. Prerelease self-updates still require explicit confirmation before the update proceeds, and that confirmation defaults to `No` so pressing Enter cancels the update. ## RELATED LINKS diff --git a/docs/NovaModuleTools/en-US/Initialize-NovaModule.md b/docs/NovaModuleTools/en-US/Initialize-NovaModule.md index bde707ed..cfd64b5f 100644 --- a/docs/NovaModuleTools/en-US/Initialize-NovaModule.md +++ b/docs/NovaModuleTools/en-US/Initialize-NovaModule.md @@ -27,26 +27,23 @@ PS> Initialize-NovaModule [-Path ] [-Example] [-WhatIf] [-Confirm] [*`; for NovaModuleTools the short name is `Nova`, but it could also have been +`NMT`. The Agentic package follows Nova's maintained agentic guidance through a filtered starter mirror, including Nova build/test/package expectations, `project.json` +`Manifest.PowerShellHostVersion` compatibility guidance, strict ScriptAnalyzer guidance without excluded rules, generated `dist` module files, command-help ownership, source-mirrored test guidance, guidance that ScriptAnalyzer findings reported by +`run.ps1` must be fixed before handoff, explicit PSScriptAnalyzer workflow guidance for `./scripts/build/Invoke-ScriptAnalyzerCI.ps1`, `./run.ps1`, and focused `Invoke-ScriptAnalyzer` usage, explicit public/private PowerShell file ownership rules, best-effort source/helper-script maintainability guidance plus separate test-design guidance delivered through Agentic Copilot files, a generated `scripts/build/Test-TextFileFormatting.ps1` helper plus `tests/TextFileFormatting.Tests.ps1` when project tests are enabled so trailing blank-line violations fail the project test flow, explicit valid-PlatyPS help guidance for `docs//en-US/*.md` that uses `New-MarkdownCommandHelp`, `Update-MarkdownCommandHelp`, and `Test-MarkdownCommandHelp`, and a strict file-ending rule for changed or generated text files. For the standard scaffold, the interactive flow also includes optional basic Pester support. -Use this command when you want to start a new module in the NovaModuleTools structure without hand-creating the project -layout. +If you enter an invalid answer during the interactive flow, `Initialize-NovaModule` reports the validation problem immediately and retries that prompt before it continues to the next question. -Use `-Path` when you want to create the project under a specific base directory. Positional path syntax is no longer -supported. +Use this command when you want to start a new module in the NovaModuleTools structure without hand-creating the project layout. -Use `-Example` when you want the scaffold to start from the packaged example project instead of the minimal default -layout. The example flow keeps the example source, resource, and test files, skips the Pester enable/disable question, -and applies the interactive metadata values to the copied `project.json`. The standard and example flows share the same -inline validation and retry behavior for interactive answers. +Use `-Path` when you want to create the project under a specific base directory. Positional path syntax is no longer supported. -This command supports `-WhatIf` and `-Confirm` through PowerShell `SupportsShouldProcess`. Use `-WhatIf` to preview the -scaffold target after the interactive answers have been collected, without creating folders, writing `project.json`, or -initializing Git. +Use `-Example` when you want the scaffold to start from the packaged example project instead of the minimal default layout. The example flow keeps the example source, resource, and test files, skips the Pester enable/disable question, and applies the interactive metadata values to the copied `project.json`, including the same disabled-by-default `CodeCoverage` block that the standard scaffold uses. The standard and example flows share the same upfront Nova update warning, inline validation and retry behavior for interactive answers, and optional Agentic Copilot setup prompt after the Git question. When Git is enabled in either flow, Nova also ensures the generated project root has the default `.gitignore` entries for local and CI artifacts without overwriting any existing `.gitignore` content. When you answer +`Yes`, Nova asks for the short project name, adds the same starter package to either scaffold style, and merges the example README instead of replacing it with the generic starter README outright. + +This command supports `-WhatIf` and `-Confirm` through PowerShell `SupportsShouldProcess`. Use `-WhatIf` to preview the scaffold target after the interactive answers have been collected, without creating folders, writing `project.json`, or initializing Git. ## EXAMPLES @@ -56,8 +53,7 @@ initializing Git. PS> Initialize-NovaModule -Path ~/Work ``` -Starts the interactive scaffold flow and creates the new module under `~/Work`. -Invalid interactive answers are retried immediately before the command continues. +Starts the interactive scaffold flow and creates the new module under `~/Work`. Invalid interactive answers are retried immediately before the command continues. ### EXAMPLE 2 @@ -73,9 +69,7 @@ Shows what would be created without writing the scaffold. PS> Initialize-NovaModule -Example -Path ~/Work ``` -Creates a new project under `~/Work` from the packaged example template and applies the answers from the interactive -prompt flow to the copied `project.json`. -Invalid interactive answers are retried immediately here as well. +Creates a new project under `~/Work` from the packaged example template and applies the answers from the interactive prompt flow to the copied `project.json`. Invalid interactive answers are retried immediately here as well. ### EXAMPLE 4 @@ -131,9 +125,7 @@ HelpMessage: '' ### CommonParameters -This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, --InformationAction, -InformationVariable, -OutBuffer, -OutVariable, -PipelineVariable, --ProgressAction, -Verbose, -WarningAction, -WarningVariable, -WhatIf, and -Confirm. For more information, see +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction, -WarningVariable, -WhatIf, and -Confirm. For more information, see [about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS @@ -150,9 +142,9 @@ This cmdlet does not emit an output object. ## NOTES -Generated projects start with NovaModuleTools defaults for recursive discovery, source markers, and duplicate-function -validation. The packaged example scaffold keeps its bundled example source and tests, while still updating prompt-driven -metadata such as project name, description, version, author, and PowerShell host version. +Generated projects start with NovaModuleTools defaults for recursive discovery, source markers, duplicate-function validation, an opt-in Pester `CodeCoverage` block (`Enabled=false`, shared `src/` paths, JaCoCo output in `artifacts/coverage.xml`, and a `90` percent target), and—when Git is enabled—a default `.gitignore` for common local and CI artifact paths. The packaged example scaffold keeps its bundled example source and tests, while still updating prompt-driven metadata such as project name, description, version, author, and PowerShell host version. The optional Agentic Copilot starter package adds repository-local Copilot workflow files under the project root and `.github/` that tell agents to keep build/test/package workflows on Nova, treat `project.json` `Manifest.PowerShellHostVersion` as the PowerShell compatibility target, run ScriptAnalyzer before build/test through the repo-standard `Invoke-ScriptAnalyzerCI.ps1` / +`run.ps1` workflow, fix any ScriptAnalyzer findings before handoff, run project tests through `Test-NovaBuild` instead of direct `Invoke-Pester`, leave `.psm1` / `.psd1` files to generated +`dist` output, generate and validate command help with the Microsoft.PowerShell.PlatyPS cmdlets instead of hand-written Markdown structure, require a matching help file for every new public entry point in the same change, mirror new tests to source files, and add a text-file-formatting guardrail helper plus a Pester guardrail test when project tests are enabled. `Initialize-NovaModule` uses `SupportsShouldProcess`, so `Get-Help Initialize-NovaModule -Full` surfaces native `-WhatIf` and diff --git a/docs/NovaModuleTools/en-US/Install-NovaCli.md b/docs/NovaModuleTools/en-US/Install-NovaCli.md index c41cb45a..3a0bb0bf 100644 --- a/docs/NovaModuleTools/en-US/Install-NovaCli.md +++ b/docs/NovaModuleTools/en-US/Install-NovaCli.md @@ -25,8 +25,7 @@ PS> Install-NovaCli [[-DestinationDirectory] ] [-Force] [-WhatIf] [-Conf ## DESCRIPTION -`Install-NovaCli` copies the bundled `nova` launcher from the installed NovaModuleTools module into a user-facing -command directory. +`Install-NovaCli` copies the bundled `nova` launcher from the installed NovaModuleTools module into a user-facing command directory. By default, the launcher is installed to `~/.local/bin/nova` on macOS and Linux. If that directory is not on your `PATH`, the command warns so you can update your shell profile. @@ -165,14 +164,12 @@ You can't pipe objects to this cmdlet. ### PSCustomObject -Returns the installed command name, destination directory, installed path, and whether the destination directory is -currently on `PATH`. +Returns the installed command name, destination directory, installed path, and whether the destination directory is currently on `PATH`. ## NOTES After running `Install-NovaCli`, add the destination directory to your shell `PATH` if needed. - ## RELATED LINKS - `Publish-NovaModule` diff --git a/docs/NovaModuleTools/en-US/Invoke-NovaBuild.md b/docs/NovaModuleTools/en-US/Invoke-NovaBuild.md index ed620b73..4a20df7a 100644 --- a/docs/NovaModuleTools/en-US/Invoke-NovaBuild.md +++ b/docs/NovaModuleTools/en-US/Invoke-NovaBuild.md @@ -27,15 +27,12 @@ PS> Invoke-NovaBuild [-ContinuousIntegration] [-OverrideWarning] [-WhatIf] [-Con `Invoke-NovaBuild` runs the NovaModuleTools build pipeline for the current project. -This command supports `-WhatIf` and `-Confirm` through PowerShell `SupportsShouldProcess`. Use `-WhatIf` to preview the -build target without clearing `dist/` or generating new build output. +This command supports `-WhatIf` and `-Confirm` through PowerShell `SupportsShouldProcess`. Use `-WhatIf` to preview the build target without clearing `dist/` or generating new build output. -Use `-ContinuousIntegration` when the same PowerShell session needs to keep using the freshly built `dist/` module after -the build completes. In CI/self-hosting flows, that re-activates the built module before the command returns. +Use `-ContinuousIntegration` when the same PowerShell session needs to keep using the freshly built `dist/` module after the build completes. In CI/self-hosting flows, that re-activates the built module before the command returns. Use `-OverrideWarning` only when you intentionally want to continue a build even though a file under `src/public` -contains zero or multiple top-level functions. The normal build guard stops there because those layouts can leak helper -functions into the public API surface. +contains zero or multiple top-level functions. The normal build guard stops there because those layouts can leak helper functions into the public API surface. The command: @@ -49,17 +46,13 @@ The command: To update the installed `NovaModuleTools` module itself, use `Update-NovaModuleTool` (alias: `Update-NovaModuleTools`). -Use `Set-NovaUpdateNotificationPreference` or `Get-NovaUpdateNotificationPreference` when you want to control whether -prerelease self-updates are eligible. +Use `Set-NovaUpdateNotificationPreference` or `Get-NovaUpdateNotificationPreference` when you want to control whether prerelease self-updates are eligible. -If `Invoke-NovaBuild` detects that a newer `NovaModuleTools` release or prerelease is available after the build, the -warning includes the recommended update command together with the release notes link from the installed module -manifest. +If `Invoke-NovaBuild` detects that a newer `NovaModuleTools` release or prerelease is available after the build, the warning includes the recommended update command together with the release notes link from the installed module manifest. If `SetSourcePath` is enabled, the generated `.psm1` includes `# Source:` markers before each source block. -If `Preamble` is configured, those lines are written at the very top of the generated `.psm1` before the rest of the -module content. +If `Preamble` is configured, those lines are written at the very top of the generated `.psm1` before the rest of the module content. ## EXAMPLES @@ -101,8 +94,7 @@ Prompts before the build workflow runs when confirmation is required. PS> Invoke-NovaBuild -ContinuousIntegration ``` -Builds the project and then re-imports the freshly built `dist//.psd1` so later CI steps in -the same session use the updated build output. +Builds the project and then re-imports the freshly built `dist//.psd1` so later CI steps in the same session use the updated build output. ## PARAMETERS @@ -110,8 +102,7 @@ the same session use the updated build output. Re-import the freshly built module from `dist/` before the command returns. -Use this in CI/self-hosting flows when later commands in the same PowerShell session must run against the freshly built -module state instead of the previously loaded copy. +Use this in CI/self-hosting flows when later commands in the same PowerShell session must run against the freshly built module state instead of the previously loaded copy. ```yaml Type: System.Management.Automation.SwitchParameter @@ -132,8 +123,7 @@ HelpMessage: '' ### -OverrideWarning -Continue the build when the `src/public` layout guard reports that a public file does not contain exactly one top-level -function. +Continue the build when the `src/public` layout guard reports that a public file does not contain exactly one top-level function. Use this only when you intentionally accept the warning and still want the current build to proceed. @@ -156,9 +146,7 @@ HelpMessage: '' ### CommonParameters -This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, --InformationAction, -InformationVariable, -OutBuffer, -OutVariable, -PipelineVariable, --ProgressAction, -Verbose, -WarningAction, -WarningVariable, -WhatIf, and -Confirm. For more information, see +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction, -WarningVariable, -WhatIf, and -Confirm. For more information, see [about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS @@ -180,11 +168,9 @@ Run this command from the project root so `project.json`, `src/`, `docs/ Invoke-NovaRelease -Repository [[-ModuleDirectoryPath] ] [[ 4. Build again to include the updated version 5. Publish through the resolved local-directory or repository publish action -Use `-Repository` and `-ApiKey` for repository publishing, or `-Local` / `-ModuleDirectoryPath` for local release -publishing. This keeps the release command aligned with the direct PowerShell parameter style used by +Use `-Repository` and `-ApiKey` for repository publishing, or `-Local` / `-ModuleDirectoryPath` for local release publishing. This keeps the release command aligned with the direct PowerShell parameter style used by `Publish-NovaModule`. Use `-SkipTests` when tests already ran earlier in your pipeline and you only want to skip the pre-release @@ -48,19 +47,15 @@ Use `-SkipTests` when tests already ran earlier in your pipeline and you only wa The command changes location to `-Path` for execution and always restores the previous location. -Use `-ContinuousIntegration` when the same CI/self-hosting session should re-activate the built `dist/` module at the -release workflow boundaries where session state matters. Nova forwards that CI intent into the nested build and version -bump steps and restores the built module again after publish. +Use `-ContinuousIntegration` when the same CI/self-hosting session should re-activate the built `dist/` module at the release workflow boundaries where session state matters. Nova forwards that CI intent into the nested build and version bump steps and restores the built module again after publish. Use `-OverrideWarning` only when you intentionally want the nested release builds to continue even though a file under `src/public` contains zero or multiple top-level functions. When local release mode is selected, the resolved local publish target is previewed consistently with -`Publish-NovaModule -Local`. Unlike `Publish-NovaModule -Local`, `Invoke-NovaRelease` does not import the published -module into the current session after publishing; it returns the version result for automation-friendly release flows. +`Publish-NovaModule -Local`. Unlike `Publish-NovaModule -Local`, `Invoke-NovaRelease` does not import the published module into the current session after publishing; it returns the version result for automation-friendly release flows. -This command supports `-WhatIf` and `-Confirm` through PowerShell `SupportsShouldProcess`. Use `-WhatIf` to preview the -entire release workflow and resolved publish target without building, testing, versioning, or publishing. +This command supports `-WhatIf` and `-Confirm` through PowerShell `SupportsShouldProcess`. Use `-WhatIf` to preview the entire release workflow and resolved publish target without building, testing, versioning, or publishing. ## EXAMPLES @@ -70,8 +65,7 @@ entire release workflow and resolved publish target without building, testing, v PS> Invoke-NovaRelease -Local ``` -Runs a local release flow and publishes to the local module path. -The command returns the version result and does not reload the published module into the current session. +Runs a local release flow and publishes to the local module path. The command returns the version result and does not reload the published module into the current session. ### EXAMPLE 2 @@ -111,15 +105,13 @@ Runs the release workflow without re-running the pre-release `Test-NovaBuild` st PS> Invoke-NovaRelease -Repository PSGallery -ApiKey $env:PSGALLERY_API -ContinuousIntegration ``` -Runs the release workflow and re-activates the built `dist//.psd1` at the CI-sensitive -workflow boundaries so later commands in the same session keep using the built module state. +Runs the release workflow and re-activates the built `dist//.psd1` at the CI-sensitive workflow boundaries so later commands in the same session keep using the built module state. ## PARAMETERS ### -Local -Use the local release target. When `-ModuleDirectoryPath` is omitted, Nova resolves the normal local module install -path for the current platform. +Use the local release target. When `-ModuleDirectoryPath` is omitted, Nova resolves the normal local module install path for the current platform. ```yaml Type: System.Management.Automation.SwitchParameter @@ -237,8 +229,7 @@ HelpMessage: '' ### -SkipTests -Skip the pre-release `Test-NovaBuild` step. `Invoke-NovaBuild` still runs before the version bump and again after the -bump so the published output reflects the updated version. +Skip the pre-release `Test-NovaBuild` step. `Invoke-NovaBuild` still runs before the version bump and again after the bump so the published output reflects the updated version. This option is mainly intended for CI/CD flows where tests already passed earlier in the pipeline. @@ -284,8 +275,7 @@ HelpMessage: '' ### -OverrideWarning -Continue the nested release builds even if the `src/public` layout guard reports that a public file does not contain -exactly one top-level function. +Continue the nested release builds even if the `src/public` layout guard reports that a public file does not contain exactly one top-level function. ```yaml Type: System.Management.Automation.SwitchParameter @@ -318,8 +308,7 @@ You can't pipe objects to this cmdlet. ### PSCustomObject -Returns the version update result from `Update-NovaModuleVersion`, including the previous version, new version, -selected release label, and commit count. +Returns the version update result from `Update-NovaModuleVersion`, including the previous version, new version, selected release label, and commit count. ## NOTES @@ -327,12 +316,9 @@ If build or tests fail, version bump and publish are not completed. When `-SkipTests` is used, only the pre-release `Test-NovaBuild` step is skipped. Both build steps still run. -Use `Publish-NovaModule -Local` when you want a successful local publish to reload the published module into the active -PowerShell session. +Use `Publish-NovaModule -Local` when you want a successful local publish to reload the published module into the active PowerShell session. -When `-ContinuousIntegration` is used, the release workflow restores the built `dist/` module after CI-sensitive -boundaries so later steps in the same session keep using the built module state instead of a stale or publish-modified -copy. +When `-ContinuousIntegration` is used, the release workflow restores the built `dist/` module after CI-sensitive boundaries so later steps in the same session keep using the built module state instead of a stale or publish-modified copy. `Invoke-NovaRelease` uses `SupportsShouldProcess`, so `Get-Help Invoke-NovaRelease -Full` surfaces native `-WhatIf` and `-Confirm` support. diff --git a/docs/NovaModuleTools/en-US/New-NovaModulePackage.md b/docs/NovaModuleTools/en-US/New-NovaModulePackage.md index 20119a25..257971bd 100644 --- a/docs/NovaModuleTools/en-US/New-NovaModulePackage.md +++ b/docs/NovaModuleTools/en-US/New-NovaModulePackage.md @@ -28,14 +28,12 @@ PS> New-NovaModulePackage [-SkipTests] [-OverrideWarning] [-WhatIf] [-Confirm] [ `New-NovaModulePackage` runs the normal NovaModuleTools build and test flow, then packages the built module output from `dist//` into the package formats requested by `Package.Types`. -Use `-SkipTests` when tests already ran earlier in your pipeline and you only want to skip `Test-NovaBuild` for this -packaging run. `Invoke-NovaBuild` still runs so the package is created from fresh built output. +Use `-SkipTests` when tests already ran earlier in your pipeline and you only want to skip `Test-NovaBuild` for this packaging run. `Invoke-NovaBuild` still runs so the package is created from fresh built output. Use `-OverrideWarning` only when you intentionally want the nested build to continue even though a file under `src/public` contains zero or multiple top-level functions. -The package is written to `artifacts/packages/` by default. You can override generic package metadata through the -optional `Package` section in `project.json`. +The package is written to `artifacts/packages/` by default. You can override generic package metadata through the optional `Package` section in `project.json`. Use this `project.json` shape when you want to control package types and the package output directory: @@ -57,8 +55,7 @@ Use this `project.json` shape when you want to control package types and the pac } ``` -`Package.Types` is optional. When it is missing, empty, or null, `New-NovaModulePackage` defaults to `NuGet` and creates -a `.nupkg` file. +`Package.Types` is optional. When it is missing, empty, or null, `New-NovaModulePackage` defaults to `NuGet` and creates a `.nupkg` file. Supported `Package.Types` values are `NuGet`, `Zip`, `.nupkg`, and `.zip`, and matching is case-insensitive. @@ -79,11 +76,9 @@ Set `Package.Latest` to `"never"` when only the versioned package file(s) should When `Package.AddVersionToFileName` is enabled and `Package.Latest` is `"stable"` or `"always"`, `New-NovaModulePackage` replaces that appended version suffix with `.latest` for the companion artifact. -`Package.OutputDirectory.Clean` defaults to `true`, which deletes the configured package output directory before a new -package is created. Set it to `false` when you want to keep existing files in that directory. +`Package.OutputDirectory.Clean` defaults to `true`, which deletes the configured package output directory before a new package is created. Set it to `false` when you want to keep existing files in that directory. -This command is intended for NovaModuleTools user projects that need a deployable package artifact without publishing to -PowerShell Gallery. +This command is intended for NovaModuleTools user projects that need a deployable package artifact without publishing to PowerShell Gallery. ## EXAMPLES @@ -93,8 +88,7 @@ PowerShell Gallery. PS> New-NovaModulePackage ``` -Builds the project, runs `Test-NovaBuild`, cleans `artifacts/packages/` by default, and writes a new `.nupkg` there -when `Package.Types` is omitted or resolves to `NuGet`. +Builds the project, runs `Test-NovaBuild`, cleans `artifacts/packages/` by default, and writes a new `.nupkg` there when `Package.Types` is omitted or resolves to `NuGet`. ### EXAMPLE 2 @@ -110,8 +104,7 @@ Previews the build, test, and packaging workflow without writing a package artif PS> New-NovaModulePackage ``` -When `Package.Types` is `@('NuGet', 'Zip')`, the command writes both `*.nupkg` and `*.zip` artifacts to the configured -package output directory. +When `Package.Types` is `@('NuGet', 'Zip')`, the command writes both `*.nupkg` and `*.zip` artifacts to the configured package output directory. ### EXAMPLE 4 @@ -119,8 +112,7 @@ package output directory. PS> New-NovaModulePackage ``` -When `Package.Latest` is `"stable"` and the project version is stable, the command keeps the normal versioned package -file and also writes a companion latest file such as `NovaModuleTools.latest.nupkg`. +When `Package.Latest` is `"stable"` and the project version is stable, the command keeps the normal versioned package file and also writes a companion latest file such as `NovaModuleTools.latest.nupkg`. ### EXAMPLE 5 @@ -128,8 +120,7 @@ file and also writes a companion latest file such as `NovaModuleTools.latest.nup PS> New-NovaModulePackage ``` -When `Package.PackageFileName` is `AgentInstaller` and `Package.AddVersionToFileName` is `true`, the command writes -package files such as `AgentInstaller.2.3.4.nupkg` and `AgentInstaller.latest.nupkg`. +When `Package.PackageFileName` is `AgentInstaller` and `Package.AddVersionToFileName` is `true`, the command writes package files such as `AgentInstaller.2.3.4.nupkg` and `AgentInstaller.latest.nupkg`. ### EXAMPLE 6 @@ -159,8 +150,7 @@ Builds the project and creates the package artifact without re-running `Test-Nov ### -SkipTests -Skip `Test-NovaBuild` for this packaging run. `Invoke-NovaBuild` still runs before packaging so the artifact is created -from fresh built output. +Skip `Test-NovaBuild` for this packaging run. `Invoke-NovaBuild` still runs before packaging so the artifact is created from fresh built output. This option is mainly intended for CI/CD flows where tests already passed earlier in the pipeline. @@ -183,8 +173,7 @@ HelpMessage: '' ### -OverrideWarning -Continue the nested build even if the `src/public` layout guard reports that a public file does not contain exactly one -top-level function. +Continue the nested build even if the `src/public` layout guard reports that a public file does not contain exactly one top-level function. ```yaml Type: System.Management.Automation.SwitchParameter @@ -249,9 +238,7 @@ HelpMessage: '' ### CommonParameters -This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, --InformationAction, -InformationVariable, -OutBuffer, -OutVariable, -PipelineVariable, --ProgressAction, -Verbose, -WarningAction, -WarningVariable, -WhatIf, and -Confirm. For more information, see +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction, -WarningVariable, -WhatIf, and -Confirm. For more information, see [about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS @@ -264,8 +251,7 @@ You can't pipe objects to this cmdlet. ### System.Management.Automation.PSCustomObject -Returns one artifact metadata object per generated package, including the package type, generated package path, output -directory, and source module directory. +Returns one artifact metadata object per generated package, including the package type, generated package path, output directory, and source module directory. ## NOTES @@ -280,18 +266,14 @@ Package metadata reuses values from `project.json` when possible, including: - `Manifest.ReleaseNotes` - `Manifest.LicenseUri` -`Manifest.Tags`, `Manifest.ProjectUri`, `Manifest.ReleaseNotes`, and `Manifest.LicenseUri` are optional. When they are -missing, `New-NovaModulePackage` omits the matching package metadata fields instead of treating them as required. +`Manifest.Tags`, `Manifest.ProjectUri`, `Manifest.ReleaseNotes`, and `Manifest.LicenseUri` are optional. When they are missing, `New-NovaModulePackage` omits the matching package metadata fields instead of treating them as required. -Use the top-level `Package` section only for generic packaging overrides such as package type selection, output -directory, or package file name. `New-NovaModulePackage` always allows packaging when you invoke it; there is no -separate +Use the top-level `Package` section only for generic packaging overrides such as package type selection, output directory, or package file name. `New-NovaModulePackage` always allows packaging when you invoke it; there is no separate `Package.Enabled` switch. When `-SkipTests` is used, only `Test-NovaBuild` is skipped. Build still runs. -Files under `src/public` are expected to contain exactly one top-level function each. `-OverrideWarning` bypasses that -guard only for the current packaging run. +Files under `src/public` are expected to contain exactly one top-level function each. `-OverrideWarning` bypasses that guard only for the current packaging run. ## RELATED LINKS diff --git a/docs/NovaModuleTools/en-US/NovaModuleTools.md b/docs/NovaModuleTools/en-US/NovaModuleTools.md index 8b220a60..840c2a44 100644 --- a/docs/NovaModuleTools/en-US/NovaModuleTools.md +++ b/docs/NovaModuleTools/en-US/NovaModuleTools.md @@ -14,18 +14,15 @@ title: NovaModuleTools Module ## Description -NovaModuleTools helps you scaffold, build, test, package, version, and publish PowerShell modules with a consistent -project layout and a repeatable workflow. +NovaModuleTools helps you scaffold, build, test, package, version, and publish PowerShell modules with a consistent project layout and a repeatable workflow. -Use the module when you want a structured path from source files under `src/` to a built module under `dist/`, including -manifest generation, external help generation, resource copying, and Pester-based validation. +Use the module when you want a structured path from source files under `src/` to a built module under `dist/`, including manifest generation, external help generation, resource copying, and Pester-based validation. ## NovaModuleTools Cmdlets ### `PS> Get-NovaProjectInfo` -Reads `project.json` and returns resolved project metadata and paths, or returns the project/install version views when -requested. +Reads `project.json` and returns resolved project metadata and paths, or returns the project/install version views when requested. ### `PS> Get-NovaUpdateNotificationPreference` @@ -57,9 +54,7 @@ Runs the project's Pester test workflow using settings from `project.json`. ### `PS> Update-NovaModuleTool` -Updates the installed `NovaModuleTools` module by using the stored prerelease preference that also controls whether -prerelease self-updates are eligible. Prerelease confirmations default to `No`, so pressing Enter cancels the -update. The compatibility alias `Update-NovaModuleTools` is also available. +Updates the installed `NovaModuleTools` module by using the stored prerelease preference that also controls whether prerelease self-updates are eligible. Prerelease confirmations default to `No`, so pressing Enter cancels the update. The compatibility alias `Update-NovaModuleTools` is also available. ### `PS> Initialize-NovaModule` diff --git a/docs/NovaModuleTools/en-US/Publish-NovaModule.md b/docs/NovaModuleTools/en-US/Publish-NovaModule.md index c1df4e64..a9271e4b 100644 --- a/docs/NovaModuleTools/en-US/Publish-NovaModule.md +++ b/docs/NovaModuleTools/en-US/Publish-NovaModule.md @@ -33,25 +33,19 @@ PS> Publish-NovaModule [-Repository] [[-ModuleDirectoryPath] ] `Publish-NovaModule` runs the normal NovaModuleTools build and test flow, then publishes the built module. -Use `-SkipTests` when tests already ran earlier in your pipeline and you only want to skip `Test-NovaBuild` for this -publish run. `Invoke-NovaBuild` still runs before the publish step. +Use `-SkipTests` when tests already ran earlier in your pipeline and you only want to skip `Test-NovaBuild` for this publish run. `Invoke-NovaBuild` still runs before the publish step. -Use local mode when you want to copy the built module into a module directory on the current machine. -After a successful local publish, the command reloads the published module from that local install path into the active -PowerShell session so the newly published module is ready to use immediately. +Use local mode when you want to copy the built module into a module directory on the current machine. After a successful local publish, the command reloads the published module from that local install path into the active PowerShell session so the newly published module is ready to use immediately. Use repository mode when you want to publish the built module to a registered PowerShell repository such as `PSGallery`. -Use `-ContinuousIntegration` when the same CI/self-hosting session should switch back to the built `dist/` module after -publish completes. This keeps later commands aligned with the built module state instead of whatever publish imported or -left loaded. +Use `-ContinuousIntegration` when the same CI/self-hosting session should switch back to the built `dist/` module after publish completes. This keeps later commands aligned with the built module state instead of whatever publish imported or left loaded. Use `-OverrideWarning` only when you intentionally want the nested build to continue even though a file under `src/public` contains zero or multiple top-level functions. -This command supports `-WhatIf` and `-Confirm` through PowerShell `SupportsShouldProcess`. Use `-WhatIf` to preview the -resolved publish target and workflow without building, testing, or publishing. +This command supports `-WhatIf` and `-Confirm` through PowerShell `SupportsShouldProcess`. Use `-WhatIf` to preview the resolved publish target and workflow without building, testing, or publishing. Use `-Confirm` when you want PowerShell to prompt before the publish workflow starts. @@ -63,8 +57,7 @@ Use `-Confirm` when you want PowerShell to prompt before the publish workflow st PS> Publish-NovaModule -Local ``` -Builds, tests, and copies the module to the default local module path. -When the copy succeeds, the published module is also imported from that local path. +Builds, tests, and copies the module to the default local module path. When the copy succeeds, the published module is also imported from that local path. ### EXAMPLE 2 @@ -72,8 +65,7 @@ When the copy succeeds, the published module is also imported from that local pa PS> Publish-NovaModule -Local -ModuleDirectoryPath ~/Modules ``` -Builds, tests, and copies the module to a custom local directory. -When the copy succeeds, the published module is imported from `~/Modules//.psd1`. +Builds, tests, and copies the module to a custom local directory. When the copy succeeds, the published module is imported from `~/Modules//.psd1`. ### EXAMPLE 3 @@ -97,8 +89,7 @@ Prompts before the repository publish workflow starts. PS> Publish-NovaModule -Local -WhatIf ``` -Previews the local publish workflow and target directory without making changes. -No module copy or import happens when `-WhatIf` is used. +Previews the local publish workflow and target directory without making changes. No module copy or import happens when `-WhatIf` is used. ### EXAMPLE 6 @@ -114,8 +105,7 @@ Builds and publishes the module to `PSGallery` without re-running `Test-NovaBuil PS> Publish-NovaModule -Repository PSGallery -ApiKey $env:PSGALLERY_API -ContinuousIntegration ``` -Publishes the module and then re-imports the built `dist//.psd1` so later CI steps in the -same session continue from the built module state. +Publishes the module and then re-imports the built `dist//.psd1` so later CI steps in the same session continue from the built module state. ## PARAMETERS @@ -236,8 +226,7 @@ HelpMessage: '' Re-import the built module from `dist/` after publish completes. -Use this when your CI/self-hosting workflow continues in the same session after publish and must keep using the built -module state for later commands. +Use this when your CI/self-hosting workflow continues in the same session after publish and must keep using the built module state for later commands. ```yaml Type: System.Management.Automation.SwitchParameter @@ -260,8 +249,7 @@ HelpMessage: '' ### -OverrideWarning -Continue the nested build even if the `src/public` layout guard reports that a public file does not contain exactly one -top-level function. +Continue the nested build even if the `src/public` layout guard reports that a public file does not contain exactly one top-level function. ```yaml Type: System.Management.Automation.SwitchParameter @@ -284,9 +272,7 @@ HelpMessage: '' ### CommonParameters -This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, --InformationAction, -InformationVariable, -OutBuffer, -OutVariable, -PipelineVariable, --ProgressAction, -Verbose, -WarningAction, -WarningVariable, -WhatIf, and -Confirm. For more information, see +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction, -WarningVariable, -WhatIf, and -Confirm. For more information, see [about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS @@ -299,27 +285,21 @@ You can't pipe objects to this cmdlet. ### None -This cmdlet does not emit an output object. In local mode it updates the active PowerShell session by importing the -published module from the local install path. +This cmdlet does not emit an output object. In local mode it updates the active PowerShell session by importing the published module from the local install path. ## NOTES The command always builds before publishing. -When `-SkipTests` is omitted, `Publish-NovaModule` also runs `Test-NovaBuild`. When `-SkipTests` is used, only the test -step is skipped. +When `-SkipTests` is omitted, `Publish-NovaModule` also runs `Test-NovaBuild`. When `-SkipTests` is used, only the test step is skipped. -Local publish imports the published module from the resolved local install directory. It does not import directly from -the -source project or from `dist/`. +Local publish imports the published module from the resolved local install directory. It does not import directly from the source project or from `dist/`. -When `-ContinuousIntegration` is used, Nova restores the built `dist/` module after publish so later commands in the -same session keep using the built module state. +When `-ContinuousIntegration` is used, Nova restores the built `dist/` module after publish so later commands in the same session keep using the built module state. `Publish-NovaModule` uses `SupportsShouldProcess`, so `Get-Help Publish-NovaModule -Full` should surface native `-WhatIf` and `-Confirm` support. - ## RELATED LINKS - https://github.com/stiwicourage/NovaModuleTools/blob/main/docs/NovaModuleTools/en-US/Invoke-NovaBuild.md diff --git a/docs/NovaModuleTools/en-US/Set-NovaUpdateNotificationPreference.md b/docs/NovaModuleTools/en-US/Set-NovaUpdateNotificationPreference.md index 3d9b8e07..c84effb2 100644 --- a/docs/NovaModuleTools/en-US/Set-NovaUpdateNotificationPreference.md +++ b/docs/NovaModuleTools/en-US/Set-NovaUpdateNotificationPreference.md @@ -34,8 +34,7 @@ PS> Set-NovaUpdateNotificationPreference -DisablePrereleaseNotifications [-WhatI `Set-NovaUpdateNotificationPreference` manages the user preference that controls whether `Update-NovaModuleTool` / `Update-NovaModuleTools` may select prerelease versions of `NovaModuleTools`. -The same stored preference is also used by `Update-NovaModuleTool` (alias: `Update-NovaModuleTools`) when it decides -whether a prerelease self-update can be selected. +The same stored preference is also used by `Update-NovaModuleTool` (alias: `Update-NovaModuleTools`) when it decides whether a prerelease self-update can be selected. Stable self-updates remain available and do not require prerelease eligibility. @@ -196,7 +195,6 @@ Returns the current prerelease self-update state, the always-available stable-up Use this command together with `Get-NovaUpdateNotificationPreference` when you want to confirm the stored setting. - ## RELATED LINKS - `Get-NovaUpdateNotificationPreference` diff --git a/docs/NovaModuleTools/en-US/Test-NovaBuild.md b/docs/NovaModuleTools/en-US/Test-NovaBuild.md index 01f7b4ea..cf54b51c 100644 --- a/docs/NovaModuleTools/en-US/Test-NovaBuild.md +++ b/docs/NovaModuleTools/en-US/Test-NovaBuild.md @@ -26,21 +26,19 @@ PS> Test-NovaBuild [-Build] [-OverrideWarning] [[-TagFilter] ] [[-Excl ## DESCRIPTION -`Test-NovaBuild` reads the Pester configuration from `project.json`, resolves the correct test path, and runs the test -suite against the current project. +`Test-NovaBuild` reads the Pester configuration from `project.json`, resolves the correct test path, and runs the test suite against the current project. + +When `project.json` sets `Pester.CodeCoverage.CoveragePercentTarget`, Nova also treats the configured threshold as a failure condition and stops the run if the measured coverage percentage is lower than that target. Use `-Build` when you want Nova to rebuild the project output before the Pester run starts. -When `-Build` is used, `-OverrideWarning` lets that nested build continue even if the `src/public` layout guard reports -zero or multiple top-level functions in a public file. +When `-Build` is used, `-OverrideWarning` lets that nested build continue even if the `src/public` layout guard reports zero or multiple top-level functions in a public file. With the default `BuildRecursiveFolders=true`, test files in nested folders under `tests` are discovered and run. Set -`BuildRecursiveFolders=false` to limit discovery to top-level `tests/*.Tests.ps1` files, following Pester's normal -test-file convention. The generated Pester XML report is written to `artifacts/TestResults.xml`. +`BuildRecursiveFolders=false` to limit discovery to top-level `tests/*.Tests.ps1` files, following Pester's normal test-file convention. The generated Pester XML report is written to `artifacts/TestResults.xml`. -This command supports `-WhatIf` and `-Confirm` through PowerShell `SupportsShouldProcess`. Use `-WhatIf` to preview the -planned test run and XML output path without creating `artifacts/` or invoking Pester. +This command supports `-WhatIf` and `-Confirm` through PowerShell `SupportsShouldProcess`. Use `-WhatIf` to preview the planned test run and XML output path without creating `artifacts/` or invoking Pester. ## EXAMPLES @@ -125,8 +123,7 @@ HelpMessage: '' ### -OverrideWarning -When `-Build` is also used, continue the nested build even if the `src/public` layout guard reports that a public file -does not contain exactly one top-level function. +When `-Build` is also used, continue the nested build even if the `src/public` layout guard reports that a public file does not contain exactly one top-level function. ```yaml Type: System.Management.Automation.SwitchParameter @@ -237,9 +234,7 @@ HelpMessage: '' ### CommonParameters -This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, --InformationAction, -InformationVariable, -OutBuffer, -OutVariable, -PipelineVariable, --ProgressAction, -Verbose, -WarningAction, -WarningVariable, -WhatIf, and -Confirm. For more information, see +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction, -WarningVariable, -WhatIf, and -Confirm. For more information, see [about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS @@ -252,12 +247,14 @@ You can't pipe objects to this cmdlet. ### None -This cmdlet does not emit an output object. It throws when the test run fails. +This cmdlet does not emit an output object. It throws when the test run fails or when a configured code coverage target is not met. ## NOTES The generated test result XML is written to `artifacts/TestResults.xml`. +If `project.json` configures `Pester.CodeCoverage.CoveragePercentTarget`, `Test-NovaBuild` also fails when the measured coverage percentage is lower than that configured threshold. + `Test-NovaBuild` uses `SupportsShouldProcess`, so `Get-Help Test-NovaBuild -Full` surfaces native `-WhatIf` and `-Confirm` support. diff --git a/docs/NovaModuleTools/en-US/Update-NovaModuleTools.md b/docs/NovaModuleTools/en-US/Update-NovaModuleTools.md index f60f4bae..e73fc390 100644 --- a/docs/NovaModuleTools/en-US/Update-NovaModuleTools.md +++ b/docs/NovaModuleTools/en-US/Update-NovaModuleTools.md @@ -29,16 +29,12 @@ PS> Update-NovaModuleTool [-WhatIf] [-Confirm] [] The cmdlet is also available through the compatibility alias `Update-NovaModuleTools`. -Before it runs `Update-Module`, it resolves the best available update candidate by using the stored prerelease -preference exposed through `Get-NovaUpdateNotificationPreference`, `Set-NovaUpdateNotificationPreference`, and -those PowerShell preference commands. +Before it runs `Update-Module`, it resolves the best available update candidate by using the stored prerelease preference exposed through `Get-NovaUpdateNotificationPreference`, `Set-NovaUpdateNotificationPreference`, and those PowerShell preference commands. When prerelease notifications are disabled, `Update-NovaModuleTool` only considers stable releases and never passes `-AllowPrerelease` to the update flow. -When prerelease notifications are enabled, `Update-NovaModuleTool` may target a prerelease. If the selected target is a -prerelease, the command always asks for explicit confirmation before it proceeds, and that prerelease confirmation -defaults to `No` so pressing Enter cancels the update. +When prerelease notifications are enabled, `Update-NovaModuleTool` may target a prerelease. If the selected target is a prerelease, the command always asks for explicit confirmation before it proceeds, and that prerelease confirmation defaults to `No` so pressing Enter cancels the update. Stable updates do not require prerelease confirmation. @@ -52,8 +48,7 @@ After a successful update, `Update-NovaModuleTool` prints the release notes link PS> Update-NovaModuleTool ``` -Updates the installed `NovaModuleTools` module by using the stored prerelease preference to resolve the update -candidate. +Updates the installed `NovaModuleTools` module by using the stored prerelease preference to resolve the update candidate. ### EXAMPLE 2 @@ -87,8 +82,7 @@ Previews the resolved update action without running `Update-Module`. ### -WhatIf -Shows what would happen if the cmdlet runs. `Update-NovaModuleTool` resolves the target version first, then previews the -selected stable or prerelease update action without changing the installed module. +Shows what would happen if the cmdlet runs. `Update-NovaModuleTool` resolves the target version first, then previews the selected stable or prerelease update action without changing the installed module. ```yaml Type: System.Management.Automation.SwitchParameter @@ -144,16 +138,14 @@ You can't pipe objects to this cmdlet. ### PSCustomObject -Returns a self-update plan/result object that shows the current version, the resolved target version, whether a newer -update was available, whether the target was prerelease, and whether the update ran or was cancelled. +Returns a self-update plan/result object that shows the current version, the resolved target version, whether a newer update was available, whether the target was prerelease, and whether the update ran or was cancelled. ## NOTES If the PowerShell Gallery cannot be reached well enough to resolve an update candidate, the command stops before calling `Update-Module`. -Use `Get-NovaUpdateNotificationPreference` and `Set-NovaUpdateNotificationPreference` to inspect or change the stored -prerelease setting. +Use `Get-NovaUpdateNotificationPreference` and `Set-NovaUpdateNotificationPreference` to inspect or change the stored prerelease setting. ## RELATED LINKS diff --git a/docs/NovaModuleTools/en-US/Update-NovaModuleVersion.md b/docs/NovaModuleTools/en-US/Update-NovaModuleVersion.md index c84053ce..dfba2f23 100644 --- a/docs/NovaModuleTools/en-US/Update-NovaModuleVersion.md +++ b/docs/NovaModuleTools/en-US/Update-NovaModuleVersion.md @@ -25,16 +25,9 @@ PS> Update-NovaModuleVersion [[-Path] ] [-Preview] [-ContinuousIntegrati ## DESCRIPTION -`Update-NovaModuleVersion` reads the current project version from `project.json`, collects Git commit messages from the -project repository, chooses a semantic version bump label, calculates the next semantic version, and writes the updated -version back to `project.json`. - -Use `-Preview` when you want an explicit prerelease-continuation bump instead of the default prerelease finalization -behavior. In preview mode, stable versions always enter the next patch preview track by incrementing the patch version -and appending `-preview`. Existing prerelease versions keep the same semantic core and preserve the current prerelease -stem while -appending or incrementing trailing digits. Any bare prerelease label now starts at `01` for predictable ordering, -for example `preview -> preview01`, `preview09 -> preview10`, `rc -> rc01`, `rc1 -> rc2`, and +`Update-NovaModuleVersion` reads the current project version from `project.json`, collects Git commit messages from the project repository, chooses a semantic version bump label, calculates the next semantic version, and writes the updated version back to `project.json`. + +Use `-Preview` when you want an explicit prerelease-continuation bump instead of the default prerelease finalization behavior. In preview mode, stable versions always enter the next patch preview track by incrementing the patch version and appending `-preview`. Existing prerelease versions keep the same semantic core and preserve the current prerelease stem while appending or incrementing trailing digits. Any bare prerelease label now starts at `01` for predictable ordering, for example `preview -> preview01`, `preview09 -> preview10`, `rc -> rc01`, `rc1 -> rc2`, and `SNAPSHOT -> SNAPSHOT01`. The release label is inferred from the commit set: @@ -43,31 +36,20 @@ The release label is inferred from the commit set: - `Minor` for `feat:` commits - `Patch` for `fix:` commits and all other cases -When the current stable version is still on `0.y.z` and the inferred label is `Major`, Nova keeps the release on the -initial-development line and plans the next minor version instead of jumping straight to `1.0.0`. The result still -reports the detected `Major` label so you can see that the commit set contained a breaking change, and Nova prints -guidance about manually setting `1.0.0` once the software is stable. With `-Preview`, stable versions still enter the -next patch preview track instead of applying semantic history inference to the semantic core. +When the current stable version is still on `0.y.z` and the inferred label is `Major`, Nova keeps the release on the initial-development line and plans the next minor version instead of jumping straight to `1.0.0`. The result still reports the detected `Major` label so you can see that the commit set contained a breaking change, and Nova prints guidance about manually setting `1.0.0` once the software is stable. With `-Preview`, stable versions still enter the next patch preview track instead of applying semantic history inference to the semantic core. -When Git tags exist, only commits since the latest tag are considered. If Git-based inference is unavailable because the -project path is not inside a Git repository, the command stops with a clear warning/error instead of silently presenting -an inferred-looking patch result. Use `-OverrideWarning` only when you intentionally want that Patch fallback, for -example in example/template flows outside Git. +When Git tags exist, only commits since the latest tag are considered. If Git-based inference is unavailable because the project path is not inside a Git repository, the command stops with a clear warning/error instead of silently presenting an inferred-looking patch result. Use `-OverrideWarning` only when you intentionally want that Patch fallback, for example in example/template flows outside Git. If the repository exists but has no commits yet, the command stops with: `Cannot bump version because the repository has no commits yet. Create an initial commit first.` -This command supports `-WhatIf` and `-Confirm` through PowerShell `SupportsShouldProcess`. Use `-WhatIf` to preview the -calculated release label and the exact next version without changing the stored version. +This command supports `-WhatIf` and `-Confirm` through PowerShell `SupportsShouldProcess`. Use `-WhatIf` to preview the calculated release label and the exact next version without changing the stored version. -Use `-ContinuousIntegration` when the same session should first re-activate the built `dist/` module before the version -bump workflow starts. This is useful in CI/self-hosting flows where an earlier command changed the active module state. +Use `-ContinuousIntegration` when the same session should first re-activate the built `dist/` module before the version bump workflow starts. This is useful in CI/self-hosting flows where an earlier command changed the active module state. -When the current version is already a prerelease for the selected release line, Nova finalizes that same semantic -version instead of incrementing again. For example, a `Major` bump from `2.0.0-preview7` resolves to `2.0.0`, not +When the current version is already a prerelease for the selected release line, Nova finalizes that same semantic version instead of incrementing again. For example, a `Major` bump from `2.0.0-preview7` resolves to `2.0.0`, not `3.0.0-preview7`. - ## EXAMPLES ### EXAMPLE 1 @@ -129,8 +111,7 @@ Label: Minor CommitCount: 12 ``` -Shows how `-Preview` keeps the detected semantic label for reporting but deterministically enters the next patch preview -track when the current version is stable. +Shows how `-Preview` keeps the detected semantic label for reporting but deterministically enters the next patch preview track when the current version is stable. ### EXAMPLE 6 @@ -145,8 +126,7 @@ Label: Patch CommitCount: 3 ``` -Shows how `-Preview` stays on the same semantic core and increments the current prerelease label when the current -version is already a prerelease. +Shows how `-Preview` stays on the same semantic core and increments the current prerelease label when the current version is already a prerelease. ### EXAMPLE 7 @@ -185,8 +165,7 @@ Label: Major CommitCount: 34 ``` -Shows how stable `0.y.z` bumps still warn that `1.0.0` must be set manually when the API becomes stable, while -breaking-change commits on that line continue to plan the next minor version instead of jumping straight to `1.0.0`. +Shows how stable `0.y.z` bumps still warn that `1.0.0` must be set manually when the API becomes stable, while breaking-change commits on that line continue to plan the next minor version instead of jumping straight to `1.0.0`. ### EXAMPLE 10 @@ -198,8 +177,7 @@ WARNING: Cannot infer the version bump label from Git history because no Git rep What if: Performing the operation "Update module version using Patch release label" on target "project.json". ``` -Shows how to opt in explicitly to the Patch fallback when a project lives outside a Git repository and Nova therefore -cannot infer the semantic label from commit history. +Shows how to opt in explicitly to the Patch fallback when a project lives outside a Git repository and Nova therefore cannot infer the semantic label from commit history. ## PARAMETERS @@ -228,10 +206,7 @@ HelpMessage: '' Opt into preview bump mode. -When the current version is stable, Nova increments the patch version and appends `-preview`. When the current -version already has any prerelease label, Nova keeps the same semantic core version and increments the current -prerelease suffix instead of finalizing or advancing to another release line. Any prerelease stem without a trailing -number starts at `01`, while labels that already include a number simply increment that number. +When the current version is stable, Nova increments the patch version and appends `-preview`. When the current version already has any prerelease label, Nova keeps the same semantic core version and increments the current prerelease suffix instead of finalizing or advancing to another release line. Any prerelease stem without a trailing number starts at `01`, while labels that already include a number simply increment that number. ```yaml Type: System.Management.Automation.SwitchParameter @@ -254,8 +229,7 @@ HelpMessage: '' Re-import the built module from `dist/` before the version bump workflow starts. -Use this when later steps in the same CI/self-hosting session must stay aligned with the built module state that Nova -just produced earlier in the workflow. +Use this when later steps in the same CI/self-hosting session must stay aligned with the built module state that Nova just produced earlier in the workflow. ```yaml Type: System.Management.Automation.SwitchParameter @@ -278,8 +252,7 @@ HelpMessage: '' Allow the version bump to continue with the explicit Patch fallback when Git-based inference is unavailable. -Use this only when you intentionally want to bump a project outside a Git repository, for example in example/template -flows where no commit history exists. +Use this only when you intentionally want to bump a project outside a Git repository, for example in example/template flows where no commit history exists. ```yaml Type: System.Management.Automation.SwitchParameter @@ -300,9 +273,7 @@ HelpMessage: '' ### CommonParameters -This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, --InformationAction, -InformationVariable, -OutBuffer, -OutVariable, -PipelineVariable, --ProgressAction, -Verbose, -WarningAction, -WarningVariable, -WhatIf, and -Confirm. For more information, see +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction, -WarningVariable, -WhatIf, and -Confirm. For more information, see [about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS @@ -321,17 +292,14 @@ Returns the previous version, new version, selected release label, and commit co Run this command from a NovaModuleTools project root or supply `-Path`. -This command updates `project.json`. Rebuild the module afterward if you want the generated manifest and built output to -reflect the new version. +This command updates `project.json`. Rebuild the module afterward if you want the generated manifest and built output to reflect the new version. `Update-NovaModuleVersion` uses `SupportsShouldProcess`, so `Get-Help Update-NovaModuleVersion -Full` surfaces native `-WhatIf` and `-Confirm` support. -When `-ContinuousIntegration` is used with a real update, the command re-activates the built `dist/` module first. When -combined with `-WhatIf`, Nova still previews the bump without changing the loaded module state. +When `-ContinuousIntegration` is used with a real update, the command re-activates the built `dist/` module first. When combined with `-WhatIf`, Nova still previews the bump without changing the loaded module state. -When Git-based inference is unavailable, `Update-NovaModuleVersion` now requires `-OverrideWarning` before it continues -with the intentional Patch fallback. +When Git-based inference is unavailable, `Update-NovaModuleVersion` now requires `-OverrideWarning` before it continues with the intentional Patch fallback. ## RELATED LINKS diff --git a/docs/assets/release-notes.js b/docs/assets/release-notes.js index 7a855168..39d13070 100644 --- a/docs/assets/release-notes.js +++ b/docs/assets/release-notes.js @@ -17,7 +17,7 @@ function requireMarked() { function createRenderer(marked) { const renderer = new marked.Renderer(); - renderer.link = function ({ tokens }) { + renderer.link = function ({tokens}) { return this.parser.parseInline(tokens ?? []); }; @@ -96,7 +96,7 @@ async function initializeReleaseNotesPage() { } try { - const response = await fetch(releaseNotesSourceUrl, { cache: 'no-store' }); + const response = await fetch(releaseNotesSourceUrl, {cache: 'no-store'}); if (!response.ok) { throw new Error(`GitHub returned ${response.status}`); diff --git a/docs/assets/site.css b/docs/assets/site.css index 52988acb..b5f949ca 100644 --- a/docs/assets/site.css +++ b/docs/assets/site.css @@ -35,10 +35,9 @@ body { font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; line-height: 1.68; color: var(--text); - background: - radial-gradient(circle at top left, #1d2a5b 0%, transparent 34%), - radial-gradient(circle at top right, #0f6d66 0%, transparent 25%), - linear-gradient(180deg, #0b1020 0%, #0f1731 48%, #0d1327 100%); + background: radial-gradient(circle at top left, #1d2a5b 0%, transparent 34%), + radial-gradient(circle at top right, #0f6d66 0%, transparent 25%), + linear-gradient(180deg, #0b1020 0%, #0f1731 48%, #0d1327 100%); } a { diff --git a/docs/commands.html b/docs/commands.html index bd7bbce1..f49a6311 100644 --- a/docs/commands.html +++ b/docs/commands.html @@ -162,7 +162,7 @@

Install the nova launcher

PS> Install-NovaCli
 PS> Install-NovaCli -DestinationDirectory ~/bin -Force
-

See setup details +

See setup details

@@ -174,7 +174,35 @@

Start a new project

Cmdlet: Initialize-NovaModule

-

Create the minimal scaffold or the example scaffold for a new module project.

+

Create the minimal scaffold or the example scaffold for a new module project. Before the + first interactive question, Nova checks whether a newer NovaModuleTools release is + available and warns without blocking the scaffold flow. When Git is enabled, Nova also + creates or updates a default .gitignore in the generated project root so + common local and CI artifact paths are ignored without overwriting existing rules. Both + interactive flows can also add the optional Agentic Copilot starter package, + which follows Nova's maintained agentic guidance through a filtered starter mirror, including Nova build/test + expectations, project.json Manifest.PowerShellHostVersion + compatibility guidance, strict ScriptAnalyzer guidance without excluded rules, generated + dist module files, command-help ownership, source-mirrored test guidance, + instructions to fix ScriptAnalyzer findings reported by run.ps1 before + handoff, explicit public/private PowerShell file ownership guidance, a best-effort + source/helper-script maintainability guidance plus separate test-design guidance delivered + through best-effort source/helper-script maintainability guidance plus separate test-design guidance, explicit PSScriptAnalyzer + workflow guidance for ./scripts/build/Invoke-ScriptAnalyzerCI.ps1, + ./run.ps1, focused Invoke-ScriptAnalyzer usage, and + Test-NovaBuild-only project test guidance that forbids direct + Invoke-Pester, explicit + valid-PlatyPS help guidance for docs/<ProjectName>/en-US/*.md using + New-MarkdownCommandHelp, Update-MarkdownCommandHelp, and + Test-MarkdownCommandHelp, with a matching help file required for every new + public entry point, and a strict file-ending rule for changed or + generated text files. +

+

New projects also start with Nova's default Pester.CodeCoverage block in + project.json, but keep it disabled until you choose to enable coverage.

+

If you enable the Agentic package, Nova also asks for a short project name used in generated + guidance placeholders such as Invoke-<ShortName>*. For NovaModuleTools the + short name is Nova, but it could also have been NMT.

  • Use when: you are creating a fresh NovaModuleTools project