Skip to content

Conversation

@WilliamBerryiii
Copy link
Member

Description

Refactored CI helper usage in linting and security scripts, expanded CI helper APIs, and aligned tests and documentation with the new behavior.

  • Extended CI helpers with environment flag and annotation helpers, plus coverage for new APIs.
  • Reworked linting scripts to rely on CI helper outputs and annotations, including the link language check core flow.
  • Hardened security and utility scripts with CI helper usage, response parsing improvements, and updated error handling.
  • Updated linting and security tests and mocks to use CI helper APIs and removed GitHub helper-specific coverage.
  • Updated GitHub documentation and removed the copilot setup workflow.

Related Issue(s)

Related to #351

Type of Change

Select all that apply:

Code & Documentation:

  • Bug fix (non-breaking change fixing an issue)
  • New feature (non-breaking change adding functionality)
  • Breaking change (fix or feature causing existing functionality to change)
  • Documentation update

Infrastructure & Configuration:

  • GitHub Actions workflow
  • Linting configuration (markdown, PowerShell, etc.)
  • Security configuration
  • DevContainer configuration
  • Dependency update

AI Artifacts:

  • Reviewed contribution with prompt-builder agent and addressed all feedback
  • Copilot instructions (.github/instructions/*.instructions.md)
  • Copilot prompt (.github/prompts/*.prompt.md)
  • Copilot agent (.github/agents/*.agent.md)

Note for AI Artifact Contributors:

  • Agents: Research, indexing/referencing other project (using standard VS Code GitHub Copilot/MCP tools), planning, and general implementation agents likely already exist. Review .github/agents/ before creating new ones.
  • Model Versions: Only contributions targeting the latest Anthropic and OpenAI models will be accepted. Older model versions (e.g., GPT-3.5, Claude 3) will be rejected.
  • See Agents Not Accepted and Model Version Requirements.

Other:

  • Script/automation (.ps1, .sh, .py)
  • Other (please describe):

Testing

Checklist

Required Checks

  • Documentation is updated (if applicable)
  • Files follow existing naming conventions
  • Changes are backwards compatible (if applicable)
  • Tests added for new functionality (if applicable)

Required Automated Checks

The following validation commands must pass before merging:

  • Markdown linting: npm run lint:md
  • Spell checking: npm run spell-check
  • Frontmatter validation: npm run lint:frontmatter
  • Link validation: npm run lint:md-links
  • PowerShell analysis: npm run lint:ps

Security Considerations

  • This PR does not contain any sensitive or NDA information
  • Any new dependencies have been reviewed for security issues
  • Security-related scripts follow the principle of least privilege

@WilliamBerryiii WilliamBerryiii requested a review from a team as a code owner February 3, 2026 19:38
Copilot AI review requested due to automatic review settings February 3, 2026 19:38
Copy link
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

Refactors linting and security PowerShell scripts to standardize CI integration via the shared CIHelpers module, and updates tests/mocks/docs to match the new CI helper APIs and behaviors.

Changes:

  • Expanded CIHelpers.psm1 with new helpers (notably CI env-var support and bulk annotation emission) and added/updated Pester coverage.
  • Updated linting and security scripts to use CI helper outputs/annotations and introduced skip-main patterns to make scripts more testable.
  • Updated Pester tests and mocks to use CI-focused environment helpers instead of GitHub-specific helpers, and refreshed linting documentation.

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
scripts/tests/security/Update-ActionSHAPinning.Tests.ps1 Switches tests to dot-source the script with HVE_SKIP_MAIN and uses CI environment mocks.
scripts/tests/security/Test-SHAStaleness.Tests.ps1 Switches tests to dot-source the script with HVE_SKIP_MAIN and uses CI environment mocks.
scripts/tests/linting/Validate-MarkdownFrontmatter.Tests.ps1 Updates tests to CI naming and validates CI annotation integration paths.
scripts/tests/linting/Markdown-Link-Check.Tests.ps1 Updates tests to dot-source with HVE_SKIP_MAIN for function access without executing main.
scripts/tests/linting/LintingHelpers.Tests.ps1 Removes GitHub-helper-focused coverage and narrows tests to core linting helper behaviors.
scripts/tests/linting/Link-Lang-Check.Tests.ps1 Updates tests to dot-source with HVE_SKIP_MAIN for function access without executing main.
scripts/tests/linting/Invoke-YamlLint.Tests.ps1 Updates mocks/assertions from GitHub helpers to CI helpers (Set-CIOutput, Write-CIAnnotation, etc.).
scripts/tests/linting/Invoke-PSScriptAnalyzer.Tests.ps1 Updates mocks/assertions from GitHub helpers to CI helpers and CI integration naming.
scripts/tests/linting/Invoke-LinkLanguageCheck.Tests.ps1 Adds unit coverage for the new core flow and updates CI helper export expectations.
scripts/tests/linting/FrontmatterValidation.Tests.ps1 Updates tests to validate Write-CIAnnotations behavior.
scripts/tests/lib/CIHelpers.Tests.ps1 Adds/updates coverage for new CI helper APIs (including env var helper and bulk annotation helper).
scripts/tests/Mocks/GitMocks.psm1 Renames and generalizes mock helpers from GitHub-specific to CI-oriented environment helpers.
scripts/security/Update-ActionSHAPinning.ps1 Improves response parsing/error handling and adds HVE_SKIP_MAIN to prevent executing main during tests.
scripts/security/Test-SHAStaleness.ps1 Adds HVE_SKIP_MAIN guard around main execution for testability.
scripts/linting/Validate-MarkdownFrontmatter.ps1 Replaces GitHub-only checks with Test-CIEnvironment and CI helper annotation/summary/env helpers.
scripts/linting/README.md Updates linting documentation to describe CI helper integration and exported helper APIs.
scripts/linting/Modules/LintingHelpers.psm1 Removes GitHub-specific helper implementations and aligns module surface toward CI helpers + file/git helpers.
scripts/linting/Modules/FrontmatterValidation.psm1 Removes GitHub-specific annotation helper implementation from the module.
scripts/linting/Markdown-Link-Check.ps1 Adds HVE_SKIP_MAIN and replaces GitHub helper usage with CI helper annotations/summary/env helpers.
scripts/linting/Link-Lang-Check.ps1 Adds HVE_SKIP_MAIN and replaces GitHub-only failure annotation with CI helper annotation.
scripts/linting/Invoke-YamlLint.ps1 Replaces GitHub helper outputs/annotations/summary/env with CI helpers.
scripts/linting/Invoke-PSScriptAnalyzer.ps1 Replaces GitHub helper outputs/annotations/summary/env with CI helpers and maps severities to CI levels.
scripts/linting/Invoke-LinkLanguageCheck.ps1 Refactors into a testable core function and switches annotations/outputs/env/summary to CI helpers.
scripts/lib/Modules/CIHelpers.psm1 Adds CI env var helper and bulk annotation helper; expands exported CI integration surface.
Comments suppressed due to low confidence (1)

scripts/security/Test-SHAStaleness.ps1:83

  • Even when $env:HVE_SKIP_MAIN is set (tests dot-source this script), the script still creates the log directory at import time. This is a side effect outside the guarded main block and can cause tests to write to the repo filesystem unexpectedly. Consider moving the log directory creation behind the skip-main guard (or lazily creating it inside Write-SecurityLog) so loading functions for tests is side-effect free.
$script:SkipMain = $env:HVE_SKIP_MAIN -eq '1'

# Ensure logging directory exists
$LogDir = Split-Path -Parent $LogPath
if (!(Test-Path $LogDir)) {
    New-Item -ItemType Directory -Path $LogDir -Force | Out-Null
}

WilliamBerryiii and others added 2 commits February 3, 2026 19:23
- replace GitHub Actions helpers across linting scripts
- extend CIHelpers for env and annotations with tests
- update linting and security test mocks for CI integration
- document CIHelpers usage in linting README

🔧 - Generated by Copilot
- Standardize SPDX-License-Identifier headers across 7 files
- Fix HVE_SKIP_MAIN handling in integration test contexts
- Add ErrorAction Continue to prevent terminating errors in catch blocks
- Remove legacy Created date headers from script files

🔧 - Generated by Copilot

Co-authored-by: littleKitchen <55852668+littleKitchen@users.noreply.github.com>
@WilliamBerryiii WilliamBerryiii force-pushed the refactor/351-linting-cihelpers branch from fbd8cc4 to d680c7d Compare February 4, 2026 05:42
@github-actions
Copy link

github-actions bot commented Feb 4, 2026

Dependency Review

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

Scanned Files

None

@codecov-commenter
Copy link

codecov-commenter commented Feb 4, 2026

Codecov Report

❌ Patch coverage is 69.16300% with 70 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.53%. Comparing base (1dd31ad) to head (f31b10f).

Files with missing lines Patch % Lines
scripts/security/Update-ActionSHAPinning.ps1 57.64% 36 Missing ⚠️
scripts/linting/Markdown-Link-Check.ps1 12.50% 14 Missing ⚠️
scripts/linting/Invoke-LinkLanguageCheck.ps1 87.23% 6 Missing ⚠️
scripts/security/Test-SHAStaleness.ps1 37.50% 5 Missing ⚠️
scripts/linting/Link-Lang-Check.ps1 33.33% 4 Missing ⚠️
scripts/linting/Invoke-PSScriptAnalyzer.ps1 83.33% 3 Missing ⚠️
scripts/linting/Invoke-YamlLint.ps1 91.66% 1 Missing ⚠️
scripts/linting/Validate-MarkdownFrontmatter.ps1 83.33% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##             main     #401       +/-   ##
===========================================
+ Coverage   60.96%   74.53%   +13.57%     
===========================================
  Files          19       19               
  Lines        3233     3295       +62     
===========================================
+ Hits         1971     2456      +485     
+ Misses       1262      839      -423     
Flag Coverage Δ
pester 74.53% <69.16%> (+13.57%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
scripts/lib/Modules/CIHelpers.psm1 95.58% <100.00%> (+1.19%) ⬆️
scripts/linting/Modules/FrontmatterValidation.psm1 96.02% <ø> (-0.27%) ⬇️
scripts/linting/Modules/LintingHelpers.psm1 100.00% <ø> (ø)
scripts/linting/Invoke-YamlLint.ps1 95.83% <91.66%> (+2.59%) ⬆️
scripts/linting/Validate-MarkdownFrontmatter.ps1 65.45% <83.33%> (+0.58%) ⬆️
scripts/linting/Invoke-PSScriptAnalyzer.ps1 92.30% <83.33%> (+0.30%) ⬆️
scripts/linting/Link-Lang-Check.ps1 48.14% <33.33%> (+48.14%) ⬆️
scripts/security/Test-SHAStaleness.ps1 56.44% <37.50%> (+7.79%) ⬆️
scripts/linting/Invoke-LinkLanguageCheck.ps1 90.00% <87.23%> (+90.00%) ⬆️
scripts/linting/Markdown-Link-Check.ps1 30.12% <12.50%> (+30.12%) ⬆️
... and 1 more

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@WilliamBerryiii
Copy link
Member Author

@littleKitchen - This PR is ready for review! It incorporates the learnings from your work on PR #379 and implements the script-as-orchestrator pattern we discussed.

Changes in latest commits:

  • Standardized SPDX-License-Identifier headers across 7 files
  • Fixed HVE_SKIP_MAIN handling in integration test contexts
  • Added ErrorAction Continue to prevent terminating errors in catch blocks
  • All 850 tests passing

Would appreciate your eyes on it when you have a chance. 🙏

- sanitize file paths in step summaries for AzDO injection prevention

- move Set-StrictMode inside SkipMain guard to prevent test scope leak

- add ExcludePaths param to mock scripts in Link-Lang-Check tests

- update README documentation for LintingHelpers module exports

🔒 - Generated by Copilot
Copilot AI review requested due to automatic review settings February 4, 2026 06:11
Copy link
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 25 out of 25 changed files in this pull request and generated 6 comments.

GeneratedAt = Get-Date -Format "yyyy-MM-dd HH:mm:ss UTC"
Summary = @{
TotalWorkflows = @($Results).Count
WorkflowsChanged = @($Results | Where-Object { $_.PSObject.Properties.Name -contains 'ContentChanged' -and $_.ContentChanged }).Count
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

WorkflowsChanged is computed via Where-Object { $_.PSObject.Properties.Name -contains 'ContentChanged' -and $_.ContentChanged }. Since workflow results are hashtables, the PSObject.Properties check can miss keys and undercount changed workflows. Make this hashtable-safe (for example, branch on -is [hashtable] and use ContainsKey('ContentChanged')/indexing), matching the approach used for the action count sums above.

Suggested change
WorkflowsChanged = @($Results | Where-Object { $_.PSObject.Properties.Name -contains 'ContentChanged' -and $_.ContentChanged }).Count
WorkflowsChanged = @(
$Results | Where-Object {
if ($_ -is [hashtable]) {
$_.ContainsKey('ContentChanged') -and $null -ne $_['ContentChanged'] -and [bool]$_['ContentChanged']
}
else {
$_.PSObject.Properties.Name -contains 'ContentChanged' -and $null -ne $_.ContentChanged -and [bool]$_.ContentChanged
}
}
).Count

Copilot uses AI. Check for mistakes.
Comment on lines 348 to +355
foreach ($link in $brokenLinks) {
$summaryContent += "`n| ``$($link.File)`` | ``$($link.Link)`` |"
$safeFile = if ((Get-CIPlatform) -eq 'azdo') {
ConvertTo-AzureDevOpsEscaped -Value $link.File
} else { $link.File }
$safeLink = if ((Get-CIPlatform) -eq 'azdo') {
ConvertTo-AzureDevOpsEscaped -Value $link.Link
} else { $link.Link }
$summaryContent += "`n| ``$safeFile`` | ``$safeLink`` |"
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

Get-CIPlatform is called twice per broken link when building the step summary table. Since this loop can run for many links, compute the platform once before the loop and reuse it (and only call ConvertTo-AzureDevOpsEscaped when needed) to avoid repeated platform detection work.

Copilot uses AI. Check for mistakes.
Comment on lines +81 to +82
$script:SkipMain = $env:HVE_SKIP_MAIN -eq '1'

Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

$script:SkipMain is intended to allow dot-sourcing for tests without side effects, but the script still performs script-level I/O after this point (for example, ensuring the log directory exists) even when HVE_SKIP_MAIN=1. Consider extending the skip-main guard to cover those script-level side effects as well, so importing the functions does not create/modify files during unit tests.

Copilot uses AI. Check for mistakes.
Comment on lines 23 to 26
* **Core Scripts** - Existing validation logic (e.g., `Link-Lang-Check.ps1`, `Validate-MarkdownFrontmatter.ps1`)
* **Shared Module** (`Modules/LintingHelpers.psm1`) - Common functions for GitHub Actions integration
* **Shared Module** (`Modules/LintingHelpers.psm1`) - Common functions for file discovery and git operations
* **CI Helpers** (`scripts/lib/Modules/CIHelpers.psm1`) - CI annotations, outputs, env flags, and step summaries
* **Configuration Files** - Tool-specific settings (e.g., `PSScriptAnalyzer.psd1`, `markdown-link-check.config.json`)
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

PR description mentions that the Copilot setup workflow was removed, but .github/workflows/copilot-setup-steps.yml is still present in this change set. Either update the PR description to reflect the current state, or remove/disable the workflow if that was the intent.

Copilot uses AI. Check for mistakes.
Describe 'Write-GitHubAnnotations' -Tag 'Unit' {
Describe 'Write-CIAnnotations' -Tag 'Unit' {
BeforeAll {
Import-Module (Join-Path $PSScriptRoot '../../linting/Modules/FrontmatterValidation.psm1') -Force
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

This Write-CIAnnotations test block calls Write-CIAnnotations, but its BeforeAll only imports FrontmatterValidation.psm1. Unless CIHelpers.psm1 was imported by a previously-run Describe, these tests can fail or become order-dependent (and can break under tag filtering). Import scripts/lib/Modules/CIHelpers.psm1 in this block’s BeforeAll (and optionally remove it in AfterAll) so the tests are self-contained.

Suggested change
Import-Module (Join-Path $PSScriptRoot '../../linting/Modules/FrontmatterValidation.psm1') -Force
Import-Module (Join-Path $PSScriptRoot '../../linting/Modules/FrontmatterValidation.psm1') -Force
Import-Module (Join-Path $PSScriptRoot '../../lib/Modules/CIHelpers.psm1') -Force

Copilot uses AI. Check for mistakes.
Comment on lines +923 to +927
if (-not $script:SkipMain) {
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

try {
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

Inside the main execution block (guarded by $script:SkipMain), the summary still aggregates $results using Measure-Object ... -Sum and PSObject.Properties checks later in the block. Since Update-WorkflowFile returns hashtables, those aggregations are likely to produce incorrect totals. Prefer hashtable-aware aggregation (ContainsKey/indexing) or cast each result to [pscustomobject] before computing totals/counts so CI summaries stay accurate.

Copilot uses AI. Check for mistakes.
}
catch {
Write-SecurityLog "Critical error in SHA pinning process: $($_.Exception.Message)" -Level 'Error'
if ($env:GITHUB_ACTIONS -eq 'true') {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: should this one be Write-CIAnnotation now?

}
catch {
Write-Error "Test SHA Staleness failed: $($_.Exception.Message)"
if ($env:GITHUB_ACTIONS -eq 'true') {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Write-CIAnnotation like the others?

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.

5 participants