Skip to content

refactor(scripts): extract pure functions for Pester testability#221

Merged
WilliamBerryiii merged 9 commits intomainfrom
feature/pester-testability-refactoring
Jan 21, 2026
Merged

refactor(scripts): extract pure functions for Pester testability#221
WilliamBerryiii merged 9 commits intomainfrom
feature/pester-testability-refactoring

Conversation

@WilliamBerryiii
Copy link
Copy Markdown
Member

@WilliamBerryiii WilliamBerryiii commented Jan 21, 2026

Description

Refactors four PowerShell scripts to extract pure functions for improved Pester unit testability. This architectural change separates business logic from I/O operations, enabling comprehensive testing without mocking external dependencies.

Changes by Script

Get-VerifiedDownload.ps1

  • Extract hash verification: Get-FileHashValue, Test-HashMatch
  • Extract path resolution: Get-DownloadTargetPath, Test-ExistingFileValid
  • Extract result building: New-DownloadResult, Get-ArchiveType, Test-TarAvailable
  • Add I/O orchestrator: Invoke-VerifiedDownload
  • Add dot-source guard for direct execution

Package-Extension.ps1

  • Extract validation: Test-VsceAvailable, Test-ExtensionManifestValid
  • Extract path/command building: Get-ExtensionOutputPath, Get-VscePackageCommand
  • Extract version resolution: Get-ResolvedPackageVersion
  • Extract result building: New-PackagingResult

Prepare-Extension.ps1

  • Extract maturity filtering: Get-AllowedMaturities
  • Extract validation: Test-PathsExist
  • Extract discovery: Get-DiscoveredAgents, Get-DiscoveredPrompts, Get-DiscoveredInstructions
  • Extract JSON manipulation: Update-PackageJsonContributes
  • Fix bug in Update-PackageJsonContributes using Add-Member for dynamic properties

Generate-PrReference.ps1

  • Add [OutputType()] attributes to existing functions
  • Add explicit param() blocks where missing

Test Coverage

Added four comprehensive Pester test files covering all extracted pure functions with 191 total tests passing.

Related Issue(s)

Closes #200

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation (changes to documentation only)
  • GitHub Actions (changes to CI/CD workflows, actions, or their configurations)
  • Linting (changes to linting rules, configurations, or related scripts)
  • Security (changes that improve or address security vulnerabilities or concerns)
  • DevContainer (changes to the development container configuration)
  • Dependencies (updates to project dependencies, including version bumps and new packages)
  • AI Artifacts (changes to agents, instructions, prompts, or other AI artifacts)
  • Script/automation (.ps1, .sh, .py, etc.)
  • Other (please describe):

Testing

All validation passes:

Pester v5.7.1
Tests completed in 1.48s
Tests Passed: 191, Failed: 0, Skipped: 0

Validation commands run:

  • npm run lint:md - Markdown linting passed
  • npm run lint:frontmatter - Frontmatter validation passed
  • npm run lint:ps - PSScriptAnalyzer passed

Checklist

Required for all contributions

  • I have performed a self-review of my own changes
  • My changes follow the project's coding standards and guidelines
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation (if applicable)
  • My changes generate no new warnings or errors
  • I have added tests that prove my fix is effective or that my feature works

AI Artifact contributions

  • I have tested my AI artifacts with GitHub Copilot
  • My prompts and instructions follow the project's AI artifact guidelines
  • I have validated that my AI artifacts produce consistent, expected outputs

Required automated checks

  • npm run lint:md passes
  • npm run spell-check passes (or words added to custom dictionary)
  • npm run lint:frontmatter passes
  • npm run lint:md-links passes
  • npm run lint:ps passes

Security Considerations

No security implications:

  • No new dependencies introduced
  • No credential handling changes
  • No external API integrations added
  • Pure function extraction maintains existing security boundaries

- refactor Get-VerifiedDownload.ps1 with hash verification and path resolution functions
- refactor Generate-PrReference.ps1 with git output parsing and XML generation functions
- refactor Package-Extension.ps1 with manifest validation and version resolution functions
- refactor Prepare-Extension.ps1 with JSON manipulation and contributor discovery functions
- add 4 comprehensive Pester test files covering all extracted pure functions
- fix bug in Update-PackageJsonContributes using Add-Member for dynamic properties

🧪 - Generated by Copilot
@WilliamBerryiii WilliamBerryiii requested a review from a team as a code owner January 21, 2026 02:01
Copilot AI review requested due to automatic review settings January 21, 2026 02:01
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 21, 2026

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

- Replace Windows-specific paths (C:\temp, C:\ext, C:\nonexistent) with platform-agnostic path construction
- Use [System.IO.Path]::Combine() and [System.IO.Path]::GetTempPath() for test directories
- Fixes CI failures on Linux runners

🔧 - Generated by Copilot
- Add entry point guard to Generate-PrReference.ps1 to prevent execution when dot-sourced
- Replace #Requires -Modules with runtime check in Prepare-Extension.ps1 entry point
- Both changes allow test files to dot-source scripts without triggering execution or module errors

🔧 - Generated by Copilot
Copilot AI review requested due to automatic review settings January 21, 2026 02:59
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 7 comments.

- change Get-CommitCount assertion to BeGreaterOrEqual 1 (merge commits inflate count)
- add dynamic branch detection fallback for shallow CI checkouts
- add skip conditions for YAML-dependent tests when PowerShell-Yaml unavailable

🔧 - Generated by Copilot
- Get-FrontmatterData performs I/O via Get-Content and ConvertFrom-Yaml
- Test-PathsExist performs I/O via Test-Path
- Get-DiscoveredAgents performs I/O via Get-ChildItem and Test-Path
- Get-DiscoveredPrompts performs I/O via Get-ChildItem and Test-Path
- Get-DiscoveredInstructions performs I/O via Get-ChildItem and Test-Path

📝 - Generated by Copilot
Copilot AI review requested due to automatic review settings January 21, 2026 03:28
- Invoke-PrReferenceGeneration Describe block was truncated
- File ended without closing It block and Describe block braces

🔧 - Generated by Copilot
- add Get-CurrentBranchOrRef helper function
- fall back to detached@<sha> when git branch --show-current returns empty
- add unit tests for new function

🔧 - Generated by Copilot
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

scripts/dev-tools/Generate-PrReference.ps1:457

  • These lines have inconsistent indentation compared to surrounding code. They should be indented to align with other statements in the try block (lines 449-455).
    $commitEntries = Get-CommitEntry -ComparisonRef $comparisonInfo.Ref
        $commitCount = Get-CommitCount -ComparisonRef $comparisonInfo.Ref
        $diffOutput = Get-DiffOutput -ComparisonRef $comparisonInfo.Ref -ExcludeMarkdownDiff:$ExcludeMarkdownDiff
        $diffSummary = Get-DiffSummary -ComparisonRef $comparisonInfo.Ref -ExcludeMarkdownDiff:$ExcludeMarkdownDiff

    $xmlContent = Get-PrXmlContent -CurrentBranch $currentBranch -BaseBranch $BaseBranch -CommitEntries $commitEntries -DiffOutput $diffOutput

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Copy Markdown
Contributor

@katriendg katriendg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one!

@WilliamBerryiii WilliamBerryiii merged commit d40e742 into main Jan 21, 2026
15 checks passed
@WilliamBerryiii WilliamBerryiii deleted the feature/pester-testability-refactoring branch January 21, 2026 17:39
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Issue]: Add Pester tests for dev-tools and extension scripts (4 scripts)

3 participants