-
Notifications
You must be signed in to change notification settings - Fork 126
Description
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-SecurityLogfunction (lines 95–124) provides color-codedWrite-Hostoutput in console mode. ✅ - CI annotations: Per-dependency
Write-CIAnnotationcalls (lines 698–718) in GitHub output format — Notice level when clean, Error level for stale dependencies. ✅ - Step summary: No
Write-CIStepSummarycall anywhere in the script. ❌ - Workflow compensation: The workflow
sha-staleness-check.ymluses inline::warningannotations 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
- Run
Test-SHAStaleness.ps1 -OutputFormat githubin a GitHub Actions environment (or locally withGITHUB_ACTIONS=true). - Check the GitHub Actions job summary tab — it is empty.
- 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:
- Mock
Write-CIStepSummary— add mock andShould -Invokeassertion verifying the markdown summary content (dependency table, counts, status). - Mock
Write-CIAnnotation— the script already calls this per dependency, but tests don't verify it. Add mock with-ParameterFilterassertions for correct-Leveland-Messageper dependency. - Mock
Write-Host(viaWrite-SecurityLog) — verify console output content matches expected color-coded patterns.
RPI Phase Testing Guidance
- Research: Audit
Test-SHAStaleness.Tests.ps1for CI helper coverage gaps; document the GitHub output format branch (lines 680–720). - Plan: Design test cases for
Write-CIStepSummarymarkdown content andWrite-CIAnnotationper-dependency assertions. - Implement: Add mock infrastructure for all CI helper functions; verify
npm run test:pspasses with patch coverage ≥ 80%. - Review: Confirm no coverage regressions in the
pesterflag 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-dependencyWrite-CIAnnotationcalls with Notice/Error levels, (2) theWrite-SecurityLogfunction (lines 95–124) providing color-coded console output, (3) the absence ofWrite-CIStepSummary, (4) the workflow file.github/workflows/sha-staleness-check.ymloutput configuration, (5) existing Pester test coverage inscripts/tests/security/Test-SHAStaleness.Tests.ps1and the gap in CI helper mocks, and (6)codecov.ymlandscripts/tests/pester.config.ps1coverage requirements (80% patch target, JaCoCo format). Compare withTest-DependencyPinning.ps1line 782 as reference forWrite-CIStepSummaryusage.
Plan Phase
Plan the addition of
Write-CIStepSummarytoTest-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) callingWrite-CIStepSummaryafter the annotation loop at approximately line 718, (3) adding Pester tests with mocks forWrite-CIStepSummaryandWrite-CIAnnotationto verify call count and arguments, and (4) ensuring patch coverage meets the 80% codecov gate. Follow the pattern fromTest-DependencyPinning.ps1.
Implement Phase
Implement
Write-CIStepSummaryforTest-SHAStaleness.ps1. After the per-dependencyWrite-CIAnnotationloop 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) callWrite-CIStepSummary -Summary $markdown. InTest-SHAStaleness.Tests.ps1: add mock forWrite-CIStepSummaryand assertions verifying it receives correctly formatted markdown including dependency table. AddWrite-CIAnnotationmock assertions. Ensure patch coverage ≥ 80%. Runnpm run lint:psandnpm run test:psto validate.
Review Phase
Review the
Write-CIStepSummaryaddition toTest-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-CIAnnotationcalls are unmodified, (4) Pester tests mock and assertWrite-CIStepSummarycontent, (5) no regressions in existing tests, (6)npm run lint:pspasses, (7) patch coverage meets the 80% codecov gate, and (8) the output pattern aligns withTest-DependencyPinning.ps1for 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 forWrite-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)