From b078278c4e437eb325750c81e81f24c0233c9625 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 10 May 2026 10:23:06 +0000 Subject: [PATCH 01/31] chore: prepare develop for next prerelease --- project.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project.json b/project.json index 15f4660a..ed66dff7 100644 --- a/project.json +++ b/project.json @@ -1,7 +1,7 @@ { "ProjectName": "NovaModuleTools", "Description": "NovaModuleTools is an enterprise-focused evolution of ModuleTools, designed for large-scale PowerShell projects with a strong emphasis on structure, maintainability, and automated CI/CD pipelines.", - "Version": "2.4.0", + "Version": "2.4.1-preview", "Preamble": [ "Set-StrictMode -Version Latest", "$ErrorActionPreference = 'Stop'" From ad76e724eadaa3a42be772d10e4c04d2933a7415 Mon Sep 17 00:00:00 2001 From: Stiwi Gabriel Courage Date: Sun, 10 May 2026 12:32:05 +0200 Subject: [PATCH 02/31] Update changelog for version 1.9.1 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index caa08f08..ec24cf0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -425,7 +425,7 @@ Keep stable `Update-NovaModuleVersion` / `% nova bump` releases on the SemVer ma [2.2.0]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_2.1.0...2.2.0 [2.1.0]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_2.0.0...Version_2.1.0 [2.0.0]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_1.9.1...Version_2.0.0 -[1.9.0]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_1.8.0...Version_1.9.0 +[1.9.1]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_1.8.0...Version_1.9.1 [1.8.0]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_1.7.0...Version_1.8.0 [1.3.0]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_1.2.5-preview...Version_1.3.0 [1.2.0]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_1.1.4-preview...Version_1.2.0 From 76ebadac99fbb90f2ff29ea94fc8828655acbe1d Mon Sep 17 00:00:00 2001 From: Stiwi Gabriel Courage Date: Mon, 11 May 2026 08:21:38 +0200 Subject: [PATCH 03/31] feat(#196): clarify architect finalization handoff (#197) Add explicit readiness-check guidance for architect/design flows so unresolved questions are surfaced before finalization. Support design-package-only handoff, clarify how to use design notes versus GitHub issue drafts, and update the related repository guidance. --- .github/agents/architect.agent.md | 12 +++++- .github/copilot-instructions.md | 5 ++- .github/prompts/design-change.prompt.md | 50 +++++++++++++++++++++---- CHANGELOG.md | 5 ++- CONTRIBUTING.md | 4 +- README.md | 3 +- 6 files changed, 66 insertions(+), 13 deletions(-) diff --git a/.github/agents/architect.agent.md b/.github/agents/architect.agent.md index 0b84239f..d8125330 100644 --- a/.github/agents/architect.agent.md +++ b/.github/agents/architect.agent.md @@ -19,6 +19,11 @@ release automation. - Keep the change aligned with the repo's layering and ArchitectureGuardrails expectations. - Recommend the smallest structure that solves the problem cleanly. - Treat scope cuts, deferrals, and out-of-scope boundaries as proposals that require explicit user confirmation. +- Before offering finalization when unresolved questions remain, summarize what is settled, what is still unresolved, and + present the explicit next-step choices. +- Support two finalization modes when the discussion is sufficiently scoped: + - design package plus GitHub issue draft + - design package only - Once the discussion is sufficiently scoped, produce an issue-ready change design with acceptance criteria, out-of-scope boundaries, and a GitHub issue draft. @@ -51,6 +56,8 @@ release automation. - Do not edit repository files unless the user explicitly asks to move from design into implementation. - Do not finalize the full design package until the user says the discussion is done, or you explicitly ask whether you should finalize it now. +- Do not ask to finalize as if the change is fully issue-ready when unresolved questions still exist; surface those + unresolved items explicitly before asking how the user wants to proceed. - Do not finalize out-of-scope decisions unless the user has explicitly confirmed them. ## Definition of done @@ -58,7 +65,9 @@ release automation. - The affected layers and files are clearly identified. - The scoped implementation approach matches existing repo structure. - Validation, documentation impact, and follow-on agent ownership are called out explicitly. -- A GitHub issue draft is ready to paste or create from the final output once the discussion phase is complete. +- 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. ## Must not do @@ -68,5 +77,6 @@ release automation. - 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 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/copilot-instructions.md b/.github/copilot-instructions.md index c6c75827..44c1e616 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -24,8 +24,9 @@ to use one of the repository's reusable task prompts. 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. Proposed scope cuts or out-of-scope boundaries must be confirmed by the user before they are -treated as final. +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. ## Repository map diff --git a/.github/prompts/design-change.prompt.md b/.github/prompts/design-change.prompt.md index 7d71b960..a2441473 100644 --- a/.github/prompts/design-change.prompt.md +++ b/.github/prompts/design-change.prompt.md @@ -30,12 +30,20 @@ deferred, split into follow-up work, or excluded from the first implementation p exists. 6. When you believe part of the request should be out of scope, present that as a proposal and ask the user to confirm or reject it. Do not silently narrow the task. -7. Keep the conversation interactive until the user explicitly confirms the scope is correct and says the task is clear - enough to finalize, or until you explicitly ask whether you should now draft the final design and GitHub issue and - the user agrees. -8. Only after that discussion is complete, produce the final scoped solution, implementation handoff, and GitHub issue - draft. -9. Do not edit repository files unless the user explicitly switches from design to implementation. +7. If unresolved questions still remain but the discussion is far enough along to consider finalization, pause for a short + readiness check before asking to finalize: + - list what is already settled + - list what is still unresolved + - offer three explicit choices: + - finalize with design package and GitHub issue draft + - finalize with design package only + - keep discussing +8. Keep the conversation interactive until the user explicitly confirms the scope is correct and says the task is clear + enough to finalize, or until you explicitly ask whether you should now draft the final output and the user chooses one + of those options. +9. Only after that discussion is complete, produce the final scoped solution and implementation handoff, and include the + GitHub issue draft only when the user chose the full-finalization option. +10. Do not edit repository files unless the user explicitly switches from design to implementation. ## Discussion-phase output @@ -47,14 +55,18 @@ Use the first response and follow-up design turns to drive a conversation, not t - clear trade-offs - a recommendation when one option is strongest - proposed scope and out-of-scope boundaries clearly marked as proposals until the user confirms them +- when unresolved items remain, a readiness summary before any finalization question so the user knows what is still open Do not produce the full final design package in the first response unless the user explicitly asks for it. Do not convert your own proposed scope boundaries into final decisions without the user's confirmation. ## Finalization output -Once the user confirms the scope and says the discussion is done, or explicitly asks for the final design, return: +If the user chooses **design package and GitHub issue draft**, return: +- a short usage note that explains: + - the sections before `GitHub issue draft` are design/handoff notes + - only the `GitHub issue draft` section is paste-ready GitHub text - Problem - Why it matters - Scope @@ -66,6 +78,27 @@ Once the user confirms the scope and says the discussion is done, or explicitly - 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 the user chooses **design package only**, return: + +- Problem +- Why it matters +- Scope +- Out of scope +- Affected areas and likely files +- Validation and documentation impact +- Proposed implementation approach +- Open questions / resume here +- Recommended follow-on agent + +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 + ## Repository-specific reminders - Preserve the distinction between public PowerShell cmdlets and `% nova` CLI behavior. @@ -75,6 +108,9 @@ Once the user confirms the scope and says the discussion is done, or explicitly - 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. +- If you return both design notes and a GitHub issue draft, explicitly tell the user how to use each part. - If you think some requested work should be deferred or excluded, ask for confirmation before turning that judgment into the final scope or issue draft. diff --git a/CHANGELOG.md b/CHANGELOG.md index ec24cf0a..b148b562 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### 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, and clarifies how to use design notes versus the paste-ready + GitHub issue draft. + ### Deprecated ### Removed @@ -437,4 +441,3 @@ Keep stable `Update-NovaModuleVersion` / `% nova bump` releases on the SemVer ma [0.0.6]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_0.0.5...Version_0.0.6 [0.0.5]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_0.0.4...Version_0.0.5 [0.0.4]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_0.0.3...Version_0.0.4 - diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f0964381..3e816e8f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -49,7 +49,9 @@ 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. Use `implement-issue.prompt.md` after the change is already scoped. +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. diff --git a/README.md b/README.md index 9de3c181..7625b9f2 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,8 @@ For new or still-fuzzy work, start with `architect.agent.md` together with `desi lead with discussion, questions, and design options rather than a finished solution in the first reply. Use `implement-issue.prompt.md` once the scope, acceptance criteria, and follow-on implementation path are already clear. If architect proposes that part of the request is out of scope, treat that as a proposal to confirm rather than a final -decision. +decision. If unresolved design questions still remain, architect should first summarize what is settled vs unresolved and +then let the user choose between full finalization, a design-package-only handoff, or continued discussion. ### Prerequisites From 39fa3a42804e010e073521dd68262d42690a424b Mon Sep 17 00:00:00 2001 From: Stiwi Gabriel Courage Date: Tue, 12 May 2026 03:06:19 +0200 Subject: [PATCH 04/31] fix: clean up whitespace and formatting in multiple files - Removed unnecessary blank lines in ReadAwesomeHost.ps1 - Adjusted spacing in GetNovaResolvedProjectPackageSettings.ps1 - Standardized spacing in SKILL.md and other markdown files --- .github/agents/architect.agent.md | 24 +- .github/agents/docs-site.agent.md | 6 +- .github/agents/release-manager.agent.md | 6 +- .github/agents/reviewer.agent.md | 6 +- .github/agents/test-engineer.agent.md | 3 +- .github/copilot-instructions.md | 33 +- ...owershell-coding-standards.instructions.md | 10 +- .../release-policy.instructions.md | 6 +- .../testing-policy.instructions.md | 3 +- .github/prompts/design-change.prompt.md | 66 ++-- .github/prompts/implement-issue.prompt.md | 9 +- .github/prompts/markdown.prompt.md | 7 +- .github/prompts/prepare-release.prompt.md | 10 +- .github/prompts/review-change.prompt.md | 3 +- .github/pull_request_template.md | 13 +- .github/skills/codescene-quality/SKILL.md | 6 +- .github/skills/docs-site-html/SKILL.md | 3 +- .github/skills/github-actions/SKILL.md | 3 +- .../SKILL.md | 14 +- .github/skills/markdown-authoring/SKILL.md | 6 +- .../powershell-module-development/SKILL.md | 6 +- .github/skills/release-and-changelog/SKILL.md | 12 +- .../safeguarding-ai-generated-code/SKILL.md | 19 +- CHANGELOG.md | 311 +++++++-------- CODE_OF_CONDUCT.md | 57 ++- CONTRIBUTING.md | 31 +- README.md | 192 +++------ RELEASE_NOTE.md | 44 +-- project.json | 2 +- src/private/build/BuildManifest.ps1 | 24 +- .../GetOrderedScriptFileForDirectory.ps1 | 6 +- src/private/build/TestProjectSchema.ps1 | 2 +- .../manifest/GetAliasNameFromFunction.ps1 | 10 +- .../manifest/GetFunctionNameFromFile.ps1 | 6 +- src/private/cli/ReadAwesomeHost.ps1 | 1 - ...BuiltModuleHasNoDuplicateFunctionNames.ps1 | 2 +- .../FormatDuplicateFunctionErrorMessage.ps1 | 2 +- .../duplicates/GetDuplicateFunctionGroup.ps1 | 6 +- .../duplicates/GetTopLevelFunctionAst.ps1 | 10 +- .../GetNovaResolvedProjectPackageSettings.ps1 | 2 +- src/resources/ProjectTemplate.json | 36 +- src/resources/Schema-Build.json | 372 +++++++++--------- src/resources/Schema-Pester.json | 66 ++-- src/resources/example/README.md | 14 +- tests/BuildOptions.TestSupport.ps1 | 56 +-- tests/BuildOptions.Tests.ps1 | 28 +- tests/CodeSceneAnalysis.Tests.ps1 | 5 +- tests/CoverageGaps.ReleaseInternals.Tests.ps1 | 2 +- tests/PackageLatestPolicy.Tests.ps1 | 2 +- tests/RemainingHelperCoverage.TestSupport.ps1 | 2 +- 50 files changed, 684 insertions(+), 881 deletions(-) diff --git a/.github/agents/architect.agent.md b/.github/agents/architect.agent.md index d8125330..b19e5f70 100644 --- a/.github/agents/architect.agent.md +++ b/.github/agents/architect.agent.md @@ -7,25 +7,21 @@ description: Designs and scopes NovaModuleTools changes through a discussion-fir ## Purpose -Design or reshape changes that cross public commands, private helper boundaries, workflows, documentation layers, or -release automation. +Design or reshape changes that cross public commands, private helper boundaries, workflows, documentation layers, or release automation. ## Responsibilities -- Default new work to analysis first: clarify the problem, scope, risks, affected layers, validation needs, and - documentation impact before implementation starts. +- Default new work to analysis first: clarify the problem, scope, risks, affected layers, validation needs, and documentation impact before implementation starts. - Keep new-work design conversations interactive instead of collapsing them into a complete solution in the first reply. - Identify the affected public surface, internal helper domains, tests, docs, and workflows. - Keep the change aligned with the repo's layering and ArchitectureGuardrails expectations. - Recommend the smallest structure that solves the problem cleanly. - Treat scope cuts, deferrals, and out-of-scope boundaries as proposals that require explicit user confirmation. -- Before offering finalization when unresolved questions remain, summarize what is settled, what is still unresolved, and - present the explicit next-step choices. +- Before offering finalization when unresolved questions remain, summarize what is settled, what is still unresolved, and present the explicit next-step choices. - Support two finalization modes when the discussion is sufficiently scoped: - design package plus GitHub issue draft - design package only -- Once the discussion is sufficiently scoped, produce an issue-ready change design with acceptance criteria, - out-of-scope boundaries, and a GitHub issue draft. +- Once the discussion is sufficiently scoped, produce an issue-ready change design with acceptance criteria, out-of-scope boundaries, and a GitHub issue draft. ## Inputs to inspect @@ -54,10 +50,8 @@ release automation. - Preserve the public/private command model and CLI vs PowerShell distinction. - Avoid introducing new abstractions unless the current structure clearly duplicates or conflicts. - Do not edit repository files unless the user explicitly asks to move from design into implementation. -- Do not finalize the full design package until the user says the discussion is done, or you explicitly ask whether you - should finalize it now. -- Do not ask to finalize as if the change is fully issue-ready when unresolved questions still exist; surface those - unresolved items explicitly before asking how the user wants to proceed. +- Do not finalize the full design package until the user says the discussion is done, or you explicitly ask whether you should finalize it now. +- Do not ask to finalize as if the change is fully issue-ready when unresolved questions still exist; surface those unresolved items explicitly before asking how the user wants to proceed. - Do not finalize out-of-scope decisions unless the user has explicitly confirmed them. ## Definition of done @@ -75,8 +69,6 @@ release automation. - Must not invent new build or test tools. - Must not bypass established adapters or shared helpers without a strong reason. - 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 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 decide on its own that requested work is out of scope and then finalize the design without the user's - confirmation. +- 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 71e9c73b..e5a2e1d6 100644 --- a/.github/agents/docs-site.agent.md +++ b/.github/agents/docs-site.agent.md @@ -7,8 +7,7 @@ description: Keeps NovaModuleTools website documentation accurate and clearly se ## Purpose -Keep the GitHub Pages documentation under `docs/*.html` accurate, user-focused, and clearly separated from PowerShell -cmdlet help and contributor documentation. +Keep the GitHub Pages documentation under `docs/*.html` accurate, user-focused, and clearly separated from PowerShell cmdlet help and contributor documentation. ## Responsibilities @@ -37,8 +36,7 @@ cmdlet help and contributor documentation. - Treat `docs/*.html` as end-user website docs, not cmdlet help. - Keep CLI and cmdlet surfaces clearly separated. -- Mention PowerShell-only commands in CLI-oriented docs only when there is no CLI equivalent for that scenario, such as - installing NovaModuleTools with `Install-Module`. +- Mention PowerShell-only commands in CLI-oriented docs only when there is no CLI equivalent for that scenario, such as installing NovaModuleTools with `Install-Module`. ## Definition of done diff --git a/.github/agents/release-manager.agent.md b/.github/agents/release-manager.agent.md index b38747c8..2ac0a504 100644 --- a/.github/agents/release-manager.agent.md +++ b/.github/agents/release-manager.agent.md @@ -14,8 +14,7 @@ Handle versioning, changelog shaping, release-flow documentation, and publish au - Verify how a change affects stable vs prerelease behavior. - 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. +- Produce a release-ready summary that follows `.github/pull_request_template.md` when a release preparation summary is requested. ## Inputs to inspect @@ -39,8 +38,7 @@ Handle versioning, changelog shaping, release-flow documentation, and publish au - 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`. -- 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. +- 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` diff --git a/.github/agents/reviewer.agent.md b/.github/agents/reviewer.agent.md index 33dff75c..71f8167f 100644 --- a/.github/agents/reviewer.agent.md +++ b/.github/agents/reviewer.agent.md @@ -14,10 +14,8 @@ 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. -- 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. +- 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. ## Inputs to inspect diff --git a/.github/agents/test-engineer.agent.md b/.github/agents/test-engineer.agent.md index 915bab58..358d82c8 100644 --- a/.github/agents/test-engineer.agent.md +++ b/.github/agents/test-engineer.agent.md @@ -43,8 +43,7 @@ Improve or maintain the repository's Pester coverage, coverage-gate behavior, an - The changed behavior is covered. - The touched tests are readable and low-duplication. - 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. +- The pre-commit CodeScene safeguard is clean before the work is treated as commit-ready when local CodeScene tooling is available. ## Must not do diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 44c1e616..43e2548e 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -4,8 +4,7 @@ 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. +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. ## Start here @@ -17,22 +16,15 @@ Read these files before making non-trivial changes: 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. +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. 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. +`.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. ## 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/`) +- `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 @@ -58,11 +50,8 @@ handoff. Proposed scope cuts or out-of-scope boundaries must be confirmed by the - 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. +- 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 @@ -74,11 +63,8 @@ handoff. Proposed scope cuts or out-of-scope boundaries must be confirmed by the ## 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. +- 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 @@ -97,8 +83,7 @@ When CodeScene tooling is available: - 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. +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. diff --git a/.github/instructions/powershell-coding-standards.instructions.md b/.github/instructions/powershell-coding-standards.instructions.md index ff41b97a..6c6d195f 100644 --- a/.github/instructions/powershell-coding-standards.instructions.md +++ b/.github/instructions/powershell-coding-standards.instructions.md @@ -20,8 +20,7 @@ Use this file when changing `src/public/`, `src/private/`, or PowerShell build/r - Put internal helpers in the correct domain folder under `src/private/`. - 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. +- 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. ## Error and behavior rules @@ -38,9 +37,7 @@ Use this file when changing `src/public/`, `src/private/`, or PowerShell build/r - Use 4 spaces per indentation level. - Indent block contents one level inside `function`, `if`, `switch`, `foreach`, `for`, `while`, `try`, `catch`, `finally`, `class`, and method bodies. -- When an expression wraps onto the next line, indent the continuation line one extra level instead of trying to align - it - visually to a previous token column. +- When an expression wraps onto the next line, indent the continuation line one extra level instead of trying to align it visually to a previous token column. ### Spacing @@ -56,8 +53,7 @@ Use this file when changing `src/public/`, `src/private/`, or PowerShell build/r ### Wrapping and braces -- Use same-line opening braces for functions, control statements, `try` / `catch` / `finally`, `switch` labels, classes, - and methods. +- Use same-line opening braces for functions, control statements, `try` / `catch` / `finally`, `switch` labels, classes, and methods. - Keep `elseif`, `else`, `catch`, and `finally` on the same line as the preceding closing brace. - Keep closing braces on their own line. - Prefer multi-line `param(...)`, hashtables, and long argument sets over overly long single lines. diff --git a/.github/instructions/release-policy.instructions.md b/.github/instructions/release-policy.instructions.md index ce61fa22..81427c89 100644 --- a/.github/instructions/release-policy.instructions.md +++ b/.github/instructions/release-policy.instructions.md @@ -6,8 +6,7 @@ applyTo: "CHANGELOG.md,RELEASE_NOTE.md,project.json,.github/workflows/Publish.ym ## Scope -Use this file when changing versioning, changelog handling, package metadata, publish workflows, or GitHub release -automation. +Use this file when changing versioning, changelog handling, package metadata, publish workflows, or GitHub release automation. ## Versioning rules @@ -17,8 +16,7 @@ automation. - Keep `## [Unreleased]` valid and readable. - Use only the official Keep a Changelog section types in both files: `Added`, `Changed`, `Deprecated`, `Removed`, `Fixed`, and `Security`. -- Do not add custom section headings such as `Documentation`; place documentation-related release notes under the - official type that best matches the real change. +- Do not add custom section headings such as `Documentation`; place documentation-related release notes under the official type that best matches the real change. - If `RELEASE_NOTE.md` has no public API or workflow changes under `## [Unreleased]`, keep the exact placeholder under `### Added`: `No public API or workflow changes in this release. Internal maintenance only.` - If `RELEASE_NOTE.md` has real release-note entries, do not keep that placeholder. diff --git a/.github/instructions/testing-policy.instructions.md b/.github/instructions/testing-policy.instructions.md index f93172d1..73a55c56 100644 --- a/.github/instructions/testing-policy.instructions.md +++ b/.github/instructions/testing-policy.instructions.md @@ -26,8 +26,7 @@ Use this file when changing production code, tests, coverage behavior, or CI tes - 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. -- If CodeScene flags coverage or duplication, fix the underlying test design instead of suppressing the warning - casually. +- If CodeScene flags coverage or duplication, fix the underlying test design instead of suppressing the warning casually. ## Common pitfalls diff --git a/.github/prompts/design-change.prompt.md b/.github/prompts/design-change.prompt.md index a2441473..7f5b373c 100644 --- a/.github/prompts/design-change.prompt.md +++ b/.github/prompts/design-change.prompt.md @@ -1,13 +1,10 @@ # Design a NovaModuleTools change -Use this prompt with `architect.agent.md` when a change still needs analysis, scoping, and issue drafting before anyone -starts editing files. +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. +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. -Scope is not final until the user confirms it. That includes anything you think should be treated as out of scope, -deferred, split into follow-up work, or excluded from the first implementation pass. +Scope is not final until the user confirms it. That includes anything you think should be treated as out of scope, deferred, split into follow-up work, or excluded from the first implementation pass. ## Required inputs @@ -17,32 +14,23 @@ deferred, split into follow-up work, or excluded from the first implementation p ## Required process -1. Clarify the real problem first. Ask focused follow-up questions when scope, public-surface impact, ownership, or - rollout direction is unclear. +1. Clarify the real problem first. Ask focused follow-up questions when scope, public-surface impact, ownership, or rollout direction is unclear. 2. Read `README.md`, `CONTRIBUTING.md`, `.github/copilot-instructions.md`, the relevant `.github/instructions/*.instructions.md` files, and the most relevant skill definitions under `.github/skills/*/SKILL.md`. -3. Inspect the affected public command, private helper domain, tests, docs, workflows, or release files without editing - them. -4. Decide whether the request affects public cmdlets, `% nova` CLI behavior, `project.json`, CI/workflows, command - help, website docs, `CHANGELOG.md`, or `RELEASE_NOTE.md`. -5. Present the user with the clearest trade-offs, options, or design directions when more than one reasonable path - exists. -6. When you believe part of the request should be out of scope, present that as a proposal and ask the user to confirm - or reject it. Do not silently narrow the task. -7. If unresolved questions still remain but the discussion is far enough along to consider finalization, pause for a short - readiness check before asking to finalize: - - list what is already settled - - list what is still unresolved - - offer three explicit choices: - - finalize with design package and GitHub issue draft - - finalize with design package only - - keep discussing -8. Keep the conversation interactive until the user explicitly confirms the scope is correct and says the task is clear - enough to finalize, or until you explicitly ask whether you should now draft the final output and the user chooses one - of those options. -9. Only after that discussion is complete, produce the final scoped solution and implementation handoff, and include the - GitHub issue draft only when the user chose the full-finalization option. +3. Inspect the affected public command, private helper domain, tests, docs, workflows, or release files without editing them. +4. Decide whether the request affects public cmdlets, `% nova` CLI behavior, `project.json`, CI/workflows, command help, website docs, `CHANGELOG.md`, or `RELEASE_NOTE.md`. +5. Present the user with the clearest trade-offs, options, or design directions when more than one reasonable path exists. +6. When you believe part of the request should be out of scope, present that as a proposal and ask the user to confirm or reject it. Do not silently narrow the task. +7. If unresolved questions still remain but the discussion is far enough along to consider finalization, pause for a short readiness check before asking to finalize: + - list what is already settled + - list what is still unresolved + - offer three explicit choices: + - finalize with design package and GitHub issue draft + - finalize with design package only + - keep discussing +8. Keep the conversation interactive until the user explicitly confirms the scope is correct and says the task is clear enough to finalize, or until you explicitly ask whether you should now draft the final output and the user chooses one of those options. +9. Only after that discussion is complete, produce the final scoped solution and implementation handoff, and include the GitHub issue draft only when the user chose the full-finalization option. 10. Do not edit repository files unless the user explicitly switches from design to implementation. ## Discussion-phase output @@ -57,16 +45,15 @@ Use the first response and follow-up design turns to drive a conversation, not t - proposed scope and out-of-scope boundaries clearly marked as proposals until the user confirms them - when unresolved items remain, a readiness summary before any finalization question so the user knows what is still open -Do not produce the full final design package in the first response unless the user explicitly asks for it. -Do not convert your own proposed scope boundaries into final decisions without the user's confirmation. +Do not produce the full final design package in the first response unless the user explicitly asks for it. Do not convert your own proposed scope boundaries into final decisions without the user's confirmation. ## Finalization output If the user chooses **design package and GitHub issue draft**, return: - a short usage note that explains: - - the sections before `GitHub issue draft` are design/handoff notes - - only the `GitHub issue draft` section is paste-ready GitHub text + - the sections before `GitHub issue draft` are design/handoff notes + - only the `GitHub issue draft` section is paste-ready GitHub text - Problem - Why it matters - Scope @@ -103,14 +90,9 @@ In design-package-only mode: - 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`). +- 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`). - 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. +- 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. - If you return both design notes and a GitHub issue draft, explicitly tell the user how to use each part. -- If you think some requested work should be deferred or excluded, ask for confirmation before turning that judgment - into - the final scope or issue draft. +- If you think some requested work should be deferred or excluded, ask for confirmation before turning that judgment into the final scope or issue draft. diff --git a/.github/prompts/implement-issue.prompt.md b/.github/prompts/implement-issue.prompt.md index 84f45fef..b6a915c3 100644 --- a/.github/prompts/implement-issue.prompt.md +++ b/.github/prompts/implement-issue.prompt.md @@ -18,10 +18,8 @@ Implement the issue in the NovaModuleTools repository using the repository-local `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. +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`). @@ -31,8 +29,7 @@ Implement the issue in the NovaModuleTools repository using the repository-local - Keep PowerShell cmdlet UX and `nova` CLI UX distinct. - Do not silently bypass warnings or release safeguards. - Prefer reuse of existing helpers and test-support files over duplication. -- Follow the `markdown-authoring` skill (`.github/skills/markdown-authoring/SKILL.md`) when the issue summary or final - handoff is intended to be pasted as Markdown. +- Follow the `markdown-authoring` skill (`.github/skills/markdown-authoring/SKILL.md`) when the issue summary or final handoff is intended to be pasted as Markdown. - Commit message suggestions must: - be in English - use Conventional Commit format diff --git a/.github/prompts/markdown.prompt.md b/.github/prompts/markdown.prompt.md index 036f565b..58b92a35 100644 --- a/.github/prompts/markdown.prompt.md +++ b/.github/prompts/markdown.prompt.md @@ -12,9 +12,7 @@ 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. +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 @@ -27,8 +25,7 @@ Inside the wrapped block: ## Why this wrapper is required -Using `~~~` for the outer wrapper keeps copy-paste output stable when the Markdown itself contains triple-backtick code -blocks. +Using `~~~` for the outer wrapper keeps copy-paste output stable when the Markdown itself contains triple-backtick code blocks. ## Do not diff --git a/.github/prompts/prepare-release.prompt.md b/.github/prompts/prepare-release.prompt.md index 70751e30..0fb297b0 100644 --- a/.github/prompts/prepare-release.prompt.md +++ b/.github/prompts/prepare-release.prompt.md @@ -11,12 +11,11 @@ Prepare release-related changes in NovaModuleTools without publishing or tagging 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`. - - Do not create custom headings such as `Documentation`; place documentation-related release notes under the official - type that best matches the actual impact. + - 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 + - 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. + - 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`. @@ -29,8 +28,7 @@ Prepare release-related changes in NovaModuleTools without publishing or tagging - Do not create tags. - Do not push release commits. - 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. +- 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`). diff --git a/.github/prompts/review-change.prompt.md b/.github/prompts/review-change.prompt.md index 2e4be2ce..38418c31 100644 --- a/.github/prompts/review-change.prompt.md +++ b/.github/prompts/review-change.prompt.md @@ -18,5 +18,4 @@ Review a NovaModuleTools change set with emphasis on correctness, maintainabilit - Watch for CLI vs PowerShell wording drift. - Watch for CodeScene maintainability regressions in tests. - Treat publish/release automation edits as high-risk even when the diff is small. -- Follow the `markdown-authoring` skill (`.github/skills/markdown-authoring/SKILL.md`) when the review output is - intended to be pasted as Markdown. +- Follow the `markdown-authoring` skill (`.github/skills/markdown-authoring/SKILL.md`) when the review output is intended to be pasted as Markdown. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 7ab72256..0adae173 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -25,8 +25,7 @@ ## Review guidance - Highlight the main code path or workflow reviewers should start with. -- Call out the primary files or folders changed (for example `src/public/`, `src/private/cli/`, `scripts/build/ci/`, - `.github/workflows/`, `docs/`, or `src/resources/example/`). +- Call out the primary files or folders changed (for example `src/public/`, `src/private/cli/`, `scripts/build/ci/`, `.github/workflows/`, `docs/`, or `src/resources/example/`). - Call out any trade-offs, follow-up work, or known limitations. ## Validation @@ -35,9 +34,7 @@ - [ ] `Test-NovaBuild` - [ ] `./scripts/build/Invoke-ScriptAnalyzerCI.ps1` - [ ] `./scripts/build/ci/Invoke-NovaModuleToolsCI.ps1` -- [ ] Targeted Nova workflow validated (`% nova build`, `% nova test`, `% nova merge`, `% nova deploy`, - `% nova publish`, - `% nova release`, `% nova update`, `% nova notification`, or `% nova init` as relevant) +- [ ] Targeted Nova workflow validated (`% nova build`, `% nova test`, `% nova merge`, `% nova deploy`, `% nova publish`, `% nova release`, `% nova update`, `% nova notification`, or `% nova init` as relevant) - [ ] Docs/example only; executable validation not needed Validation notes: @@ -53,12 +50,10 @@ If package/upload/release behavior changed, note the exact scenario you exercise - [ ] `README.md` reviewed and updated if contributor workflow, architecture, CI, release, or automation changed - [ ] `CONTRIBUTING.md` reviewed and updated if contribution expectations or review guidance changed - [ ] `CHANGELOG.md` reviewed and updated if the change matters to users, maintainers, or contributors -- [ ] `RELEASE_NOTE.md` reviewed and updated if the change affects public cmdlet usage, CLI usage, configuration - semantics, or migration expectations +- [ ] `RELEASE_NOTE.md` reviewed and updated if the change affects public cmdlet usage, CLI usage, configuration semantics, or migration expectations - [ ] `docs/NovaModuleTools/en-US/` help updated if a public command or CLI behavior changed - [ ] `docs/*.html` updated if end-user workflows or examples changed -- [ ] `src/resources/example/` reviewed and updated if the real-world project layout, package model, or upload workflow - changed +- [ ] `src/resources/example/` reviewed and updated if the real-world project layout, package model, or upload workflow changed - [ ] No documentation, changelog, release-note, or example updates were needed ## Maintainability, compatibility, and risk diff --git a/.github/skills/codescene-quality/SKILL.md b/.github/skills/codescene-quality/SKILL.md index 309aedad..a16ab366 100644 --- a/.github/skills/codescene-quality/SKILL.md +++ b/.github/skills/codescene-quality/SKILL.md @@ -12,8 +12,7 @@ Use this skill when CodeScene reports low Code Health, duplication, or changed-c Use the narrower sibling skills when the task is more specific: - Use `/guiding-refactoring-with-code-health` when refactoring an unhealthy file and choosing small structural steps. -- Use `/safeguarding-ai-generated-code` when AI-touched changes need Code Health gates before commit, handoff, or PR - readiness. +- Use `/safeguarding-ai-generated-code` when AI-touched changes need Code Health gates before commit, handoff, or PR readiness. ## Relevant files and tools @@ -29,8 +28,7 @@ Use the narrower sibling skills when the task is more specific: - Treat Code Health as the repository's authoritative maintainability signal. - Aim for Code Health `10.0` on touched files, not merely "good enough." - Treat CodeScene findings as actionable maintainability signals. -- If CodeScene tooling is unavailable locally, continue with the normal repository validation flow and continue silently; - pull requests and CI remain the effective CodeScene gate. +- If CodeScene tooling is unavailable locally, continue with the normal repository validation flow and continue silently; pull requests and CI remain the effective CodeScene gate. - Fix duplicated test structure by extracting or parameterizing setup. - Add the smallest test that covers the missing changed-code branch. - Prefer incremental refactors over large rewrites. diff --git a/.github/skills/docs-site-html/SKILL.md b/.github/skills/docs-site-html/SKILL.md index a6da61e3..9c3b32a5 100644 --- a/.github/skills/docs-site-html/SKILL.md +++ b/.github/skills/docs-site-html/SKILL.md @@ -7,8 +7,7 @@ description: Guidance for NovaModuleTools website documentation so docs/*.html s ## When to use -Use this skill when changing `docs/*.html`, end-user examples, installation guidance, or any documentation that appears -on the NovaModuleTools website. +Use this skill when changing `docs/*.html`, end-user examples, installation guidance, or any documentation that appears on the NovaModuleTools website. ## Relevant files diff --git a/.github/skills/github-actions/SKILL.md b/.github/skills/github-actions/SKILL.md index ed759aec..addb10bf 100644 --- a/.github/skills/github-actions/SKILL.md +++ b/.github/skills/github-actions/SKILL.md @@ -7,8 +7,7 @@ description: Guidance for changing NovaModuleTools GitHub Actions workflows, CI ## When to use -Use this skill when changing CI workflows, artifact handling, CodeScene coverage flow, publish automation, or reusable -actions under `.github/actions/`. +Use this skill when changing CI workflows, artifact handling, CodeScene coverage flow, publish automation, or reusable actions under `.github/actions/`. ## Relevant files diff --git a/.github/skills/guiding-refactoring-with-code-health/SKILL.md b/.github/skills/guiding-refactoring-with-code-health/SKILL.md index bfc793f9..4c6b5d50 100644 --- a/.github/skills/guiding-refactoring-with-code-health/SKILL.md +++ b/.github/skills/guiding-refactoring-with-code-health/SKILL.md @@ -7,9 +7,7 @@ description: Use when refactoring unhealthy code and needing Code Health finding ## Overview -Use Code Health as the control signal for refactoring. The agent should first understand why a file is hard to work -with, establish a measurable baseline, then improve it in small structural steps and verify that each step helped. The -goal is not just cleaner code, but code that is easier for both humans and agents to understand and modify safely. +Use Code Health as the control signal for refactoring. The agent should first understand why a file is hard to work with, establish a measurable baseline, then improve it in small structural steps and verify that each step helped. The goal is not just cleaner code, but code that is easier for both humans and agents to understand and modify safely. ## When to use @@ -17,8 +15,7 @@ goal is not just cleaner code, but code that is easier for both humans and agent - The user asks for refactoring help and wants an objective way to measure progress. - A safeguard or review points to complexity, size, low cohesion, or deep nesting. -Do not use this skill when the task is to rank project-wide priorities. Use CodeScene's project-level debt and hotspot -tools instead. +Do not use this skill when the task is to rank project-wide priorities. Use CodeScene's project-level debt and hotspot tools instead. ## Quick reference @@ -29,14 +26,11 @@ tools instead. 1. Run `code_health_review` on the target file. 2. Record the current `code_health_score` so the refactoring starts from a measurable baseline. -3. Identify the highest-leverage structural problems, such as excessive responsibilities, deep nesting, low cohesion, or - hard-to-follow control flow. +3. Identify the highest-leverage structural problems, such as excessive responsibilities, deep nesting, low cohesion, or hard-to-follow control flow. 4. Propose 3 to 5 small structural refactor steps, not a single rewrite. 5. After each meaningful step, re-run `code_health_review` to see whether the targeted structural problems were reduced. 6. Use `code_health_score` as the compact checkpoint to confirm directional improvement across iterations. -7. Stop only when the targeted structural issues are substantially reduced and the score has measurably improved, or - when - the user explicitly accepts a partial uplift. +7. Stop only when the targeted structural issues are substantially reduced and the score has measurably improved, or when the user explicitly accepts a partial uplift. ## Common mistakes diff --git a/.github/skills/markdown-authoring/SKILL.md b/.github/skills/markdown-authoring/SKILL.md index 8d98e5e9..e8709f9e 100644 --- a/.github/skills/markdown-authoring/SKILL.md +++ b/.github/skills/markdown-authoring/SKILL.md @@ -7,8 +7,7 @@ description: Guidance for producing valid, copy-safe Markdown files and UI-ready ## When to use -Use this skill when producing Markdown files in the repository or Markdown output that must be copied directly from the -UI, such as release summaries, PR-template-shaped text, contributor docs, or reusable prompt output. +Use this skill when producing Markdown files in the repository or Markdown output that must be copied directly from the UI, such as release summaries, PR-template-shaped text, contributor docs, or reusable prompt output. ## Relevant files @@ -33,8 +32,7 @@ UI, such as release summaries, PR-template-shaped text, contributor docs, or reu ## Copy-safe fence rules -- When the entire response must be wrapped, start with a line containing exactly `~~~` and end with a line containing - exactly `~~~`. +- When the entire response must be wrapped, start with a line containing exactly `~~~` and end with a line containing exactly `~~~`. - Do not place prose before or after that outer wrapper. - Inside the wrapped block, use normal Markdown. - For inner code examples, use triple backticks and include a language when helpful. diff --git a/.github/skills/powershell-module-development/SKILL.md b/.github/skills/powershell-module-development/SKILL.md index 70c3266b..12b066a1 100644 --- a/.github/skills/powershell-module-development/SKILL.md +++ b/.github/skills/powershell-module-development/SKILL.md @@ -7,8 +7,7 @@ description: Guidance for changing NovaModuleTools public commands, private help ## When to use -Use this skill when changing public commands, private helpers, CLI routing support, packaging behavior, or project.json -resolution. +Use this skill when changing public commands, private helpers, CLI routing support, packaging behavior, or project.json resolution. ## Relevant files @@ -28,8 +27,7 @@ resolution. - Put implementation detail in the correct private domain folder. - Preserve native PowerShell semantics and Nova naming patterns. - 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 the repository's PowerShell style rules: 4-space indentation, same-line opening braces, restrained blank lines, full cmdlet names, and readable operator spacing. ## Common pitfalls diff --git a/.github/skills/release-and-changelog/SKILL.md b/.github/skills/release-and-changelog/SKILL.md index 9ccf0563..266bd5d9 100644 --- a/.github/skills/release-and-changelog/SKILL.md +++ b/.github/skills/release-and-changelog/SKILL.md @@ -7,8 +7,7 @@ description: Guidance for NovaModuleTools semantic versioning, changelog handlin ## When to use -Use this skill when working on semantic versioning, release automation, package metadata, prerelease flow, -`CHANGELOG.md`, or `RELEASE_NOTE.md`. +Use this skill when working on semantic versioning, release automation, package metadata, prerelease flow, `CHANGELOG.md`, or `RELEASE_NOTE.md`. ## Relevant files @@ -26,12 +25,9 @@ Use this skill when working on semantic versioning, release automation, package - Keep unreleased entries readable and outcome-focused. - Keep `CHANGELOG.md` exhaustive and keep `RELEASE_NOTE.md` limited to interface-facing change summaries. -- Use only the official Keep a Changelog section types: `Added`, `Changed`, `Deprecated`, `Removed`, `Fixed`, and - `Security`. -- Do not create custom changelog headings such as `Documentation`; place documentation-related release notes under the - official type that best matches the actual release impact. -- If `RELEASE_NOTE.md` has no public API or workflow changes under `## [Unreleased]`, keep the exact placeholder under - `### Added`: `No public API or workflow changes in this release. Internal maintenance only.` +- Use only the official Keep a Changelog section types: `Added`, `Changed`, `Deprecated`, `Removed`, `Fixed`, and `Security`. +- Do not create custom changelog headings such as `Documentation`; place documentation-related release notes under the official type that best matches the actual release impact. +- If `RELEASE_NOTE.md` has no public API or workflow changes under `## [Unreleased]`, keep the exact placeholder under `### Added`: `No public API or workflow changes in this release. Internal maintenance only.` - If `RELEASE_NOTE.md` has real release-note entries, remove that placeholder. - Keep `RELEASE_NOTE.md` free of compare-link footer URLs. - Use `Added`, `Changed`, `Deprecated`, `Removed`, `Fixed`, and `Security` intentionally. diff --git a/.github/skills/safeguarding-ai-generated-code/SKILL.md b/.github/skills/safeguarding-ai-generated-code/SKILL.md index a150f20b..0d7d9ecd 100644 --- a/.github/skills/safeguarding-ai-generated-code/SKILL.md +++ b/.github/skills/safeguarding-ai-generated-code/SKILL.md @@ -7,9 +7,7 @@ description: Use when AI-generated or AI-modified changes need a Code Health gat ## Overview -Use Code Health safeguards before declaring AI-touched code ready. The goal is to catch maintainability regressions -early -and prevent agents from normalizing technical debt. +Use Code Health safeguards before declaring AI-touched code ready. The goal is to catch maintainability regressions early and prevent agents from normalizing technical debt. ## When to use @@ -28,16 +26,11 @@ Do not use this skill for broad refactoring discovery or project-level prioritiz ## Implementation 1. After each AI modification to a file, run `code_health_review` on that file. -2. If the review reports maintainability problems or regression risk, refactor the file in small steps and review it - again. -3. When local CodeScene tooling is available, run `pre_commit_code_health_safeguard` before commit-oriented - recommendations as a broader gate across staged or modified files. -4. When local CodeScene tooling is available, run `analyze_change_set` before PR-oriented recommendations as a final - branch-level gate. -5. If local CodeScene tooling is unavailable, continue with the normal repository validation flow and continue silently; - pull requests and CI remain the effective CodeScene gate. -6. If either later gate reports a regression, inspect the affected files with `code_health_review` and keep iterating - until the issue is removed or the user explicitly accepts the risk. +2. If the review reports maintainability problems or regression risk, refactor the file in small steps and review it again. +3. When local CodeScene tooling is available, run `pre_commit_code_health_safeguard` before commit-oriented recommendations as a broader gate across staged or modified files. +4. When local CodeScene tooling is available, run `analyze_change_set` before PR-oriented recommendations as a final branch-level gate. +5. If local CodeScene tooling is unavailable, continue with the normal repository validation flow and continue silently; pull requests and CI remain the effective CodeScene gate. +6. If either later gate reports a regression, inspect the affected files with `code_health_review` and keep iterating until the issue is removed or the user explicitly accepts the risk. ## Common mistakes diff --git a/CHANGELOG.md b/CHANGELOG.md index b148b562..655328a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,8 @@ # 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 **PREVIEW / 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). +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] @@ -12,9 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### 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, and clarifies how to use design notes versus the paste-ready - GitHub issue draft. +- 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 @@ -30,58 +26,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 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. - - Adds a discussion-first architect flow so `architect.agent.md` together with `design-change.prompt.md` now keeps - the early phase conversational, asks clarifying questions, presents design directions, and only finalizes the - scoped solution and GitHub issue draft after the discussion is complete. - - Requires architect/design flows to treat out-of-scope cuts and deferred work as proposals that must be confirmed by - the user before they become part of the final scope or issue draft. - - Includes branch-aware Conventional Commit guidance that derives ticket references from `$GIT_BRANCH_NAME` and - keeps - commit suggestions concise and English-only. - - Treats CodeScene Code Health as authoritative, requires safeguard checks before commit/PR readiness, and carries - the - repository's trailing-newline formatting rule into the agent flow. - - Keeps local agentic work moving silently when CodeScene tooling is unavailable on a contributor machine, while - pull requests and CI remain the effective CodeScene gate. - - Adds repository-local PowerShell style guidance for indentation, spacing, braces/wrapping, and blank-line usage. - - Adds a dedicated docs-site agent and documentation-separation guidance so website docs keep a clear CLI-vs-cmdlet - split. - - Makes the repository agent files valid Copilot custom-agent profiles by adding the required YAML frontmatter so - they load correctly in `/agent`. - - Makes the release-manager flow own PR-template-based release summaries and removes the old standalone - PR-description - prompt. - - Adds reusable markdown-authoring guidance so copy-ready Markdown output can use safe outer `~~~` fences without - breaking inner triple-backtick code blocks. - - Aligns the repository guidance with actual Copilot CLI formats by using `.github/copilot-instructions.md`, - `.github/instructions/*.instructions.md`, and `.github/skills//SKILL.md`, while keeping - `.github/prompts/*.prompt.md` as explicit prompt templates. - - Makes the relevant agent and prompt outputs explicitly point to the `markdown-authoring` skill when they produce - Markdown summaries or UI-ready Markdown text. - - Adds focused CodeScene skills for refactoring with Code Health and for safeguarding AI-touched code before commit - or - PR readiness, instead of overloading the broader `codescene-quality` skill. + - Aligns the agent guidance with Nova's existing PowerShell, Pester, CodeScene, GitHub Actions, and release conventions. + - Adds a discussion-first architect flow so `architect.agent.md` together with `design-change.prompt.md` now keeps the early phase conversational, asks clarifying questions, presents design directions, and only finalizes the scoped solution and GitHub issue draft after the discussion is complete. + - Requires architect/design flows to treat out-of-scope cuts and deferred work as proposals that must be confirmed by the user before they become part of the final scope or issue draft. + - Includes branch-aware Conventional Commit guidance that derives ticket references from `$GIT_BRANCH_NAME` and keeps commit suggestions concise and English-only. + - Treats CodeScene Code Health as authoritative, requires safeguard checks before commit/PR readiness, and carries the repository's trailing-newline formatting rule into the agent flow. + - Keeps local agentic work moving silently when CodeScene tooling is unavailable on a contributor machine, while pull requests and CI remain the effective CodeScene gate. + - Adds repository-local PowerShell style guidance for indentation, spacing, braces/wrapping, and blank-line usage. + - Adds a dedicated docs-site agent and documentation-separation guidance so website docs keep a clear CLI-vs-cmdlet split. + - Makes the repository agent files valid Copilot custom-agent profiles by adding the required YAML frontmatter so they load correctly in `/agent`. + - Makes the release-manager flow own PR-template-based release summaries and removes the old standalone PR-description prompt. + - Adds reusable markdown-authoring guidance so copy-ready Markdown output can use safe outer `~~~` fences without breaking inner triple-backtick code blocks. + - Aligns the repository guidance with actual Copilot CLI formats by using `.github/copilot-instructions.md`, + `.github/instructions/*.instructions.md`, and `.github/skills//SKILL.md`, while keeping + `.github/prompts/*.prompt.md` as explicit prompt templates. + - Makes the relevant agent and prompt outputs explicitly point to the `markdown-authoring` skill when they produce Markdown summaries or UI-ready Markdown text. + - Adds focused CodeScene skills for refactoring with Code Health and for safeguarding AI-touched code before commit or PR readiness, instead of overloading the broader `codescene-quality` skill. - Added a root-level `RELEASE_NOTE.md` that is separate from `CHANGELOG.md`. - `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. + - `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. ### 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. + - `"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. - Release-history handling now uses a separate root-level `RELEASE_NOTE.md`. - `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. + - `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. ### Deprecated @@ -91,14 +66,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### 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. + - `Tests.yml` no longer uploads CI coverage results to Codecov. + - The standalone `codecov.yml` configuration has been removed from the repository. ### 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. + explicitly, while the published `NovaModuleTools` manifest continues to declare that dependency for installed workflows. ## [2.3.1] - 2026-05-08 @@ -112,8 +86,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### 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. + - `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. @@ -121,15 +94,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 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. + - 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. ## [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 @@ -137,307 +107,302 @@ their own `Pester` installation step. The regression was fixed in `2.3.0`. - 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`. - - 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. +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. + - Running the bump without `-Preview` still finalizes or advances prerelease versions by Nova's normal semantic rules. ### 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. +- `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 -- 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 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 `--what-if`. - The GitHub Pages guide now keeps the PowerShell `-WhatIf` wording only in the PowerShell view and shows `--what-if` in the command-line view. - Add a PowerShell installed-tool version view through `Get-NovaProjectInfo -Installed`. - - PowerShell now exposes the installed `NovaModuleTools` module name and version directly instead of requiring the - launcher-only `% nova --version` path. + - PowerShell now exposes the installed `NovaModuleTools` module name and version directly instead of requiring the launcher-only `% nova --version` path. - `Get-Help Get-NovaProjectInfo` now documents both the project-version and installed-tool-version views. - Stop build-driven workflows when a `src/public` file contains zero or multiple top-level functions. - This prevents helper functions from being exported accidentally just because they live in a public file. - - `Invoke-NovaBuild`, `Test-NovaBuild -Build`, packaging, publishing, and release flows now surface the warning - consistently. - - PowerShell supports `-OverrideWarning`, and the `nova` CLI supports `--override-warning` / `-o` when maintainers - intentionally want to continue past the warning. -- Fix `Invoke-NovaBuild` help discovery so it only scans `docs//` for PlatyPS - markdown. + - `Invoke-NovaBuild`, `Test-NovaBuild -Build`, packaging, publishing, and release flows now surface the warning consistently. + - PowerShell supports `-OverrideWarning`, and the `nova` CLI supports `--override-warning` / `-o` when maintainers intentionally want to continue past the warning. +- Fix `Invoke-NovaBuild` help discovery so it only scans `docs//` for PlatyPS markdown. - Regular markdown elsewhere under `docs/` no longer breaks the help-generation step. - - When PlatyPS export does not create the expected help folder, Nova now raises a stable documentation error instead - of a raw rename-path failure. + - When PlatyPS export does not create the expected help folder, Nova now raises a stable documentation error instead of a raw rename-path failure. - Fix the repository `run.ps1` quality loop after the CI installer refactor introduced new ScriptAnalyzer warnings. - The internal CI installer helper now follows ScriptAnalyzer naming and `ShouldProcess` expectations. - `run.ps1` no longer stops in the analyzer step because of those helper warnings. - Fix interactive `nova init` / `nova init -e` scaffold validation so invalid answers retry immediately at the prompt. - 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. + - Standard and example scaffold flows now share the same retry-first validation behavior through the common prompt path. ## [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 `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` files. - Add native `-WhatIf` and `-Confirm` support across mutating Nova commands, including GNU-style routed CLI support for `--verbose`/`-v`, `--what-if`/`-w`, and `--confirm`/`-c` on `build`, `test`, `bump`, `publish`, and `release`. - Routed CLI confirmation now stays inside the `nova` experience instead of exposing PowerShell's `Suspend` prompt. - - Entering `S` during CLI confirmation now cancels safely, returns a non-zero exit code, and returns directly to the - original shell. + - Entering `S` during CLI confirmation now cancels safely, returns a non-zero exit code, and returns directly to the original shell. - Direct PowerShell cmdlets such as `Deploy-NovaPackage`, `Publish-NovaModule`, and `Update-NovaModuleVersion` continue to use native PowerShell confirmation semantics. - Non-confirmable `nova` routes such as `info`, `version`, `--help`, `--version`, and `init` now reject `--confirm`/`-c` consistently instead of silently accepting a PowerShell-style confirmation concept. -- Add `Update-NovaModuleTool` (with `Update-NovaModuleTools` as a compatibility alias) and `% nova update` for - self-updating the installed module. +- Add `Update-NovaModuleTool` (with `Update-NovaModuleTools` as a compatibility alias) and `% nova update` for self-updating the installed module. - Supports `Set-NovaUpdateNotificationPreference` / `Get-NovaUpdateNotificationPreference` for PowerShell usage. - - Supports `% nova notification`, `% nova notification --disable`/`-d`, and `% nova notification --enable`/`-e` for - CLI - usage. + - Supports `% nova notification`, `% nova notification --disable`/`-d`, and `% nova notification --enable`/`-e` for CLI usage. - Uses the stored prerelease update preference to decide whether prerelease self-updates are eligible. - Requires explicit confirmation before a prerelease self-update proceeds. -- Add `% nova version --installed` / `% nova version -i` so users can compare the locally installed version of the - current project/module with the current project version from `project.json`, while keeping `% nova --version` / +- Add `% nova version --installed` / `% nova version -i` so users can compare the locally installed version of the current project/module with the current project version from `project.json`, while keeping `% nova --version` / `% nova -v` dedicated to the installed NovaModuleTools version. - Add build-before-test support to the test workflow so `Test-NovaBuild -Build`, `% nova test --build`, and `% nova test -b` rebuild the project before running Pester. -- Add an opt-in `-Preview` mode to `Update-NovaModuleVersion` / GNU-style `% nova bump --preview` / `% nova bump -p` for - explicit preview iteration. +- Add an opt-in `-Preview` mode to `Update-NovaModuleVersion` / GNU-style `% nova bump --preview` / `% nova bump -p` for explicit preview iteration. - Stable versions still use the normal semantic bump target first, then append `-preview`. - - Existing prerelease versions now stay on the same semantic core and preserve the current prerelease stem while - appending or incrementing trailing digits, for example `preview -> preview01`, `preview09 -> preview10`, + - Existing prerelease versions now stay on the same semantic core and preserve the current prerelease stem while appending or incrementing trailing digits, for example `preview -> preview01`, `preview09 -> preview10`, `rc -> rc01`, `rc1 -> rc2`, `SNAPSHOT -> SNAPSHOT01`, and `SNAPSHOT1 -> SNAPSHOT2`. - Add `New-NovaModulePackage` and `% nova package` so projects can build, test, and package the built module output as a - `.nupkg` artifact by using generic metadata from `project.json`, including repositories whose test runs reload or - remove `NovaModuleTools` before the final package step. + `.nupkg` artifact by using generic metadata from `project.json`, including repositories whose test runs reload or remove `NovaModuleTools` before the final package step. - Package output supports `Package.Types` with case-insensitive `NuGet`, `Zip`, `.nupkg`, and `.zip` values. - Omitting `Package.Types` still defaults packaging to a `.nupkg` artifact. - Selecting both `NuGet` and `Zip` creates both package formats in the configured output directory. - `Package.AddVersionToFileName` can append the top-level project version to a custom `Package.PackageFileName` before the package extension is applied. - - Setting `Package.Latest` to `true` also creates a companion `*.latest.*` artifact for each selected package type - while keeping the normal versioned file. + - Setting `Package.Latest` to `true` also creates a companion `*.latest.*` artifact for each selected package type while keeping the normal versioned file. - Package output uses `Package.OutputDirectory.Path` with `Package.OutputDirectory.Clean` defaulting to `true`. - - Add `Deploy-NovaPackage` and `% nova deploy` for raw HTTP package uploads that stay separate from PowerShell - repository publishing. - - Package upload resolves `-Url`, `Package.RepositoryUrl`, or named `Package.Repositories` targets and can merge - generic headers/auth settings. + - Add `Deploy-NovaPackage` and `% nova deploy` for raw HTTP package uploads that stay separate from PowerShell repository publishing. + - Package upload resolves `-Url`, `Package.RepositoryUrl`, or named `Package.Repositories` targets and can merge generic headers/auth settings. - Package upload now discovers all matching artifacts for the selected package types, including versioned and `latest` files in the configured package output directory. -- Add opt-in skip-test support to the package, publish, and release workflows for CI/CD-oriented delivery paths where - tests already ran earlier in the pipeline. -- Centralize delivery configuration resolution so raw package upload, update notification settings, and PSGallery - publishing now follow one explicit precedence model without surfacing configured secrets in error text. +- Add opt-in skip-test support to the package, publish, and release workflows for CI/CD-oriented delivery paths where tests already ran earlier in the pipeline. +- Centralize delivery configuration resolution so raw package upload, update notification settings, and PSGallery publishing now follow one explicit precedence model without surfacing configured secrets in error text. - Raw upload now resolves command overrides before named repository settings, then package defaults. - - Secret lookup now resolves explicit values before environment-variable indirection, then configured literal - fallbacks. + - Secret lookup now resolves explicit values before environment-variable indirection, then configured literal fallbacks. - Keep CI-oriented publish and bump workflows bound to the freshly built module so follow-up `publish`, `release`, and `bump` steps no longer lose private helpers after module re-imports in the same session. - PowerShell now supports `New-NovaModulePackage -SkipTests`, `Publish-NovaModule -SkipTests`, and `Invoke-NovaRelease -SkipTests`. - The `nova` launcher now supports `--skip-tests` / `-s` on `nova package`, `nova publish`, and `nova release`. - Skip-tests bypasses `Test-NovaBuild` only; the related build steps still run. -- Add first-class CI activation switches so Nova can re-import the built `dist/` module at the workflow boundaries where - session state matters. +- Add first-class CI activation switches so Nova can re-import the built `dist/` module at the workflow boundaries where session state matters. - PowerShell now supports `Invoke-NovaBuild -ContinuousIntegration`, `Update-NovaModuleVersion -ContinuousIntegration`, `Publish-NovaModule -ContinuousIntegration`, and `Invoke-NovaRelease -ContinuousIntegration`. - - 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. + - 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. - - `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. + `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 + - 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. + - 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. -- Isolate external workflow execution behind smaller internal adapters so git, raw package upload, repository publish, - self-update, settings-file I/O, and CLI environment access have clearer change points and smaller test seams. +- Isolate external workflow execution behind smaller internal adapters so git, raw package upload, repository publish, self-update, settings-file I/O, and CLI environment access have clearer change points and smaller test seams. - `% nova --help` and `% nova -h` now show short CLI help. - `% nova --help ` and `% nova -h ` now show long CLI help. - - Long command help now includes the matching public GitHub Pages guide URL for the selected command, while short help - stays focused on command syntax and options. + - Long command help now includes the matching public GitHub Pages guide URL for the selected command, while short help stays focused on command syntax and options. - CLI help no longer delegates to PowerShell `Get-Help` and now consistently shows CLI option spellings such as `--repository` and `-r`. - **BREAKING CHANGE**: Rename the public Nova scaffold cmdlets. - `New-NovaModule` → `Initialize-NovaModule` - No compatibility aliases are exported for the retired cmdlet names or CLI subcommands. - 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. +- 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 -- **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. + +- **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 -- Fix unsupported `nova` help invocations so they now return Nova's structured CLI validation error instead of a - PowerShell parameter-binding failure. +- 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. - - `New-NovaPackageArtifacts` now accepts an empty metadata list and returns an empty artifact result instead of - failing during parameter binding. -- Fix configuration and validation errors so empty `project.json` files and unsupported `Manifest` keys fail fast with - clear messages. -- Fix semantic-release PSGallery publishing on fresh CI runners by bootstrapping the PSResourceGet repository store - before + - `New-NovaPackageArtifacts` now accepts an empty metadata list and returns an empty artifact result instead of failing during parameter binding. +- Fix configuration and validation errors so empty `project.json` files and unsupported `Manifest` keys fail fast with clear messages. +- 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 + ### 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` + - New public commands: `Get-NovaProjectInfo`, `Invoke-NovaBuild`, `Invoke-NovaCli`, `Invoke-NovaRelease`, `Initialize-NovaModule`, `Publish-NovaModule`, `Test-NovaBuild`, `Update-NovaModuleVersion` - Release orchestration helpers for command routing, version label detection from commits, and publish flow support. - New test coverage in `tests/NovaCommandModel.Tests.ps1` for Nova command routing and release flow behavior. - New GitHub workflow: Dependency Review (`.github/workflows/dependency-review.yml`). - New GitHub workflow: PowerShell code quality (`.github/workflows/powershell.yml`). ### 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 + - `MT` commands and MT-branded command documentation in favor of the Nova command model. ### Fixed + - Resource lookup compatibility in `Get-ResourceFilePath` for source/dist execution contexts. ## [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`. + - `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`. ### 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 + - 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 + ### 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 + - Version upgrade using update-mtmoduleversion now support build tags. Improvements to semver versioning. ## [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 + ## Added -- Now Module manifest includes `AliasesToExport`. This helps loading aliases without explicitly importing modules to - session. + +- 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 + ### 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) + +- 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 + - **BREAKING CHANGE**: Typo corrected: ProjecUri to ProjectUri. Existing projects require manual update. ## [0.0.9] - 2024-07-17 + ### Fixed + - Fixed #7, Invoke build should not through for empty tags ## [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 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. + +- 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 ### Added + - `Test-NovaBuild` now supports including and excluding tags ### Fixed + - Code cleanup ## [0.0.5] - 2024-07-05 + ### Added + - More verbose info during MTModule creation ### 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 + ### 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 + [2.3.0]: https://github.com/stiwicourage/NovaModuleTools/compare/2.2.0...2.3.0 + [2.2.0]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_2.1.0...2.2.0 + [2.1.0]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_2.0.0...Version_2.1.0 + [2.0.0]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_1.9.1...Version_2.0.0 + [1.9.1]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_1.8.0...Version_1.9.1 + [1.8.0]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_1.7.0...Version_1.8.0 + [1.3.0]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_1.2.5-preview...Version_1.3.0 + [1.2.0]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_1.1.4-preview...Version_1.2.0 + [1.1.3]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_1.1.0...Version_1.1.3 + [1.1.0]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_1.0.0...Version_1.1.0 + [1.0.0]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_0.0.9...Version_1.0.0 + [0.0.9]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_0.0.8...Version_0.0.9 + [0.0.7]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_0.0.6...Version_0.0.7 + [0.0.6]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_0.0.5...Version_0.0.6 + [0.0.5]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_0.0.4...Version_0.0.5 + [0.0.4]: https://github.com/stiwicourage/NovaModuleTools/compare/Version_0.0.3...Version_0.0.4 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 9592eeb5..21007e41 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -2,14 +2,11 @@ ## Our Commitment -Terra Nova is an open, community-driven initiative focused on building high-quality software through shared ownership, -strong collaboration, and modern development practices. +Terra Nova is an open, community-driven initiative focused on building high-quality software through shared ownership, strong collaboration, and modern development practices. -We are committed to creating a community that is welcoming, respectful, constructive, and open to everyone, regardless -of background, identity, experience level, or preferred technology stack. +We are committed to creating a community that is welcoming, respectful, constructive, and open to everyone, regardless of background, identity, experience level, or preferred technology stack. -Terra Nova is not defined by a specific language, platform, or framework. It is defined by how we build software -together. +Terra Nova is not defined by a specific language, platform, or framework. It is defined by how we build software together. We want this community to be a place where people can: @@ -64,11 +61,40 @@ The following behavior is not acceptable in the Terra Nova community: Terra Nova is guided by these principles: -- **Clarity over cleverness** -- **Automation over manual processes** -- **Consistency over fragmentation** -- **Quality and pragmatism in balance** -- **Open by default** +- + +* + +*Clarity over cleverness +** + +- + +* + +*Automation over manual processes +** + +- + +* + +*Consistency over fragmentation +** + +- + +* + +*Quality and pragmatism in balance +** + +- + +* + +*Open by default +** We encourage contributions that align with these principles and improve the ecosystem as a whole. @@ -76,8 +102,7 @@ We encourage contributions that align with these principles and improve the ecos Terra Nova is designed to support both speed and freedom without sacrificing responsibility. -We welcome new ideas, including ideas that introduce new directions. When a contribution expands the project in a way -that current maintainers are unsure about or do not wish to own directly, it may still be accepted — with ownership. +We welcome new ideas, including ideas that introduce new directions. When a contribution expands the project in a way that current maintainers are unsure about or do not wish to own directly, it may still be accepted — with ownership. This means: @@ -131,13 +156,11 @@ They may take any action they believe is appropriate in response to unacceptable - temporary restriction from participation - permanent ban from some or all community spaces -Enforcement decisions will be made with the goal of protecting the health, safety, and long-term sustainability of the -community. +Enforcement decisions will be made with the goal of protecting the health, safety, and long-term sustainability of the community. ## Our Standards for Collaboration -Because Terra Nova is built around maintainable, collaborative software development, we expect contributors to support -healthy engineering practices, including when relevant: +Because Terra Nova is built around maintainable, collaborative software development, we expect contributors to support healthy engineering practices, including when relevant: - open discussion of trade-offs - clear, reviewable changes diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3e816e8f..bb86abca 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,9 +1,9 @@ ## Contributing -[![KeepAChangelog](https://img.shields.io/badge/changelog-KeepAChangelog-%23E05735)](https://keepachangelog.ps) + +[![KeepAChangelog](https://img.shields.io/badge/changelog-KeepAChangelog-%23E05735)](https://keepachangelog.ps) [![CodeScene Average Code Health](https://codescene.io/projects/78904/status-badges/average-code-health)](https://codescene.io/projects/78904) -**This repository is intentionally opinionated about maintainability, however, we welcome contributions that align with -our goals. We want to keep the codebase clean, maintainable, and easy to understand for both users and contributors.** +**This repository is intentionally opinionated about maintainability, however, we welcome contributions that align with our goals. We want to keep the codebase clean, maintainable, and easy to understand for both users and contributors.** If you want to contribute, please work in the same style as the project: @@ -12,8 +12,7 @@ If you want to contribute, please work in the same style as the project: `SECURITY.md` instead of a public issue for vulnerability reports. - Keep commits small, reviewable, and easy to understand. - The size of a pull request is not as important as the clarity of its intent and the ease of reviewing it. - - A large pull request that is well-organized in smaller commits with clear messages can be easier to review than a - small pull request that is not well-explained or has unclear intent. + - A large pull request that is well-organized in smaller commits with clear messages can be easier to review than a small pull request that is not well-explained or has unclear intent. - Aim for maintainable code: - short functions - simple branching @@ -29,11 +28,9 @@ Before making larger changes, read the contributor docs in: - [README.md#repository-structure-and-ownership](./README.md#repository-structure-and-ownership) - [README.md#cicd-and-release-automation](./README.md#cicd-and-release-automation) - [.github/copilot-instructions.md](./.github/copilot-instructions.md) -- the relevant files under `.github/agents/`, `.github/skills/`, and `.github/prompts/` when you are using Copilot or - another AI agent to help with repository work +- the relevant files under `.github/agents/`, `.github/skills/`, and `.github/prompts/` when you are using Copilot or another AI agent to help with repository work -GitHub now prefills pull requests with `.github/pull_request_template.md`. -Use it to explain intent clearly, record what you validated, and call out any required documentation or changelog work. +GitHub now prefills pull requests with `.github/pull_request_template.md`. Use it to explain intent clearly, record what you validated, and call out any required documentation or changelog work. Repository-local agentic guidance now lives in `.github/`: @@ -46,12 +43,7 @@ Repository-local agentic guidance now lives in `.github/`: The files in `.github/agents/` are repository-level Copilot custom agent profiles, so they should load in `/agent` 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. +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. @@ -72,15 +64,13 @@ 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 Cobertura 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` -- 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` +- 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: @@ -88,8 +78,7 @@ Please also make sure your contribution includes the right kind of follow-up wor - update help files in `docs/` when a command changes - update `README.md` when repository workflow, architecture, or contributor expectations change - 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 +- 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 Documentation ownership is intentionally split: diff --git a/README.md b/README.md index 7625b9f2..b0370f41 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # NovaModuleTools -[![CodeScene general](https://codescene.io/images/analyzed-by-codescene-badge.svg)](https://codescene.io/projects/78904) + +[![CodeScene general](https://codescene.io/images/analyzed-by-codescene-badge.svg)](https://codescene.io/projects/78904) ![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 evolution of ModuleTools for structured PowerShell module development, repository automation, and maintainable Nova workflows. This README is the single developer-documentation entry point for the repository. @@ -32,9 +32,7 @@ This README is the single developer-documentation entry point for the repository Start here when you work on NovaModuleTools itself: - [CONTRIBUTING.md](./CONTRIBUTING.md) — contribution expectations and review checklist -- [.github/copilot-instructions.md](./.github/copilot-instructions.md) — - repository-local - guidance for Copilot/AI agents and maintainers +- [.github/copilot-instructions.md](./.github/copilot-instructions.md) — repository-local guidance for Copilot/AI agents and maintainers - [Development workflow](#development-workflow) — local setup, build, test, reload, and quality loop - [Repository structure and ownership](#repository-structure-and-ownership) — architecture and folder responsibilities - [CI/CD and release automation](#cicd-and-release-automation) — workflow, release, and publish responsibilities @@ -42,13 +40,10 @@ Start here when you work on NovaModuleTools itself: Suggested reading order: 1. Read [CONTRIBUTING.md](./CONTRIBUTING.md) -2. Read [.github/copilot-instructions.md](./.github/copilot-instructions.md) when you - want - repository-local coding guidance for Copilot/AI-assisted work +2. Read [.github/copilot-instructions.md](./.github/copilot-instructions.md) when you want repository-local coding guidance for Copilot/AI-assisted work 3. Follow [Development workflow](#development-workflow) for local iteration 4. Use [Repository structure and ownership](#repository-structure-and-ownership) when deciding where changes belong -5. Use [CI/CD and release automation](#cicd-and-release-automation) when your change touches workflows, release - automation, or publishing +5. Use [CI/CD and release automation](#cicd-and-release-automation) when your change touches workflows, release automation, or publishing ## Development workflow @@ -60,19 +55,13 @@ 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, not auto-loaded like instructions or skills - `CHANGELOG.md` and `RELEASE_NOTE.md` - exhaustive release history plus interface-focused release summaries -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. +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. -For new or still-fuzzy work, start with `architect.agent.md` together with `design-change.prompt.md`. That pair should -lead with discussion, questions, and design options rather than a finished solution in the first reply. Use -`implement-issue.prompt.md` once the scope, acceptance criteria, and follow-on implementation path are already clear. -If architect proposes that part of the request is out of scope, treat that as a proposal to confirm rather than a final -decision. If unresolved design questions still remain, architect should first summarize what is settled vs unresolved and -then let the user choose between full finalization, a design-package-only handoff, or continued discussion. +For new or still-fuzzy work, start with `architect.agent.md` together with `design-change.prompt.md`. That pair should lead with discussion, questions, and design options rather than a finished solution in the first reply. Use +`implement-issue.prompt.md` once the scope, acceptance criteria, and follow-on implementation path are already clear. If architect proposes that part of the request is out of scope, treat that as a proposal to confirm rather than a final decision. If unresolved design questions still remain, architect should first summarize what is settled vs unresolved and then let the user choose between full finalization, a design-package-only handoff, or continued discussion. ### Prerequisites @@ -97,10 +86,7 @@ PS> Invoke-NovaBuild This creates the built module under `dist/NovaModuleTools/`. -Files under `src/public/` are expected to contain exactly one top-level function each. Nova now stops build-driven -workflows when a public file contains zero or multiple top-level functions, because that layout can accidentally export -helpers as part of the public API surface. Use `-OverrideWarning` / `--override-warning` / `-o` only when you -intentionally want to bypass that guard for a specific build, test-build, package, publish, or release run. +Files under `src/public/` are expected to contain exactly one top-level function each. Nova now stops build-driven workflows when a public file contains zero or multiple top-level functions, because that layout can accidentally export helpers as part of the public API surface. Use `-OverrideWarning` / `--override-warning` / `-o` only when you intentionally want to bypass that guard for a specific build, test-build, package, publish, or release run. When you want the test workflow to rebuild first, use: @@ -127,8 +113,7 @@ PS> Update-NovaModuleTools # alias % nova update ``` -Use `% nova notification` when you want the CLI-oriented workflow and the `Set-` / `Get-` cmdlets when you want the -PowerShell function form in scripts. +Use `% nova notification` when you want the CLI-oriented workflow and the `Set-` / `Get-` cmdlets when you want the PowerShell function form in scripts. Update notification preferences use one shared settings location: @@ -136,17 +121,9 @@ Update notification preferences use one shared settings location: - macOS/Linux with `XDG_CONFIG_HOME`: `$XDG_CONFIG_HOME/NovaModuleTools/settings.json` - macOS/Linux fallback: `~/.config/NovaModuleTools/settings.json` -`Update-NovaModuleTool` (and its `Update-NovaModuleTools` alias), CLI:`% nova update` use that stored prerelease -preference to decide whether prerelease self-updates are eligible. When prerelease self-updates are disabled, -self-update stays on stable releases. When they are enabled, self-update may target a prerelease, but it asks for -explicit confirmation before proceeding and defaults that prerelease prompt to `No`, so pressing Enter cancels the -update. - +`Update-NovaModuleTool` (and its `Update-NovaModuleTools` alias), CLI:`% nova update` use that stored prerelease preference to decide whether prerelease self-updates are eligible. When prerelease self-updates are disabled, self-update stays on stable releases. When they are enabled, self-update may target a prerelease, but it asks for explicit confirmation before proceeding and defaults that prerelease prompt to `No`, so pressing Enter cancels the update. -Successful `Update-NovaModuleTool`, CLI:`% nova update`, and `Install-NovaCli` runs print the release notes link from -the -installed module manifest. When `Invoke-NovaBuild` detects a newer `NovaModuleTools` version after a build, the update -warning also includes that same release notes link. +Successful `Update-NovaModuleTool`, CLI:`% nova update`, and `Install-NovaCli` runs print the release notes link from the installed module manifest. When `Invoke-NovaBuild` detects a newer `NovaModuleTools` version after a build, the update warning also includes that same release notes link. To inspect the current project version, the installed version of the current project module, or the installed `NovaModuleTools` tool version, use: @@ -161,9 +138,7 @@ PS> Get-NovaProjectInfo -Installed ``` - `% nova version` shows the version from the current project's `project.json` -- `% nova version --installed` / `% nova version -i` shows the locally installed version of the current project/module - from - the local module path +- `% nova version --installed` / `% nova version -i` shows the locally installed version of the current project/module from the local module path - `Get-NovaProjectInfo -Installed` shows the installed `NovaModuleTools` module name and version from PowerShell - `% nova --version` / `% nova -v` shows the installed `NovaModuleTools` version @@ -181,8 +156,7 @@ Use the launcher-oriented help forms when you want CLI syntax instead of PowerSh - `% nova --help` / `% nova -h` shows short command help - `% nova --help ` / `% nova -h ` shows long command help -- Long command help now includes the matching public GitHub Pages guide URL for the selected command, while short help - stays link-free +- Long command help now includes the matching public GitHub Pages guide URL for the selected command, while short help stays link-free - CLI help is launcher-native and uses CLI option spellings such as `--repository` and `-r` - Use PowerShell `Get-Help` when you want cmdlet help such as `Get-Help Publish-NovaModule -Full` - Root `% nova -v` means version, while command-level `% nova build -v` means verbose for supported routed commands @@ -193,18 +167,13 @@ Use `% nova --confirm` / `% nova -c` when - `Y` / `Yes` and `A` / `Yes to All` continue - `N` / `No` and `L` / `No to All` cancel with a non-zero exit code -- `S` / `Suspend` is not supported in CLI mode and is treated as cancel so `nova` returns directly to your original - shell instead of opening a nested PowerShell prompt +- `S` / `Suspend` is not supported in CLI mode and is treated as cancel so `nova` returns directly to your original shell instead of opening a nested PowerShell prompt -Only the supported mutating `nova` commands accept `--confirm` / `-c`. Read-only routes and `% nova init` now reject the -CLI confirm flag with a clear validation error instead of silently treating it as a PowerShell-style concept. +Only the supported mutating `nova` commands accept `--confirm` / `-c`. Read-only routes and `% nova init` now reject the CLI confirm flag with a clear validation error instead of silently treating it as a PowerShell-style concept. -Direct PowerShell cmdlets such as `Publish-NovaModule`, `Deploy-NovaPackage`, and `Update-NovaModuleVersion` keep their -native `-Confirm` behavior. The CLI-safe confirmation flow applies to `nova` CLI usage, while `Invoke-NovaCli` remains -the explicit PowerShell cmdlet entrypoint for routed command dispatch. +Direct PowerShell cmdlets such as `Publish-NovaModule`, `Deploy-NovaPackage`, and `Update-NovaModuleVersion` keep their native `-Confirm` behavior. The CLI-safe confirmation flow applies to `nova` CLI usage, while `Invoke-NovaCli` remains the explicit PowerShell cmdlet entrypoint for routed command dispatch. -The module does not export a PowerShell alias named `nova`. Install the bundled launcher with `Install-NovaCli` when you -want `% nova ...` available directly from your shell. +The module does not export a PowerShell alias named `nova`. Install the bundled launcher with `Install-NovaCli` when you want `% nova ...` available directly from your shell. ### Reload the built module while iterating @@ -223,12 +192,9 @@ PS> Remove-Module NovaModuleTools -ErrorAction SilentlyContinue PS> Publish-NovaModule -Local ``` -`Publish-NovaModule -Local` now copies the module to the resolved local module path and reloads that published copy into -the active PowerShell session. If your repository workflow needs to switch back to the built `dist/` output afterward, -re-import `./dist/NovaModuleTools` explicitly. +`Publish-NovaModule -Local` now copies the module to the resolved local module path and reloads that published copy into the active PowerShell session. If your repository workflow needs to switch back to the built `dist/` output afterward, re-import `./dist/NovaModuleTools` explicitly. -When the same CI/self-hosting session must stay aligned with the built `dist/` output automatically, use the new -continuous-integration activation switches instead of handling re-imports manually: +When the same CI/self-hosting session must stay aligned with the built `dist/` output automatically, use the new continuous-integration activation switches instead of handling re-imports manually: ```powershell PS> Invoke-NovaBuild -ContinuousIntegration @@ -246,21 +212,13 @@ These switches keep the behavior explicit and opt-in: - `Invoke-NovaBuild -ContinuousIntegration` re-imports the freshly built module after the build succeeds - `Update-NovaModuleVersion -ContinuousIntegration` re-imports the built module before the bump workflow starts -- `Update-NovaModuleVersion -ContinuousIntegration` also falls back to a patch bump when the current `HEAD` already - matches the latest tag, so release automation can seed the next prerelease line without requiring an extra commit - first -- `Update-NovaModuleVersion` and `% nova bump` now stop when Git-based bump inference is unavailable, unless you - explicitly opt in to the Patch fallback with `-OverrideWarning` / `--override-warning` / `-o` for a non-git - example/template flow -- `Update-NovaModuleVersion` and `% nova bump` treat stable `0.y.z` versions as the SemVer initial-development phase, - so breaking-change bumps stay on the `0.y.z` line by planning the next minor version instead of jumping to `1.0.0` +- `Update-NovaModuleVersion -ContinuousIntegration` also falls back to a patch bump when the current `HEAD` already matches the latest tag, so release automation can seed the next prerelease line without requiring an extra commit first +- `Update-NovaModuleVersion` and `% nova bump` now stop when Git-based bump inference is unavailable, unless you explicitly opt in to the Patch fallback with `-OverrideWarning` / `--override-warning` / `-o` for a non-git example/template flow +- `Update-NovaModuleVersion` and `% nova bump` treat stable `0.y.z` versions as the SemVer initial-development phase, so breaking-change bumps stay on the `0.y.z` line by planning the next minor version instead of jumping to `1.0.0` - `Publish-NovaModule -ContinuousIntegration` restores the built module after publish completes -- `Invoke-NovaRelease -ContinuousIntegration` forwards that CI intent through the nested build/bump boundaries and then - restores the built module again after publish +- `Invoke-NovaRelease -ContinuousIntegration` forwards that CI intent through the nested build/bump boundaries and then restores the built module again after publish -When the current stable version is still `0.y.z`, Nova also prints one warning that major version zero is still the -initial-development line and that `1.0.0` must be set manually once the software is stable. Preview bumps keep their -current behavior and are not remapped by this rule. +When the current stable version is still `0.y.z`, Nova also prints one warning that major version zero is still the initial-development line and that `1.0.0` must be set manually once the software is stable. Preview bumps keep their current behavior and are not remapped by this rule. Useful local helper: @@ -304,13 +262,11 @@ Notes: - it writes NUnit XML to `artifacts/TestResults.xml` - it respects `BuildRecursiveFolders` when discovering tests - 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 +- the published `NovaModuleTools` manifest also declares `Pester 5.7.1`, so installed end-user workflows can still resolve that dependency automatically ### Create a package artifact -Use the explicit packaging workflow when you want a package artifact for a Nova project without publishing to a -PowerShell repository: +Use the explicit packaging workflow when you want a package artifact for a Nova project without publishing to a PowerShell repository: ```powershell PS> New-NovaModulePackage @@ -318,10 +274,7 @@ PS> New-NovaModulePackage ``` The package command runs the normal build and test flow, then writes the generated package artifacts to -`artifacts/packages/` by default by using the generic `Package` section in `project.json` when present. -When `Manifest.Tags`, `Manifest.ProjectUri`, `Manifest.ReleaseNotes`, or `Manifest.LicenseUri` are present, Nova -copies them into the generated package metadata; when they are omitted, packaging still succeeds and the matching -package metadata fields are simply left out. +`artifacts/packages/` by default by using the generic `Package` section in `project.json` when present. When `Manifest.Tags`, `Manifest.ProjectUri`, `Manifest.ReleaseNotes`, or `Manifest.LicenseUri` are present, Nova copies them into the generated package metadata; when they are omitted, packaging still succeeds and the matching package metadata fields are simply left out. When tests already ran earlier in CI/CD, you can skip only the test step while still rebuilding before packaging: @@ -340,7 +293,10 @@ Use this `project.json` shape when you want to control the package types and out "Package": { "PackageFileName": "AgentInstaller", "AddVersionToFileName": true, - "Types": ["NuGet", "Zip"], + "Types": [ + "NuGet", + "Zip" + ], "Latest": "stable", "OutputDirectory": { "Path": "artifacts/packages", @@ -358,19 +314,15 @@ Use this `project.json` shape when you want to control the package types and out - Set `Latest` to `"always"` when both stable and preview versions should also create companion `*.latest.*` artifacts. - Set `Latest` to `"never"` when you only want versioned package files. - `PackageFileName` lets you override the base artifact name. -- `AddVersionToFileName` defaults to `false`. When set to `true`, Nova appends `.` from `project.json` to the - configured `PackageFileName`, so `AgentInstaller` becomes `AgentInstaller.2.3.4` before the package - extension is applied. -- When `AddVersionToFileName` is enabled and `Latest` is `"stable"` or `"always"`, the companion artifact substitutes - the appended version suffix with `.latest`, such as `AgentInstaller.latest.nupkg`. +- `AddVersionToFileName` defaults to `false`. When set to `true`, Nova appends `.` from `project.json` to the configured `PackageFileName`, so `AgentInstaller` becomes `AgentInstaller.2.3.4` before the package extension is applied. +- When `AddVersionToFileName` is enabled and `Latest` is `"stable"` or `"always"`, the companion artifact substitutes the appended version suffix with `.latest`, such as `AgentInstaller.latest.nupkg`. - `Path` selects where the package artifact(s) are written. - `Clean` defaults to `true` and removes that output directory before a new package is created. - Set `Clean` to `false` when you want to keep existing files in the package output directory. ### Upload package artifacts to a raw endpoint -Use the upload workflow when a Nova project must push existing package artifacts to a raw HTTP endpoint instead of a -PowerShell repository: +Use the upload workflow when a Nova project must push existing package artifacts to a raw HTTP endpoint instead of a PowerShell repository: ```powershell PS> Deploy-NovaPackage -Repository LocalNexus @@ -383,7 +335,9 @@ Use this `project.json` shape when you want Nova to resolve upload targets from ```json { "Package": { - "Types": ["Zip"], + "Types": [ + "Zip" + ], "OutputDirectory": { "Path": "artifacts/packages", "Clean": true @@ -410,22 +364,16 @@ Use this `project.json` shape when you want Nova to resolve upload targets from - When `-PackagePath` is omitted, Nova resolves package files from `Package.OutputDirectory.Path`. - `Package.FileNamePattern` overrides the default upload discovery pattern. When omitted, Nova falls back to `*` and then applies the selected package type extension. -- If `Package.PackageFileName` uses a different base name than `Package.Id`, update `Package.FileNamePattern` too so - automatic upload discovery keeps matching the generated files. -- When `Package.FileNamePattern` already ends with `.zip` or `.nupkg`, Nova treats that extension as authoritative. - For example, `MyModule.*.zip` discovers `MyModule.1.2.3.zip` and `MyModule.latest.zip` without picking up +- If `Package.PackageFileName` uses a different base name than `Package.Id`, update `Package.FileNamePattern` too so automatic upload discovery keeps matching the generated files. +- When `Package.FileNamePattern` already ends with `.zip` or `.nupkg`, Nova treats that extension as authoritative. For example, `MyModule.*.zip` discovers `MyModule.1.2.3.zip` and `MyModule.latest.zip` without picking up `MyModule.1.2.3.nupkg`. - When multiple matching files exist for a selected package type, Nova uploads all of them, including versioned and `latest` variants. -- `Package.Headers`, `Package.Auth`, `Package.RepositoryUrl`, and repository-specific overrides remain generic so the - workflow works with raw endpoints such as Nexus or Artifactory without turning `Publish-NovaModule` into a vendor- - specific upload command. +- `Package.Headers`, `Package.Auth`, `Package.RepositoryUrl`, and repository-specific overrides remain generic so the workflow works with raw endpoints such as Nexus or Artifactory without turning `Publish-NovaModule` into a vendor- specific upload command. - `Publish-NovaModule` and `Invoke-NovaRelease` keep a matching secret rule for PowerShell repositories: `-ApiKey` / - `--api-key` overrides any fallback, and `PSGallery` still checks `PSGALLERY_API` when no explicit API key was - provided. + `--api-key` overrides any fallback, and `PSGallery` still checks `PSGALLERY_API` when no explicit API key was provided. -For module publishing and release flows, the same opt-in skip-tests behavior is available when tests already ran earlier -in the pipeline: +For module publishing and release flows, the same opt-in skip-tests behavior is available when tests already ran earlier in the pipeline: ```powershell PS> Publish-NovaModule -Repository PSGallery -ApiKey $env:PSGALLERY_API -SkipTests @@ -437,8 +385,7 @@ PS> Invoke-NovaRelease -Repository PSGallery -ApiKey $env:PSGALLERY_API -SkipTes These forms skip `Test-NovaBuild` only. `Publish-NovaModule` still builds before publishing, and `Invoke-NovaRelease` still runs both build steps around the version bump. -`Invoke-NovaRelease` now uses the same direct delivery parameters as `Publish-NovaModule` and `% nova release`, so -PowerShell automation can pass `-Local`, `-Repository`, `-ModuleDirectoryPath`, and `-ApiKey` without wrapping them in a +`Invoke-NovaRelease` now uses the same direct delivery parameters as `Publish-NovaModule` and `% nova release`, so PowerShell automation can pass `-Local`, `-Repository`, `-ModuleDirectoryPath`, and `-ApiKey` without wrapping them in a `-PublishOption` hashtable. When your pipeline continues in the same PowerShell session after build, bump, publish, or release, add @@ -461,21 +408,14 @@ For CI-parity coverage and report generation, use: 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: +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` -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 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`. ### Recommended local quality loop @@ -512,8 +452,7 @@ Within that split, keep CLI and cmdlet documentation separate: `Install-Module -Name NovaModuleTools` - `docs/NovaModuleTools/en-US/*.md` remains the cmdlet-help surface -If you want build-generated PowerShell help, place it under `docs//`. -Markdown elsewhere under `docs/` is ignored by help generation, so you can keep non-help docs there when needed. +If you want build-generated PowerShell help, place it under `docs//`. Markdown elsewhere under `docs/` is ignored by help generation, so you can keep non-help docs there when needed. ## Repository structure and ownership @@ -598,8 +537,7 @@ This folder has two different responsibilities that must stay separated by file - `docs/*.html` → GitHub Pages end-user guides - `docs//**/*.md` → PlatyPS command-help source for the current project -The build only treats markdown under `docs//` as help input. -Markdown elsewhere under `docs/` can be used for other documentation without affecting help generation. +The build only treats markdown under `docs//` as help input. Markdown elsewhere under `docs/` can be used for other documentation without affecting help generation. ### Scripts and automation @@ -625,13 +563,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 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. ### Build and test automation @@ -642,12 +575,9 @@ The normal repository workflow is: 3. ScriptAnalyzer via `scripts/build/Invoke-ScriptAnalyzerCI.ps1` 4. Optional CI helper flow via `scripts/build/ci/Invoke-NovaModuleToolsCI.ps1` -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. +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 JUnit and Cobertura artifacts for external systems, including the coverage file that the CodeScene workflow gate and upload steps consume. ### Release automation @@ -672,10 +602,7 @@ Responsibilities currently covered by the release pipeline include: - publishing to PowerShell Gallery - preparing the next prerelease version on `develop` -The workflow now uses `KeepAChangelog` for changelog release moves, creates annotated git tags named directly from the -release version, and bootstraps the local PSResourceGet repository store before calling `Publish-NovaModule`. -The shared CI installer also installs `Pester 5.7.1` explicitly before it installs prerelease gallery modules so test -workflows do not rely on transitive manifest dependency resolution. +The workflow now uses `KeepAChangelog` for changelog release moves, creates annotated git tags named directly from the release version, and bootstraps the local PSResourceGet repository store before calling `Publish-NovaModule`. The shared CI installer also installs `Pester 5.7.1` explicitly before it installs prerelease gallery modules so test workflows do not rely on transitive manifest dependency resolution. ### Where NovaModuleTools cmdlets fit @@ -685,8 +612,7 @@ NovaModuleTools already provides the core release building blocks: - `Publish-NovaModule` - `Invoke-NovaRelease` -The repository workflow combines these with the `KeepAChangelog` module and local reusable GitHub actions instead of a -separate semantic-release toolchain. +The repository workflow combines these with the `KeepAChangelog` module and local reusable GitHub actions instead of a separate semantic-release toolchain. ### Contributor expectations for workflow changes @@ -696,8 +622,7 @@ When you change CI, build, or release behavior: - update command help if public command behavior changes - update `README.md` when contributor workflow changes - update `CHANGELOG.md` when the change is relevant to users or maintainers -- update `RELEASE_NOTE.md` when the change affects public cmdlet usage, CLI usage, configuration semantics, or migration - expectations +- update `RELEASE_NOTE.md` when the change affects public cmdlet usage, CLI usage, configuration semantics, or migration expectations ## Documentation ownership rules @@ -716,6 +641,9 @@ When you change CI, build, or release behavior: This project is licensed under the MIT License. See LICENSE for details. [PSGalleryLink]: https://www.powershellgallery.com/packages/NovaModuleTools/ + [WorkFlowStatus]: https://img.shields.io/github/actions/workflow/status/stiwicourage/NovaModuleTools/Tests.yml + [changelog]: https://keepachangelog.com/ + [changelog-badge]: https://img.shields.io/badge/changelog-Keep%20a%20Changelog-%23E05735 diff --git a/RELEASE_NOTE.md b/RELEASE_NOTE.md index fa9d82e3..ab9f8e4b 100644 --- a/RELEASE_NOTE.md +++ b/RELEASE_NOTE.md @@ -1,7 +1,7 @@ # 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** +`CHANGELOG.md` remains the exhaustive record of all changes in each release. **PREVIEW / UNRELEASED** changes will be included in the next **stable** release! ## [Unreleased] @@ -34,18 +34,15 @@ changes will be included in the next **stable** release! ### 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. +- `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 ### 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. + - `Update-NovaModuleTool`, `Update-NovaModuleTools`, and `% nova update` now require an explicit `Y` before a prerelease self-update continues. ### Fixed @@ -56,8 +53,7 @@ changes will be included in the next **stable** release! ## [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`. +`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 @@ -66,33 +62,27 @@ their own `Pester` installation step. The regression was fixed in `2.3.0`. - Existing automation should move away from deprecated `-PublishOption` usage. - Stable `0.y.z` bump planning now stays on the major-zero line even when commit history implies a breaking change. - Nova now plans the next minor version instead of auto-jumping to `1.0.0`. -- `Update-NovaModuleVersion -Preview` and `% nova bump --preview` now enter the preview track deterministically from - stable versions. +- `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 ### Added -- `Install-NovaCli` and a packaged `nova` launcher now let macOS and Linux users install and run `nova` directly from - zsh or bash. +- `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. -- Self-update support is now available through `Update-NovaModuleTool`, `Update-NovaModuleTools`, and `nova update`, - with matching notification preference commands and CLI routes. +- 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. - `Update-NovaModuleVersion -Preview` and `nova bump --preview` now support explicit preview-version iteration. -- `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. +- `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 - 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. +- `Publish-NovaModule -Local` and `nova publish --local` now reload the published module from the local install path into the current PowerShell session. ### Removed @@ -122,8 +112,7 @@ their own `Pester` installation step. The regression was fixed in `2.3.0`. ### Added -- Added `BuildRecursiveFolders`, `SetSourcePath`, and `FailOnDuplicateFunctionNames` project settings for more explicit - build control. +- Added `BuildRecursiveFolders`, `SetSourcePath`, and `FailOnDuplicateFunctionNames` project settings for more explicit build control. ### Changed @@ -133,8 +122,7 @@ their own `Pester` installation step. The regression was fixed in `2.3.0`. ### Added -- Resource format files named `Name.format.ps1xml` are now imported automatically through the generated module - manifest. +- Resource format files named `Name.format.ps1xml` are now imported automatically through the generated module manifest. ## [1.2.0] - 2025-09-17 @@ -150,8 +138,7 @@ their own `Pester` installation step. The regression was fixed in `2.3.0`. ### Added -- `Update-NovaModuleVersion` now supports preview tags, and project/build metadata now follows semver naming more - consistently. +- `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 @@ -164,8 +151,7 @@ their own `Pester` installation step. The regression was fixed in `2.3.0`. ### Added -- Added the optional `CopyResourcesToModuleRoot` project setting so resource files can be copied to the module root when - needed. +- Added the optional `CopyResourcesToModuleRoot` project setting so resource files can be copied to the module root when needed. ### Fixed diff --git a/project.json b/project.json index ed66dff7..ddb6574a 100644 --- a/project.json +++ b/project.json @@ -41,7 +41,7 @@ "OutputFormat": "NUnitXml" }, "Output": { - "Verbosity": "Detailed" + "Verbosity": "Normal" } } } diff --git a/src/private/build/BuildManifest.ps1 b/src/private/build/BuildManifest.ps1 index a1be8b4b..23725621 100644 --- a/src/private/build/BuildManifest.ps1 +++ b/src/private/build/BuildManifest.ps1 @@ -39,26 +39,26 @@ function Build-Manifest { Assert-ManifestSchema -Manifest $data.Manifest -AllowedParameter $ManfiestAllowedParams $sv = [semver]$data.Version $ParmsManifest = @{ - Path = $data.ManifestFilePSD1 - Description = $data.Description + Path = $data.ManifestFilePSD1 + Description = $data.Description FunctionsToExport = $functionToExport - AliasesToExport = $aliasToExport - RootModule = "$($data.ProjectName).psm1" - ModuleVersion = [version]$sv - FormatsToProcess = $FormatsToProcess - TypesToProcess = $TypesToProcess + AliasesToExport = $aliasToExport + RootModule = "$( $data.ProjectName ).psm1" + ModuleVersion = [version]$sv + FormatsToProcess = $FormatsToProcess + TypesToProcess = $TypesToProcess } - + ## Release lable if ($sv.PreReleaseLabel) { - $ParmsManifest['Prerelease'] = $sv.PreReleaseLabel - } + $ParmsManifest['Prerelease'] = $sv.PreReleaseLabel + } # Accept only valid Manifest Parameters $data.Manifest.Keys | ForEach-Object { - if ( $ManfiestAllowedParams -contains $_) { + if ($ManfiestAllowedParams -contains $_) { if ($data.Manifest.$_) { - $ParmsManifest.add($_, $data.Manifest.$_ ) + $ParmsManifest.add($_, $data.Manifest.$_) } } } diff --git a/src/private/build/GetOrderedScriptFileForDirectory.ps1 b/src/private/build/GetOrderedScriptFileForDirectory.ps1 index 01273c4f..f70caea7 100644 --- a/src/private/build/GetOrderedScriptFileForDirectory.ps1 +++ b/src/private/build/GetOrderedScriptFileForDirectory.ps1 @@ -20,10 +20,10 @@ function Get-OrderedScriptFileForDirectory { $root = $ProjectRoot return @( - $items | + $items | Sort-Object -Stable -Property @( - @{ Expression = { (Get-NormalizedRelativePath -Root $root -FullName $_.FullName).ToLowerInvariant() } }, - @{ Expression = { $_.FullName.ToLowerInvariant() } } + @{Expression = {(Get-NormalizedRelativePath -Root $root -FullName $_.FullName).ToLowerInvariant()}}, + @{Expression = {$_.FullName.ToLowerInvariant()}} ) ) } diff --git a/src/private/build/TestProjectSchema.ps1 b/src/private/build/TestProjectSchema.ps1 index 07400f94..87f1ba2d 100644 --- a/src/private/build/TestProjectSchema.ps1 +++ b/src/private/build/TestProjectSchema.ps1 @@ -8,7 +8,7 @@ function Test-ProjectSchema { ) Write-Verbose "Running Schema test against using $Schema schema" $SchemaPath = @{ - Build = Get-ResourceFilePath -FileName 'Schema-Build.json' + Build = Get-ResourceFilePath -FileName 'Schema-Build.json' Pester = Get-ResourceFilePath -FileName 'Schema-Pester.json' } try { diff --git a/src/private/build/manifest/GetAliasNameFromFunction.ps1 b/src/private/build/manifest/GetAliasNameFromFunction.ps1 index 621e3aab..d5406a6c 100644 --- a/src/private/build/manifest/GetAliasNameFromFunction.ps1 +++ b/src/private/build/manifest/GetAliasNameFromFunction.ps1 @@ -11,14 +11,14 @@ function Get-AliasInFunctionFromFile { $ast = [System.Management.Automation.Language.Parser]::ParseFile($filePath, [ref]$null, [ref]$null) $functionNodes = $ast.FindAll({ - param($node) - $node -is [System.Management.Automation.Language.FunctionDefinitionAst] - }, $true) + param($node) + $node -is [System.Management.Automation.Language.FunctionDefinitionAst] + }, $true) $function = $functionNodes[0] - $paramsAttributes = $function.Body.ParamBlock.Attributes + $paramsAttributes = $function.Body.ParamBlock.Attributes - $aliases = ($paramsAttributes | Where-Object { $_.TypeName -like 'Alias' } | ForEach-Object PositionalArguments).Value + $aliases = ($paramsAttributes | Where-Object {$_.TypeName -like 'Alias'} | ForEach-Object PositionalArguments).Value $aliases } catch { return diff --git a/src/private/build/manifest/GetFunctionNameFromFile.ps1 b/src/private/build/manifest/GetFunctionNameFromFile.ps1 index cc97e43e..aa2f3a85 100644 --- a/src/private/build/manifest/GetFunctionNameFromFile.ps1 +++ b/src/private/build/manifest/GetFunctionNameFromFile.ps1 @@ -3,8 +3,10 @@ function Get-FunctionNameFromFile { try { $moduleContent = Get-Content -Path $filePath -Raw $ast = [System.Management.Automation.Language.Parser]::ParseInput($moduleContent, [ref]$null, [ref]$null) - $functionName = $ast.FindAll({ $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] }, $false) | ForEach-Object { $_.Name } + $functionName = $ast.FindAll({$args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst]}, $false) | ForEach-Object {$_.Name} return $functionName } - catch { return '' } + catch { + return '' + } } diff --git a/src/private/cli/ReadAwesomeHost.ps1 b/src/private/cli/ReadAwesomeHost.ps1 index e8237995..a71201c9 100644 --- a/src/private/cli/ReadAwesomeHost.ps1 +++ b/src/private/cli/ReadAwesomeHost.ps1 @@ -1,4 +1,3 @@ - function Read-AwesomeHost { [CmdletBinding()] param ( diff --git a/src/private/quality/duplicates/AssertBuiltModuleHasNoDuplicateFunctionNames.ps1 b/src/private/quality/duplicates/AssertBuiltModuleHasNoDuplicateFunctionNames.ps1 index 8770dcb8..349df418 100644 --- a/src/private/quality/duplicates/AssertBuiltModuleHasNoDuplicateFunctionNames.ps1 +++ b/src/private/quality/duplicates/AssertBuiltModuleHasNoDuplicateFunctionNames.ps1 @@ -11,7 +11,7 @@ function Assert-BuiltModuleHasNoDuplicateFunctionName { $parsed = Get-PowerShellAstFromFile -Path $psm1Path if ($parsed.Errors -and $parsed.Errors.Count -gt 0) { - $messages = @($parsed.Errors | ForEach-Object { $_.Message }) -join '; ' + $messages = @($parsed.Errors | ForEach-Object {$_.Message}) -join '; ' Stop-NovaOperation -Message "Built module contains parse errors and cannot be validated for duplicates. File: $psm1Path. Errors: $messages" -ErrorId 'Nova.Configuration.BuiltModuleDuplicateValidationParseFailed' -Category ParserError -TargetObject $psm1Path } diff --git a/src/private/quality/duplicates/FormatDuplicateFunctionErrorMessage.ps1 b/src/private/quality/duplicates/FormatDuplicateFunctionErrorMessage.ps1 index 8d528814..e83c6466 100644 --- a/src/private/quality/duplicates/FormatDuplicateFunctionErrorMessage.ps1 +++ b/src/private/quality/duplicates/FormatDuplicateFunctionErrorMessage.ps1 @@ -16,7 +16,7 @@ function Format-DuplicateFunctionErrorMessage { $lines.Add('') $lines.Add("- $displayName") - foreach ($occurrence in ($dup.Group | Sort-Object { $_.Extent.StartLineNumber })) { + foreach ($occurrence in ($dup.Group | Sort-Object {$_.Extent.StartLineNumber})) { $lines.Add((" - dist line {0}" -f $occurrence.Extent.StartLineNumber)) } diff --git a/src/private/quality/duplicates/GetDuplicateFunctionGroup.ps1 b/src/private/quality/duplicates/GetDuplicateFunctionGroup.ps1 index 60d1f3ae..412073ee 100644 --- a/src/private/quality/duplicates/GetDuplicateFunctionGroup.ps1 +++ b/src/private/quality/duplicates/GetDuplicateFunctionGroup.ps1 @@ -5,8 +5,8 @@ function Get-DuplicateFunctionGroup { ) return @( - $FunctionAst | - Group-Object -Property { ('' + $_.Name).ToLowerInvariant() } | - Where-Object { $_.Count -gt 1 } + $FunctionAst | + Group-Object -Property {('' + $_.Name).ToLowerInvariant()} | + Where-Object {$_.Count -gt 1} ) } diff --git a/src/private/quality/duplicates/GetTopLevelFunctionAst.ps1 b/src/private/quality/duplicates/GetTopLevelFunctionAst.ps1 index 2c3741b7..16597084 100644 --- a/src/private/quality/duplicates/GetTopLevelFunctionAst.ps1 +++ b/src/private/quality/duplicates/GetTopLevelFunctionAst.ps1 @@ -5,14 +5,16 @@ function Get-TopLevelFunctionAst { ) $all = @($Ast.FindAll({ - param($n) - $n -is [System.Management.Automation.Language.FunctionDefinitionAst] - }, $true)) + param($n) + $n -is [System.Management.Automation.Language.FunctionDefinitionAst] + }, $true)) $top = foreach ($candidate in $all) { $nested = $false foreach ($other in $all) { - if ($other -eq $candidate) { continue } + if ($other -eq $candidate) { + continue + } if ($other.Extent.StartOffset -lt $candidate.Extent.StartOffset -and $other.Extent.EndOffset -gt $candidate.Extent.EndOffset) { $nested = $true diff --git a/src/private/shared/GetNovaResolvedProjectPackageSettings.ps1 b/src/private/shared/GetNovaResolvedProjectPackageSettings.ps1 index 2834373c..c04136e7 100644 --- a/src/private/shared/GetNovaResolvedProjectPackageSettings.ps1 +++ b/src/private/shared/GetNovaResolvedProjectPackageSettings.ps1 @@ -51,7 +51,7 @@ function ConvertTo-NovaPackageLatestPolicy { } $policy = "$Value".Trim() - if ([string]::IsNullOrWhiteSpace($policy)) { + if ( [string]::IsNullOrWhiteSpace($policy)) { return 'never' } diff --git a/src/resources/ProjectTemplate.json b/src/resources/ProjectTemplate.json index a0981a6b..cfd8593a 100644 --- a/src/resources/ProjectTemplate.json +++ b/src/resources/ProjectTemplate.json @@ -1,15 +1,15 @@ { - "ProjectName": "", - "Description": "", - "Version": "", + "ProjectName": "", + "Description": "", + "Version": "", "Preamble": [], - "Manifest": { - "Author": "", - "PowerShellHostVersion": "", - "GUID": "", - "Tags": [], - "ProjectUri": "" - }, + "Manifest": { + "Author": "", + "PowerShellHostVersion": "", + "GUID": "", + "Tags": [], + "ProjectUri": "" + }, "Package": { "Types": [ "NuGet" @@ -19,13 +19,13 @@ "Clean": true } }, - "Pester": { - "TestResult": { - "Enabled": true, - "OutputFormat": "NUnitXml" - }, - "Output": { - "Verbosity": "Detailed" - } + "Pester": { + "TestResult": { + "Enabled": true, + "OutputFormat": "NUnitXml" + }, + "Output": { + "Verbosity": "Detailed" } + } } diff --git a/src/resources/Schema-Build.json b/src/resources/Schema-Build.json index cad680ea..f7359b0a 100644 --- a/src/resources/Schema-Build.json +++ b/src/resources/Schema-Build.json @@ -1,217 +1,221 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "description": "Project Schema for Build only", - "properties": { - "ProjectName": { - "type": "string" - }, - "Description": { - "type": "string" - }, - "Version": { - "type": "string" - }, - "CopyResourcesToModuleRoot": { - "type": "boolean" + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "description": "Project Schema for Build only", + "properties": { + "ProjectName": { + "type": "string" + }, + "Description": { + "type": "string" + }, + "Version": { + "type": "string" + }, + "CopyResourcesToModuleRoot": { + "type": "boolean" + }, + "BuildRecursiveFolders": { + "type": "boolean", + "description": "Default enabled recursive discovery for src/classes, src/private and tests. src/public stays top-level only unless explicitly set to false for top-level-only discovery." + }, + "SetSourcePath": { + "type": "boolean", + "description": "Default enabled source markers: emit '# Source: ' before each concatenated source file in the generated dist//.psm1." + }, + "FailOnDuplicateFunctionNames": { + "type": "boolean", + "description": "Default enabled validation: fail build when duplicate top-level function names exist in the generated dist//.psm1." + }, + "Preamble": { + "type": "array", + "description": "Optional module-level lines written at the very top of the generated dist//.psm1 before any source markers or other generated content.", + "items": { + "type": "string" + } + }, + "Manifest": { + "type": "object", + "properties": { + "Author": { + "type": "string" }, - "BuildRecursiveFolders": { - "type": "boolean", - "description": "Default enabled recursive discovery for src/classes, src/private and tests. src/public stays top-level only unless explicitly set to false for top-level-only discovery." + "PowerShellHostVersion": { + "type": "string" }, - "SetSourcePath": { - "type": "boolean", - "description": "Default enabled source markers: emit '# Source: ' before each concatenated source file in the generated dist//.psm1." + "GUID": { + "type": "string" }, - "FailOnDuplicateFunctionNames": { - "type": "boolean", - "description": "Default enabled validation: fail build when duplicate top-level function names exist in the generated dist//.psm1." + "Tags": { + "type": "array", + "items": { + "type": "string" + } }, - "Preamble": { - "type": "array", - "description": "Optional module-level lines written at the very top of the generated dist//.psm1 before any source markers or other generated content.", - "items": { + "ProjectUri": { "type": "string" } }, - "Manifest": { - "type": "object", - "properties": { - "Author": { - "type": "string" - }, - "PowerShellHostVersion": { - "type": "string" - }, - "GUID": { - "type": "string" - }, - "Tags": { - "type": "array", - "items": { - "type": "string" - } - }, - "ProjectUri": { - "type": "string" - } - }, - "required": [ - "Author", - "PowerShellHostVersion", - "GUID" - ] + "required": [ + "Author", + "PowerShellHostVersion", + "GUID" + ] + }, + "Package": { + "type": "object", + "properties": { + "Id": { + "type": "string" }, - "Package": { - "type": "object", - "properties": { - "Id": { - "type": "string" - }, - "Types": { - "type": "array", - "items": { + "Types": { + "type": "array", + "items": { + "type": "string", + "pattern": "^(?:[Nn][Uu][Gg][Ee][Tt]|[Zz][Ii][Pp]|\\.[Nn][Uu][Pp][Kk][Gg]|\\.[Zz][Ii][Pp])$" + } + }, + "Latest": { + "anyOf": [ + { + "type": "boolean" + }, + { "type": "string", - "pattern": "^(?:[Nn][Uu][Gg][Ee][Tt]|[Zz][Ii][Pp]|\\.[Nn][Uu][Pp][Kk][Gg]|\\.[Zz][Ii][Pp])$" + "enum": [ + "never", + "stable", + "always" + ] } - }, - "Latest": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "string", - "enum": ["never", "stable", "always"] - } - ] - }, - "OutputDirectory": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "Path": { - "type": "string" - }, - "Clean": { - "type": "boolean" - } + ] + }, + "OutputDirectory": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": { + "Path": { + "type": "string" + }, + "Clean": { + "type": "boolean" } } - ] - }, - "PackageFileName": { - "type": "string" - }, - "AddVersionToFileName": { - "type": "boolean" - }, - "FileNamePattern": { - "type": "string" - }, - "Authors": { - "anyOf": [ - { + } + ] + }, + "PackageFileName": { + "type": "string" + }, + "AddVersionToFileName": { + "type": "boolean" + }, + "FileNamePattern": { + "type": "string" + }, + "Authors": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { "type": "string" - }, - { - "type": "array", - "items": { - "type": "string" - } } - ] - }, - "Description": { - "type": "string" - }, - "RepositoryUrl": { - "type": "string" - }, - "RawRepositoryUrl": { - "type": "string" - }, - "UploadPath": { + } + ] + }, + "Description": { + "type": "string" + }, + "RepositoryUrl": { + "type": "string" + }, + "RawRepositoryUrl": { + "type": "string" + }, + "UploadPath": { + "type": "string" + }, + "Headers": { + "type": "object", + "additionalProperties": { "type": "string" - }, - "Headers": { - "type": "object", - "additionalProperties": { + } + }, + "Auth": { + "type": "object", + "properties": { + "HeaderName": { + "type": "string" + }, + "Scheme": { + "type": "string" + }, + "Token": { + "type": "string" + }, + "TokenEnvironmentVariable": { "type": "string" } - }, - "Auth": { + } + }, + "Repositories": { + "type": "array", + "items": { "type": "object", "properties": { - "HeaderName": { + "Name": { "type": "string" }, - "Scheme": { + "Url": { "type": "string" }, - "Token": { + "UploadPath": { "type": "string" }, - "TokenEnvironmentVariable": { - "type": "string" - } - } - }, - "Repositories": { - "type": "array", - "items": { - "type": "object", - "properties": { - "Name": { - "type": "string" - }, - "Url": { - "type": "string" - }, - "UploadPath": { + "Headers": { + "type": "object", + "additionalProperties": { "type": "string" - }, - "Headers": { - "type": "object", - "additionalProperties": { + } + }, + "Auth": { + "type": "object", + "properties": { + "HeaderName": { + "type": "string" + }, + "Scheme": { + "type": "string" + }, + "Token": { + "type": "string" + }, + "TokenEnvironmentVariable": { "type": "string" - } - }, - "Auth": { - "type": "object", - "properties": { - "HeaderName": { - "type": "string" - }, - "Scheme": { - "type": "string" - }, - "Token": { - "type": "string" - }, - "TokenEnvironmentVariable": { - "type": "string" - } } } - }, - "required": [ - "Name", - "Url" - ] - } + } + }, + "required": [ + "Name", + "Url" + ] } } - } - }, - "required": [ - "ProjectName", - "Description", - "Version", - "Manifest" - ] + } + } + }, + "required": [ + "ProjectName", + "Description", + "Version", + "Manifest" + ] } diff --git a/src/resources/Schema-Pester.json b/src/resources/Schema-Pester.json index 6b7d8ec8..78dddc0f 100644 --- a/src/resources/Schema-Pester.json +++ b/src/resources/Schema-Pester.json @@ -1,37 +1,37 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "Pester": { - "type": "object", - "properties": { - "TestResult": { - "type": "object", - "properties": { - "Enabled": { - "type": "boolean" - } - }, - "required": [ - "Enabled" - ] - }, - "Output": { - "type": "object", - "properties": { - "Verbosity": { - "type": "string" - } - }, - "required": [ - "Verbosity" - ] - } - }, - "required": [ - "TestResult", - "Output" - ] + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "Pester": { + "type": "object", + "properties": { + "TestResult": { + "type": "object", + "properties": { + "Enabled": { + "type": "boolean" + } + }, + "required": [ + "Enabled" + ] + }, + "Output": { + "type": "object", + "properties": { + "Verbosity": { + "type": "string" + } + }, + "required": [ + "Verbosity" + ] } + }, + "required": [ + "TestResult", + "Output" + ] } + } } diff --git a/src/resources/example/README.md b/src/resources/example/README.md index b5e92f03..398f4212 100644 --- a/src/resources/example/README.md +++ b/src/resources/example/README.md @@ -17,8 +17,7 @@ It is meant to help a new user understand the smallest useful setup that can: - includes all current top-level project settings, including `CopyResourcesToModuleRoot`, `BuildRecursiveFolders`, `SetSourcePath`, and `FailOnDuplicateFunctionNames` - includes optional manifest metadata such as `ProjectUri`, `ReleaseNotes`, and `LicenseUri` - - includes a complete `Package` example so new users can see where package metadata and generic raw upload settings - belong + - includes a complete `Package` example so new users can see where package metadata and generic raw upload settings belong - includes named `Package.Repositories` examples for `PS> Deploy-NovaPackage` / `% nova deploy` - `src/public/Get-ExampleGreeting.ps1` – a public function exported from the built module - `src/private/Get-ExampleConfiguration.ps1` – a private helper used by the public function @@ -31,8 +30,7 @@ It is meant to help a new user understand the smallest useful setup that can: Run these commands from the repository root: -If `./dist/NovaModuleTools` is not available yet, build `NovaModuleTools` from the repository root first, or use the -PowerShell Gallery workflow below. +If `./dist/NovaModuleTools` is not available yet, build `NovaModuleTools` from the repository root first, or use the PowerShell Gallery workflow below. ```text PS> Import-Module ./dist/NovaModuleTools -Force @@ -75,9 +73,7 @@ After `New-NovaModulePackage`, the package artifact is written to: src/resources/example/artifacts/packages/ ``` -The example project sets `Package.Types` to `['NuGet', 'Zip']` and `Package.Latest` to `"stable"`, so stable packing -generates the normal versioned `.nupkg` / `.zip` files plus companion `*.latest.*` files in the package output -directory. +The example project sets `Package.Types` to `['NuGet', 'Zip']` and `Package.Latest` to `"stable"`, so stable packing generates the normal versioned `.nupkg` / `.zip` files plus companion `*.latest.*` files in the package output directory. The example `project.json` also shows how to configure raw package upload settings such as: @@ -119,6 +115,4 @@ This example is intentionally small, but it demonstrates the most important Nova - how tests should import the built module from `dist/` - where the current package, packaging, and raw-upload configuration keys live in `project.json` -If you want a new project scaffold, use `PS> Initialize-NovaModule` (`% nova init`). If you want a concrete project you -can -inspect, run, or copy through `% nova init --example` / `% nova init -e`, use this example folder. +If you want a new project scaffold, use `PS> Initialize-NovaModule` (`% nova init`). If you want a concrete project you can inspect, run, or copy through `% nova init --example` / `% nova init -e`, use this example folder. diff --git a/tests/BuildOptions.TestSupport.ps1 b/tests/BuildOptions.TestSupport.ps1 index 42dbc2dd..6ccb0b6d 100644 --- a/tests/BuildOptions.TestSupport.ps1 +++ b/tests/BuildOptions.TestSupport.ps1 @@ -9,17 +9,17 @@ function New-TestProjectRoot { New-Item -ItemType Directory -Path $root -Force | Out-Null foreach ($dir in @( - 'src/public', - 'src/public/nested', - 'src/private', - 'src/private/a', - 'src/private/b', - 'src/classes', - 'src/classes/nested', - 'tests', - 'tests/nested', - 'docs' - )) { + 'src/public', + 'src/public/nested', + 'src/private', + 'src/private/a', + 'src/private/b', + 'src/classes', + 'src/classes/nested', + 'tests', + 'tests/nested', + 'docs' + )) { New-Item -ItemType Directory -Path (Join-Path $root $dir) -Force | Out-Null } @@ -55,15 +55,15 @@ function Write-TestProjectJson { } } - if ($Options.ContainsKey('BuildRecursiveFolders')) { + if ( $Options.ContainsKey('BuildRecursiveFolders')) { $project.BuildRecursiveFolders = [bool]$Options.BuildRecursiveFolders } - if ($Options.ContainsKey('SetSourcePath')) { + if ( $Options.ContainsKey('SetSourcePath')) { $project.SetSourcePath = [bool]$Options.SetSourcePath } - if ($Options.ContainsKey('FailOnDuplicateFunctionNames')) { + if ( $Options.ContainsKey('FailOnDuplicateFunctionNames')) { $project.FailOnDuplicateFunctionNames = [bool]$Options.FailOnDuplicateFunctionNames } @@ -137,7 +137,7 @@ function Invoke-BuildAndParsePsm1Ast { $errors = $null $ast = [System.Management.Automation.Language.Parser]::ParseFile($psm1, [ref]$tokens, [ref]$errors) if ($errors -and $errors.Count -gt 0) { - throw "Built psm1 parse errors: $(@($errors | ForEach-Object Message) -join '; ')" + throw "Built psm1 parse errors: $( @($errors | ForEach-Object Message) -join '; ' )" } return $ast @@ -194,7 +194,7 @@ function Get-NestedSourceBuildSummary { return [pscustomobject]@{ Ast = $ast - TypeNames = @($ast.FindAll({ param($n) $n -is [System.Management.Automation.Language.TypeDefinitionAst] }, $true) | ForEach-Object Name) + TypeNames = @($ast.FindAll({param($n) $n -is [System.Management.Automation.Language.TypeDefinitionAst]}, $true) | ForEach-Object Name) FunctionAsts = $functionAsts FunctionNames = @($functionAsts | ForEach-Object Name) } @@ -267,14 +267,16 @@ function Get-TopLevelFunctionAstFromAst { ) $all = @($Ast.FindAll({ - param($n) - $n -is [System.Management.Automation.Language.FunctionDefinitionAst] - }, $true)) + param($n) + $n -is [System.Management.Automation.Language.FunctionDefinitionAst] + }, $true)) $top = foreach ($candidate in $all) { $nested = $false foreach ($other in $all) { - if ($other -eq $candidate) { continue } + if ($other -eq $candidate) { + continue + } if ($other.Extent.StartOffset -lt $candidate.Extent.StartOffset -and $other.Extent.EndOffset -gt $candidate.Extent.EndOffset) { $nested = $true @@ -282,7 +284,9 @@ function Get-TopLevelFunctionAstFromAst { } } - if (-not $nested) { $candidate } + if (-not $nested) { + $candidate + } } return @($top) @@ -296,12 +300,12 @@ function Write-TestMarkerPesterFile { ) $content = @" -Describe '$($TestCase.Name)' { +Describe '$( $TestCase.Name )' { It 'imports built module and writes marker' { - Import-Module '$($TestCase.BuiltModulePath)' -Force - Get-Module -Name '$($TestCase.ProjectName)' | Should -Not -BeNullOrEmpty - Set-Content -LiteralPath '$($TestCase.MarkerPath)' -Value '$($TestCase.Name)' -Encoding utf8 -NoNewline - (Get-Content -LiteralPath '$($TestCase.MarkerPath)' -Raw) | Should -Be '$($TestCase.Name)' + Import-Module '$( $TestCase.BuiltModulePath )' -Force + Get-Module -Name '$( $TestCase.ProjectName )' | Should -Not -BeNullOrEmpty + Set-Content -LiteralPath '$( $TestCase.MarkerPath )' -Value '$( $TestCase.Name )' -Encoding utf8 -NoNewline + (Get-Content -LiteralPath '$( $TestCase.MarkerPath )' -Raw) | Should -Be '$( $TestCase.Name )' } } "@ diff --git a/tests/BuildOptions.Tests.ps1 b/tests/BuildOptions.Tests.ps1 index e728d60f..79edee9c 100644 --- a/tests/BuildOptions.Tests.ps1 +++ b/tests/BuildOptions.Tests.ps1 @@ -160,7 +160,7 @@ Describe 'Invoke-NovaBuild options' { } It 'BuildRecursiveFolders=false excludes nested classes/private and nested public' { - $root = New-TestProjectWithNestedSourceFiles -TestDriveRoot $TestDrive -Name 'NoRecurse' -Options @{ ProjectName = 'NoRecurse'; BuildRecursiveFolders = $false; FailOnDuplicateFunctionNames = $false } + $root = New-TestProjectWithNestedSourceFiles -TestDriveRoot $TestDrive -Name 'NoRecurse' -Options @{ProjectName = 'NoRecurse'; BuildRecursiveFolders = $false; FailOnDuplicateFunctionNames = $false} $summary = Get-NestedSourceBuildSummary -ProjectRoot $root $summary.TypeNames | Should -Not -Contain 'NestedThing' @@ -169,7 +169,7 @@ Describe 'Invoke-NovaBuild options' { } It 'BuildRecursiveFolders=true includes nested classes/private but never nested public' { - $root = New-TestProjectWithNestedSourceFiles -TestDriveRoot $TestDrive -Name 'Recurse' -Options @{ ProjectName = 'Recurse'; BuildRecursiveFolders = $true; FailOnDuplicateFunctionNames = $false } -IncludeTopLevelFiles + $root = New-TestProjectWithNestedSourceFiles -TestDriveRoot $TestDrive -Name 'Recurse' -Options @{ProjectName = 'Recurse'; BuildRecursiveFolders = $true; FailOnDuplicateFunctionNames = $false} -IncludeTopLevelFiles $summary = Get-NestedSourceBuildSummary -ProjectRoot $root $summary.TypeNames | Should -Contain 'NestedThing' @@ -178,7 +178,7 @@ Describe 'Invoke-NovaBuild options' { $summary.FunctionNames | Should -Contain 'Invoke-PrivateTop' $summary.FunctionNames | Should -Not -Contain 'Invoke-NestedPublic' - $classOffset = ($summary.Ast.FindAll({ param($n) $n -is [System.Management.Automation.Language.TypeDefinitionAst] -and $n.Name -eq 'NestedThing' }, $true) | Select-Object -First 1).Extent.StartOffset + $classOffset = ($summary.Ast.FindAll({param($n) $n -is [System.Management.Automation.Language.TypeDefinitionAst] -and $n.Name -eq 'NestedThing'}, $true) | Select-Object -First 1).Extent.StartOffset $publicOffset = ($summary.FunctionAsts | Where-Object Name -eq 'Invoke-PublicTop' | Select-Object -First 1).Extent.StartOffset $privateOffset = ($summary.FunctionAsts | Where-Object Name -eq 'Invoke-PrivateTop' | Select-Object -First 1).Extent.StartOffset @@ -194,7 +194,7 @@ Describe 'Invoke-NovaBuild options' { } It 'missing BuildRecursiveFolders defaults to true for classes/private but never nested public' { - $root = New-TestProjectWithNestedSourceFiles -TestDriveRoot $TestDrive -Name 'RecurseDefault' -Options @{ ProjectName = 'RecurseDefault'; SetSourcePath = $false; FailOnDuplicateFunctionNames = $false } + $root = New-TestProjectWithNestedSourceFiles -TestDriveRoot $TestDrive -Name 'RecurseDefault' -Options @{ProjectName = 'RecurseDefault'; SetSourcePath = $false; FailOnDuplicateFunctionNames = $false} (Get-TestProjectInfoValue -ProjectRoot $root -PropertyName 'BuildRecursiveFolders') | Should -BeTrue @@ -207,7 +207,7 @@ Describe 'Invoke-NovaBuild options' { It 'missing SetSourcePath defaults to true and emits source markers' { $root = New-TestProjectRoot -TestDriveRoot $TestDrive -Name 'SetSourceDefault' - Write-TestProjectJson -ProjectRoot $root -Options @{ ProjectName = 'SetSourceDefault'; BuildRecursiveFolders = $false; FailOnDuplicateFunctionNames = $false } + Write-TestProjectJson -ProjectRoot $root -Options @{ProjectName = 'SetSourceDefault'; BuildRecursiveFolders = $false; FailOnDuplicateFunctionNames = $false} [System.IO.File]::WriteAllText((Join-Path $root 'src/public/PublicTop.ps1'), 'function Invoke-PublicTop { }') @@ -225,7 +225,7 @@ Describe 'Invoke-NovaBuild options' { It 'SetSourcePath=false preserves current concatenation output exactly' { $root = New-TestProjectRoot -TestDriveRoot $TestDrive -Name 'SetSourceOff' - Write-TestProjectJson -ProjectRoot $root -Options @{ ProjectName = 'SetSourceOff'; BuildRecursiveFolders = $false; SetSourcePath = $false; FailOnDuplicateFunctionNames = $false } + Write-TestProjectJson -ProjectRoot $root -Options @{ProjectName = 'SetSourceOff'; BuildRecursiveFolders = $false; SetSourcePath = $false; FailOnDuplicateFunctionNames = $false} [System.IO.File]::WriteAllText((Join-Path $root 'src/classes/Strict.ps1'), 'Set-StrictMode -Version Latest') [System.IO.File]::WriteAllText((Join-Path $root 'src/public/PublicTop.ps1'), 'function Invoke-PublicTop { "public" }') @@ -244,7 +244,7 @@ Describe 'Invoke-NovaBuild options' { It 'SetSourcePath=true writes one normalized relative source marker before each file and keeps the module importable' { $root = New-TestProjectRoot -TestDriveRoot $TestDrive -Name 'SetSourceOn' - Write-TestProjectJson -ProjectRoot $root -Options @{ ProjectName = 'SetSourceOn'; BuildRecursiveFolders = $true; SetSourcePath = $true; FailOnDuplicateFunctionNames = $false } + Write-TestProjectJson -ProjectRoot $root -Options @{ProjectName = 'SetSourceOn'; BuildRecursiveFolders = $true; SetSourcePath = $true; FailOnDuplicateFunctionNames = $false} [System.IO.File]::WriteAllText((Join-Path $root 'src/classes/nested/Thing.ps1'), 'class NestedThing { [string]$Name }') [System.IO.File]::WriteAllText((Join-Path $root 'src/public/PublicTop.ps1'), 'function Invoke-PublicTop { "public" }') @@ -254,7 +254,7 @@ Describe 'Invoke-NovaBuild options' { $content = [System.IO.File]::ReadAllText($psm1) $newLine = [Environment]::NewLine - ([regex]::Matches($content, '(?m)^# Source: .+$')).Count | Should -Be 3 + ([regex]::Matches($content, '(?m)^# Source: .+$')).Count | Should -Be 3 $content | Should -Not -Match '\\' $classBlock = "# Source: src/classes/nested/Thing.ps1${newLine}class NestedThing { [string]`$Name }" @@ -276,7 +276,7 @@ Describe 'Invoke-NovaBuild options' { $publicIndex | Should -BeLessThan $privateIndex Remove-Module SetSourceOn -ErrorAction SilentlyContinue - { Import-Module (Split-Path -Parent $psm1) -Force -ErrorAction Stop } | Should -Not -Throw + {Import-Module (Split-Path -Parent $psm1) -Force -ErrorAction Stop} | Should -Not -Throw Get-Command Invoke-PublicTop -Module SetSourceOn | Should -Not -BeNullOrEmpty Remove-Module SetSourceOn -ErrorAction SilentlyContinue } @@ -298,8 +298,8 @@ Describe 'Invoke-NovaBuild options' { } Context 'Test-NovaBuild discovery for BuildRecursiveFolders=' -ForEach @( - @{ Name = 'TestsTopOnly'; BuildRecursiveFolders = $false; ExpectedNestedMarker = $false } - @{ Name = 'TestsRecursive'; BuildRecursiveFolders = $true; ExpectedNestedMarker = $true } + @{Name = 'TestsTopOnly'; BuildRecursiveFolders = $false; ExpectedNestedMarker = $false} + @{Name = 'TestsRecursive'; BuildRecursiveFolders = $true; ExpectedNestedMarker = $true} ) { It 'runs the expected set of top-level and nested tests' { $project = New-TestProjectWithMarkerTests -TestDriveRoot $TestDrive -Name $_.Name -BuildRecursiveFolders $_.BuildRecursiveFolders @@ -324,7 +324,7 @@ Describe 'Invoke-NovaBuild options' { } It 'missing FailOnDuplicateFunctionNames defaults to true and fails on duplicate top-level function names' { - $root = New-TestProjectWithDuplicateFunctions -TestDriveRoot $TestDrive -Name 'DupDefault' -Options @{ ProjectName = 'DupDefault'; BuildRecursiveFolders = $false; SetSourcePath = $false } + $root = New-TestProjectWithDuplicateFunctions -TestDriveRoot $TestDrive -Name 'DupDefault' -Options @{ProjectName = 'DupDefault'; BuildRecursiveFolders = $false; SetSourcePath = $false} $expectedModulePath = Get-BuiltModuleFilePath -ProjectRoot $root (Get-TestProjectInfoValue -ProjectRoot $root -PropertyName 'FailOnDuplicateFunctionNames') | Should -BeTrue @@ -368,7 +368,7 @@ Describe 'Invoke-NovaBuild options' { } It 'FailOnDuplicateFunctionNames=true fails when built psm1 contains duplicate top-level function names' { - $root = New-TestProjectWithDuplicateFunctions -TestDriveRoot $TestDrive -Name 'DupFail' -Options @{ ProjectName = 'DupFail'; BuildRecursiveFolders = $false; FailOnDuplicateFunctionNames = $true } + $root = New-TestProjectWithDuplicateFunctions -TestDriveRoot $TestDrive -Name 'DupFail' -Options @{ProjectName = 'DupFail'; BuildRecursiveFolders = $false; FailOnDuplicateFunctionNames = $true} $expectedModulePath = Get-BuiltModuleFilePath -ProjectRoot $root Assert-InvokeNovaBuildThrows -ProjectRoot $root -ExpectedError ([pscustomobject]@{ @@ -381,7 +381,7 @@ Describe 'Invoke-NovaBuild options' { It 'FailOnDuplicateFunctionNames=false allows duplicates (last wins) for backward compatibility' { $root = New-TestProjectRoot -TestDriveRoot $TestDrive -Name 'DupAllowed' - Write-TestProjectJson -ProjectRoot $root -Options @{ ProjectName = 'DupAllowed'; BuildRecursiveFolders = $false; FailOnDuplicateFunctionNames = $false } + Write-TestProjectJson -ProjectRoot $root -Options @{ProjectName = 'DupAllowed'; BuildRecursiveFolders = $false; FailOnDuplicateFunctionNames = $false} Set-Content -LiteralPath (Join-Path $root 'src/public/Dup.ps1') -Value 'function Invoke-Dup { "first" }' -Encoding utf8 Set-Content -LiteralPath (Join-Path $root 'src/private/Dup.ps1') -Value 'function Invoke-Dup { "second" }' -Encoding utf8 diff --git a/tests/CodeSceneAnalysis.Tests.ps1 b/tests/CodeSceneAnalysis.Tests.ps1 index 7163c2ed..28266f49 100644 --- a/tests/CodeSceneAnalysis.Tests.ps1 +++ b/tests/CodeSceneAnalysis.Tests.ps1 @@ -74,10 +74,11 @@ function Invoke-WebRequest { "@ $result = Invoke-CodeSceneAnalysisTestScript -RunnerContent $runnerContent + $outputText = ($result.Output -join [Environment]::NewLine) $result.ExitCode | Should -Not -Be 0 - ($result.Output -join [Environment]::NewLine) | Should -Match 'project owner' - ($result.Output -join [Environment]::NewLine) | Should -Match 'separate from CS_ACCESS_TOKEN' + $outputText | Should -Match 'project owner' + $outputText | Should -Match '(?s)separate from.*CS_ACCESS_TOKEN' } It 'still uploads coverage when CoveragePath is provided' { diff --git a/tests/CoverageGaps.ReleaseInternals.Tests.ps1 b/tests/CoverageGaps.ReleaseInternals.Tests.ps1 index 71cbef5f..5927f176 100644 --- a/tests/CoverageGaps.ReleaseInternals.Tests.ps1 +++ b/tests/CoverageGaps.ReleaseInternals.Tests.ps1 @@ -681,7 +681,7 @@ Describe 'Coverage gaps for release and git internals' { $records = @(& {Assert-NovaVersionBumpInferenceAvailability -ProjectRoot $projectRoot -CommitMessages @() -OverrideWarningRequested} 3>&1) - { $null = $records } | Should -Not -Throw + {$null = $records} | Should -Not -Throw @($records | Where-Object {$_ -is [System.Management.Automation.WarningRecord]}).Count | Should -Be 1 (@($records | Where-Object {$_ -is [System.Management.Automation.WarningRecord]} | ForEach-Object Message) -join [Environment]::NewLine) | Should -Match 'Cannot infer the version bump label from Git history' } diff --git a/tests/PackageLatestPolicy.Tests.ps1 b/tests/PackageLatestPolicy.Tests.ps1 index 69cdb1f9..8f27768e 100644 --- a/tests/PackageLatestPolicy.Tests.ps1 +++ b/tests/PackageLatestPolicy.Tests.ps1 @@ -41,7 +41,7 @@ Describe 'Package latest policy behavior' { InModuleScope $script:moduleName -Parameters @{TestCase = $_} { param($TestCase) - $projectRoot = Join-Path $TestDrive "package-latest-$($TestCase.Name)" + $projectRoot = Join-Path $TestDrive "package-latest-$( $TestCase.Name )" New-Item -ItemType Directory -Path $projectRoot -Force | Out-Null $projectJson = ([ordered]@{ ProjectName = 'PackageLatestProject' diff --git a/tests/RemainingHelperCoverage.TestSupport.ps1 b/tests/RemainingHelperCoverage.TestSupport.ps1 index c1f24d52..00dcd607 100644 --- a/tests/RemainingHelperCoverage.TestSupport.ps1 +++ b/tests/RemainingHelperCoverage.TestSupport.ps1 @@ -106,7 +106,7 @@ function Get-TestNovaPackageProjectInfo { $null = $manifest.Remove('LicenseUri') } - if ([string]::IsNullOrWhiteSpace($PackageFileName)) { + if ( [string]::IsNullOrWhiteSpace($PackageFileName)) { $PackageFileName = "PackageProject.$Version.nupkg" } From 1922644c2a2c581a36213c2b7d7d4e0bf4977c50 Mon Sep 17 00:00:00 2001 From: Stiwi Gabriel Courage Date: Tue, 12 May 2026 03:37:23 +0200 Subject: [PATCH 05/31] fix: remove MIT License links from documentation pages - Updated multiple HTML files to remove links to the MIT License - Ensured that the standalone license page remains accessible --- docs/advanced.html | 3 +-- docs/commands.html | 3 +-- docs/core-workflows.html | 3 +-- docs/getting-started.html | 6 ++---- docs/index.html | 3 +-- docs/packaging-and-delivery.html | 3 +-- docs/project-json-reference.html | 6 ++---- docs/release-notes.html | 1 - docs/troubleshooting.html | 3 +-- docs/versioning-and-updates.html | 6 ++---- docs/working-with-modules.html | 6 ++---- 11 files changed, 14 insertions(+), 29 deletions(-) diff --git a/docs/advanced.html b/docs/advanced.html index 2e83efda..06638566 100644 --- a/docs/advanced.html +++ b/docs/advanced.html @@ -210,8 +210,7 @@

Once the model clicks, Nova becomes predictable

Open project.json Reference Open Command Reference - + diff --git a/docs/commands.html b/docs/commands.html index 199eac46..bd7bbce1 100644 --- a/docs/commands.html +++ b/docs/commands.html @@ -638,8 +638,7 @@

Need the next layer of detail?

Open project.json Reference + Modules and Release Notes.

diff --git a/docs/troubleshooting.html b/docs/troubleshooting.html index 178e7efb..bdee8c70 100644 --- a/docs/troubleshooting.html +++ b/docs/troubleshooting.html @@ -327,8 +327,7 @@

If the symptom is clear, the fix is usually short

Open Command Reference Open Core Workflows - +