Skip to content

Test-SHAStaleness.ps1 missing Write-CIStepSummary in GitHub Actions #633

@WilliamBerryiii

Description

@WilliamBerryiii

Summary

Test-SHAStaleness.ps1 provides good console output via Write-SecurityLog (color-coded Write-Host in console mode) and emits per-dependency Write-CIAnnotation calls in GitHub output mode — but it never calls Write-CIStepSummary. The GitHub Actions job summary tab remains empty for SHA staleness checks; users must expand the full log or download the sha-staleness-results.json artifact to understand results.

Current Behavior

  • Console output: Write-SecurityLog function (lines 95–124) provides color-coded Write-Host output in console mode. ✅
  • CI annotations: Per-dependency Write-CIAnnotation calls (lines 698–718) in GitHub output format — Notice level when clean, Error level for stale dependencies. ✅
  • Step summary: No Write-CIStepSummary call anywhere in the script. ❌
  • Workflow compensation: The workflow sha-staleness-check.yml uses inline ::warning annotations in YAML but does not produce a step summary either.

Expected Behavior

After the per-dependency annotation loop and before returning the results object, the script should call Write-CIStepSummary with a markdown summary table showing:

  • Total dependencies scanned
  • Stale dependency count and details (dependency name, current SHA age, threshold)
  • Clean dependency count
  • Overall compliance status (pass/fail)

Root Cause

The GitHub output format branch (lines 680–720) writes annotations and JSON output but skips Write-CIStepSummary. Compare with Invoke-PSScriptAnalyzer.ps1 and scripts/security/Test-DependencyPinning.ps1 (line 782), which both call Write-CIStepSummary.

Files Requiring Changes

File Change
scripts/security/Test-SHAStaleness.ps1 Add Write-CIStepSummary call with markdown table after the annotation loop in the GitHub output format branch (~line 718)
scripts/tests/security/Test-SHAStaleness.Tests.ps1 Add mocks and assertions for Write-CIStepSummary; add Write-CIAnnotation mock assertions

Reproduction Steps

  1. Run Test-SHAStaleness.ps1 -OutputFormat github in a GitHub Actions environment (or locally with GITHUB_ACTIONS=true).
  2. Check the GitHub Actions job summary tab — it is empty.
  3. Compare with Test-DependencyPinning.ps1, which populates the summary tab.

Fix Guidance

Follow the pattern from Test-DependencyPinning.ps1 (line 782):

# After the annotation loop, before returning results
$summaryLines = @(
    "## SHA Staleness Check Results"
    ""
    "| Dependency | Age (days) | Threshold | Status |"
    "|-----------|-----------|-----------|--------|"
)

foreach ($dep in $results) {
    $status = if ($dep.IsStale) { "❌ Stale" } else { "✅ Current" }
    $summaryLines += "| $($dep.Name) | $($dep.AgeDays) | $($dep.MaxAge) | $status |"
}

$summaryLines += ""
$summaryLines += "**Total**: $($results.Count) dependencies, $($staleCount) stale"

Write-CIStepSummary -Summary ($summaryLines -join "`n")

Unit Testing and Code Coverage Requirements

Codecov Configuration

The repository enforces an auto-incrementing project coverage threshold (+1% over base) and an 80% patch target (codecov.yml). All new or modified lines must meet the patch coverage gate.

Pester Coverage

  • Config: scripts/tests/pester.config.ps1 — JaCoCo format, CoveragePercentTarget = 80
  • Coverage path: scripts/security/ is already in the coverage scan scope
  • Run: npm run test:ps

Current Test Gap

The existing test file scripts/tests/security/Test-SHAStaleness.Tests.ps1 (578+ lines) covers Test-GitHubToken, Invoke-GitHubAPIWithRetry, Write-SecurityLog, Compare-ToolVersion, Get-ToolStaleness, and main script execution — but has no mocks for Write-CIAnnotation, Write-CIStepSummary, or Write-Host. When adding Write-CIStepSummary:

  1. Mock Write-CIStepSummary — add mock and Should -Invoke assertion verifying the markdown summary content (dependency table, counts, status).
  2. Mock Write-CIAnnotation — the script already calls this per dependency, but tests don't verify it. Add mock with -ParameterFilter assertions for correct -Level and -Message per dependency.
  3. Mock Write-Host (via Write-SecurityLog) — verify console output content matches expected color-coded patterns.

