refactor(scripts): extract frontmatter validation to testable module#293
Merged
WilliamBerryiii merged 16 commits intomainfrom Jan 26, 2026
Merged
refactor(scripts): extract frontmatter validation to testable module#293WilliamBerryiii merged 16 commits intomainfrom
WilliamBerryiii merged 16 commits intomainfrom
Conversation
- Create FrontmatterValidation.psm1 with ValidationIssue and FileTypeInfo classes - Extract 6 content-type validators and 4 shared helper functions - Add comprehensive unit tests (67+ test cases for module) - Remove ~550 lines of duplicated code from main script 🧪 - Generated by Copilot
…n module - Extract parsing, validation, and output functions into new FrontmatterValidation.psm1 module - Replace 500+ line god function with thin wrapper delegating to module - Add ValidationSummary return type with GetExitCode method for cleaner API - Update integration tests for ValidationSummary interface (TotalFiles, TotalErrors, TotalWarnings) 🧹 - Generated by Copilot
- extract ValidationIssue, FileValidationResult, ValidationSummary classes - extract 18 public functions to FrontmatterValidation.psm1 - convert main script to thin orchestration wrapper - achieve 96.33% test coverage (target: 80%) 🔧 - Generated by Copilot
… test coverage - remove duplicate FrontmatterResult class, ConvertFrom-YamlFrontmatter, Get-MarkdownFrontmatter from main script - update schema validation to use frontmatter from module's FileValidationResult - add 11 tests for Initialize-JsonSchemaValidation, Get-SchemaForFile pattern matching, ChangedFilesOnly mode - improve coverage from 78.41% to 82.58% (110 tests) 🧹 - Generated by Copilot
- Remove unused param declarations in FileReader scriptblocks - Fix unused BaseBranch parameter and result variables - Add UTF-8 BOM encoding to FrontmatterValidation.Tests.ps1 - Remove 10 obsolete tests for deleted functions 🧹 - Generated by Copilot
Contributor
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
Contributor
There was a problem hiding this comment.
Pull request overview
Refactors markdown frontmatter validation by extracting the core validation logic into a dedicated PowerShell module to improve testability and unit coverage.
Changes:
- Introduces
scripts/linting/Modules/FrontmatterValidation.psm1containing validation types, validators, orchestration, and output helpers. - Refactors
scripts/linting/Validate-MarkdownFrontmatter.ps1into a thinner wrapper that delegates to the new module. - Updates and expands Pester coverage via a new module-focused test suite and updates to existing validation tests.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 10 comments.
| File | Description |
|---|---|
| scripts/linting/Validate-MarkdownFrontmatter.ps1 | Imports and delegates validation to the new module; updates result model and orchestration. |
| scripts/linting/Modules/FrontmatterValidation.psm1 | New module implementing frontmatter parsing, file-type routing, validation rules, and output/export formatting. |
| scripts/tests/linting/FrontmatterValidation.Tests.ps1 | Adds comprehensive unit tests for the new module and some wrapper-level behavior. |
| scripts/tests/linting/Validate-MarkdownFrontmatter.Tests.ps1 | Updates existing tests to the new ValidationSummary result model and adds new scenarios. |
- Replace hardcoded Windows paths (C:\test\repo) with TestDrive - Use Join-Path instead of string interpolation with backslashes - Add Push-Location/Pop-Location for Test-Path relative path resolution - Use platform-specific directory separator in path assertions 🐛 - Generated by Copilot
- add SkipFooterValidation parameter (Fix #1) - add agent.md classification with IsAgent property (Fix #3) - use RelativePath in GitHub annotations (Fix #5) - remove misleading 'pure' header claim (Fix #6) - remove hardcoded creation date (Fix #7) - fix regex for empty frontmatter (Fix #8) - add workflow command escaping for security (Fix #10) - remove type constraints for testability (PowerShell class identity) 🔧 - Generated by Copilot
- Change ConvertFrom-Yaml check from throw to error result - Add SkipFooterValidation parameter chain to main execution - Add YAML support skip checks to 17 tests requiring powershell-yaml 🔧 - Generated by Copilot
- add YAML support detection to skip tests when powershell-yaml unavailable - fix ChangedFilesOnly to return success when no markdown files changed - fix IsAgent handling in Test-GitHubResourceFileFields - add Test-CommonFields call for keywords and reading time validation - fix footer severity routing for root community and config files - implement full GitHub workflow command escaping 🔧 - Generated by Copilot
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #293 +/- ##
==========================================
+ Coverage 29.94% 38.21% +8.27%
==========================================
Files 14 15 +1
Lines 2785 2805 +20
==========================================
+ Hits 834 1072 +238
+ Misses 1951 1733 -218
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
…lesOnly exit code - add 8 tests for ConvertTo-GitHubCommandMessage escaping (%, CR, LF, ::, null) - add 8 tests for ConvertTo-GitHubCommandProperty escaping (%, CR, LF, :, ,, null) - update ChangedFilesOnly test to expect TotalFiles=1 (success exit code) 🔧 - Generated by Copilot
- make YAML parsing graceful with warning instead of hard error - detect file type before missing frontmatter warning (skip AI artifacts) - call Complete() on empty summary in ChangedFilesOnly mode - show warning icon for files with warnings but no errors - exclude strings from array type validation (IEnumerable fix) - update test to expect error for string in array field 🔧 - Generated by Copilot
- add GetNewClosure() to FileReader scriptblocks in Test-SingleFileFrontmatter tests - fixes variable capture across module boundaries on Linux/PowerShell Core - ensures mockContent variable is available when invoked from module scope 🔧 - Generated by Copilot
- add PowerShell-Yaml install step to pester-tests.yml workflow - change FrontmatterValidation.psm1 to error (not warn) when YAML missing - remove hasYamlSupport skip logic from 3 test files (~21 tests now run) 📦 - Generated by Copilot
- return accurate TotalFiles=0 for ChangedFilesOnly empty case - replace hardcoded Windows paths with cross-platform $TestDrive - add UTF-8 BOM encoding for non-ASCII test file 🔧 - Generated by Copilot
katriendg
approved these changes
Jan 26, 2026
WilliamBerryiii
pushed a commit
that referenced
this pull request
Jan 28, 2026
🤖 I have created a release *beep* *boop* --- ## [2.0.0](hve-core-v1.1.0...hve-core-v2.0.0) (2026-01-28) ### ⚠ BREAKING CHANGES * **agents:** add Task Reviewer and expand RPI to 4-phase workflow ([#277](#277)) ### ✨ Features * **agents:** add hve-core-installer agent to extension package ([#297](#297)) ([c0e48c6](c0e48c6)) * **agents:** add Task Reviewer and expand RPI to 4-phase workflow ([#277](#277)) ([ae76cab](ae76cab)) * **build:** add code coverage reporting to Pester workflow ([#230](#230)) ([a34822a](a34822a)) * **docs:** add GOVERNANCE.md for OSSF Silver Badge compliance ([#235](#235)) ([b0e752c](b0e752c)) * **docs:** add ROADMAP.md for OSSF Silver badge compliance ([#238](#238)) ([4a41c16](4a41c16)) * **mcp:** add MCP server configuration guidance and installer enhancements ([#225](#225)) ([0bce418](0bce418)) * **scripts:** add YAML linting with actionlint ([#234](#234)) ([d9301f9](d9301f9)) * **security:** add OpenSSF Scorecard workflow and badge ([#271](#271)) ([7c6d788](7c6d788)) * **skills:** add video-to-gif conversion skill with FFmpeg two-pass optimization ([#247](#247)) ([8d65c42](8d65c42)) * **tests:** add Pester tests for LintingHelpers and Validate-MarkdownFrontmatter ([#197](#197), [#198](#198)) ([#205](#205)) ([51ae563](51ae563)) ### 🐛 Bug Fixes * **build:** detect table formatting changes via git diff ([#261](#261)) ([985eee0](985eee0)) * **build:** disable MD024 lint rule in CHANGELOG for release-please ([#220](#220)) ([971df94](971df94)) * **build:** quote shell variables and group redirects in workflow files ([#299](#299)) ([3372509](3372509)) * **build:** resolve scorecard badge and workflow security issues ([#301](#301)) ([aeaed13](aeaed13)) * **extension:** remove frontmatter from README and exclude from markdown linting ([#223](#223)) ([4272529](4272529)) * **instructions:** quote applyTo glob pattern for YAML compatibility ([#216](#216)) ([085199c](085199c)) * **scripts:** add FooterExcludePaths parameter to frontmatter validation ([#334](#334)) ([64db98d](64db98d)) * **scripts:** add GHSA word and logs/ exclusion to cspell config ([#214](#214)) ([5c99b3f](5c99b3f)) * **scripts:** correct type assertions in Invoke-YamlLint.Tests.ps1 ([#332](#332)) ([af7050d](af7050d)) * **scripts:** eliminate false positives in dependency pinning npm pattern ([#273](#273)) ([ccbdfa3](ccbdfa3)) * **security:** add artifact attestation for signed releases ([#257](#257)) ([c52d6e2](c52d6e2)) * standardize markdown footers and complete frontmatter ([#217](#217)) ([b4e7556](b4e7556)) ### 📚 Documentation * add OpenSSF Best Practices Passing badge to README ([#239](#239)) ([91bc529](91bc529)) * **architecture:** add architecture documentation and value proposition ([#252](#252)) ([0e4b02f](0e4b02f)) * **contributing:** add testing requirements for OSSF compliance ([#254](#254)) ([4db1a18](4db1a18)) * **docs:** add enterprise status badges to README header ([#270](#270)) ([ccb68a4](ccb68a4)) * **security:** add security assurance case and threat model for OSSF Silver ([#259](#259)) ([a390e26](a390e26)) ### ♻️ Refactoring * **application:** wrap execution with try blocks, ensure proper … ([#296](#296)) ([35c4417](35c4417)) * **scripts:** extract frontmatter validation to testable module ([#293](#293)) ([4e8707e](4e8707e)) * **scripts:** extract pure functions for Pester testability ([#221](#221)) ([d40e742](d40e742)) ### 🔧 Maintenance * **deps-dev:** bump cspell from 9.4.0 to 9.6.0 in the npm-dependencies group ([#208](#208)) ([855914b](855914b)) * **deps-dev:** bump cspell from 9.6.0 to 9.6.1 in the npm-dependencies group ([#294](#294)) ([1e45ad6](1e45ad6)) * **deps:** bump actions/setup-node from 6.1.0 to 6.2.0 in the github-actions group ([#209](#209)) ([c4c69e2](c4c69e2)) * **deps:** bump the github-actions group with 4 updates ([#295](#295)) ([d8337b8](d8337b8)) * remove step-security/harden-runner from workflows ([#246](#246)) ([c5708d8](c5708d8)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: hve-core-release-please[bot] <254602402+hve-core-release-please[bot]@users.noreply.github.com>
This was referenced Jan 28, 2026
This was referenced Feb 6, 2026
This was referenced Feb 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
refactor(scripts): extract frontmatter validation to testable module
Description
Extract frontmatter validation logic from
Validate-MarkdownFrontmatter.ps1into a dedicated testable module (FrontmatterValidation.psm1), addressing the testability concerns raised in issue #266.Key changes:
New module:
FrontmatterValidation.psm1(1,039 lines) containing:ValidationIssue,FileTypeInfo,FileValidationResult,ValidationSummaryTest-RequiredField,Test-DateFormat,Test-SuggestedFields,Test-TopicValueTest-CommonFields,Test-MarkdownFooter,Test-SingleFileFrontmatter,Invoke-FrontmatterValidationWrite-ValidationConsoleOutput,Write-GitHubAnnotationsNew test suite:
FrontmatterValidation.Tests.ps1(1,553 lines) with comprehensive coverageRefactored main script:
Validate-MarkdownFrontmatter.ps1is now a thin orchestration wrapperRemoved ~550 lines of duplicate code from main script
Related Issue(s)
Closes #266
Type of Change
Select all that apply:
Code & Documentation:
Infrastructure & Configuration:
AI Artifacts:
prompt-builderagent and addressed all feedback.github/instructions/*.instructions.md).github/prompts/*.prompt.md).github/agents/*.agent.md)Other:
.ps1,.sh,.py)Sample Prompts (for AI Artifact Contributions)
Testing
Checklist
Required Checks
AI Artifact Contributions
Required Automated Checks
The following validation commands must pass before merging:
npm run lint:mdnpm run spell-checknpm run lint:frontmatternpm run lint:md-linksnpm run lint:psSecurity Considerations
No security concerns. Internal refactoring of development tooling with no changes to authentication, data handling, external dependencies, or network communication.
Additional Notes
Architecture Benefits
API Changes
Internal API surface changed (
ValidationResult→ValidationSummary), but external behavior remains compatible. Integration tests updated for new type names.🔧 - Generated by Copilot