RPI Phase Testing Guidance

  • Research: Audit Test-SHAStaleness.Tests.ps1 for CI helper coverage gaps; document the GitHub output format branch (lines 680–720).
  • Plan: Design test cases for Write-CIStepSummary markdown content and Write-CIAnnotation per-dependency assertions.
  • Implement: Add mock infrastructure for all CI helper functions; verify npm run test:ps passes with patch coverage ≥ 80%.
  • Review: Confirm no coverage regressions in the pester flag on Codecov.

RPI Framework Starter Prompts

Research Phase

Research CI output coverage in scripts/security/Test-SHAStaleness.ps1. Document: (1) the GitHub output format branch (lines 680–720), noting per-dependency Write-CIAnnotation calls with Notice/Error levels, (2) the Write-SecurityLog function (lines 95–124) providing color-coded console output, (3) the absence of Write-CIStepSummary, (4) the workflow file .github/workflows/sha-staleness-check.yml output configuration, (5) existing Pester test coverage in scripts/tests/security/Test-SHAStaleness.Tests.ps1 and the gap in CI helper mocks, and (6) codecov.yml and scripts/tests/pester.config.ps1 coverage requirements (80% patch target, JaCoCo format). Compare with Test-DependencyPinning.ps1 line 782 as reference for Write-CIStepSummary usage.

Plan Phase

Plan the addition of Write-CIStepSummary to Test-SHAStaleness.ps1. The plan should cover: (1) building a markdown table from the results object containing dependency name, SHA age, threshold, and stale/current status, (2) calling Write-CIStepSummary after the annotation loop at approximately line 718, (3) adding Pester tests with mocks for Write-CIStepSummary and Write-CIAnnotation to verify call count and arguments, and (4) ensuring patch coverage meets the 80% codecov gate. Follow the pattern from Test-DependencyPinning.ps1.

Implement Phase

Implement Write-CIStepSummary for Test-SHAStaleness.ps1. After the per-dependency Write-CIAnnotation loop in the GitHub output format branch (~line 718): (1) build a markdown summary table from results showing each dependency's name, age, threshold, and pass/fail status, (2) include totals (scanned, stale, clean), (3) call Write-CIStepSummary -Summary $markdown. In Test-SHAStaleness.Tests.ps1: add mock for Write-CIStepSummary and assertions verifying it receives correctly formatted markdown including dependency table. Add Write-CIAnnotation mock assertions. Ensure patch coverage ≥ 80%. Run npm run lint:ps and npm run test:ps to validate.

Review Phase

Review the Write-CIStepSummary addition to Test-SHAStaleness.ps1. Verify: (1) the markdown table renders correctly in GitHub Actions summary tab format, (2) stale and clean dependencies have distinct status indicators, (3) Write-CIAnnotation calls are unmodified, (4) Pester tests mock and assert Write-CIStepSummary content, (5) no regressions in existing tests, (6) npm run lint:ps passes, (7) patch coverage meets the 80% codecov gate, and (8) the output pattern aligns with Test-DependencyPinning.ps1 for consistency.


References

  • Affected script: scripts/security/Test-SHAStaleness.ps1
  • Tests: scripts/tests/security/Test-SHAStaleness.Tests.ps1
  • Workflow: .github/workflows/sha-staleness-check.yml
  • Also used by: .github/workflows/weekly-security-maintenance.yml
  • Reference implementation: scripts/security/Test-DependencyPinning.ps1 (line 782 for Write-CIStepSummary)
  • CI helpers module: scripts/lib/Modules/CIHelpers.psm1
  • Codecov config: codecov.yml (80% patch target, auto +1% project threshold)
  • Pester config: scripts/tests/pester.config.ps1 (JaCoCo format, 80% coverage target)

Metadata

Metadata

Labels

bugSomething isn't workinggithub-actionsGitHub Actions workflowsgood first issueGood for newcomersscriptsPowerShell, Bash, or Python scriptssecuritySecurity-related changes or concerns

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions