-
Notifications
You must be signed in to change notification settings - Fork 125
Description
Summary
Test-DependencyPinning.ps1 verifies SHA pinning compliance for supply chain security. It has Write-CIStepSummary (line 782) ✅ but is missing two CI output features: no Write-Host output at all for per-violation details, and Write-CIAnnotation fires only in the catch block (line 923). Contributors see results only via the step summary, artifacts, or by expanding verbose workflow logs — there is no console-level per-violation output.
Current Behavior
- Console output: No
Write-Hostcalls in the entire script (0 matches confirmed). ❌ - CI annotations:
Write-CIAnnotationonly incatchblock (line 923) — fires on fatal errors, not per unpinned dependency. ❌ - Step summary:
Write-CIStepSummaryon line 782 with compliance score, unpinned count, and total deps. ✅ - Workflow:
dependency-pinning-scan.ymlhas a separate "Add job summary" step writingGITHUB_STEP_SUMMARYin YAML and inline::warningannotations — partially compensating for the script's gaps.
Expected Behavior
- Per-violation
Write-Hostoutput in the console log showing each unpinned dependency with file path, action/image reference, and current pinning status — following the pattern fromInvoke-PSScriptAnalyzer.ps1. - Per-violation
Write-CIAnnotation(levelWarning) so GitHub renders inline annotations on PR diffs showing exactly which workflow lines have unpinned dependencies.
Root Cause
The script was designed around structured output formats (JSON, SARIF, CSV, Markdown, Table) written to files, with the workflow handling summary display via separate steps and inline ::warning notation. Console-level Write-Host output for human readability and per-violation Write-CIAnnotation for PR annotations were never implemented.
Files Requiring Changes
| File | Change |
|---|---|
scripts/security/Test-DependencyPinning.ps1 |
Add per-violation Write-Host output in the results processing section. Add per-violation Write-CIAnnotation calls with Warning level. |
scripts/tests/security/Test-DependencyPinning.Tests.ps1 |
Add mocks and assertions for Write-Host, Write-CIAnnotation, and existing Write-CIStepSummary. |
Additional Context
Write-Hostis safe —PSAvoidUsingWriteHostis explicitly excluded inscripts/linting/PSScriptAnalyzer.psd1.- The
CIHelpersmodule is already available — no new imports needed. - The workflow
dependency-pinning-scan.ymlhas inline::warningannotations in YAML — the script-levelWrite-CIAnnotationcalls will provide richer, per-file annotations that replace the need for workflow-level inline warnings. - The workflow's separate "Add job summary" step is redundant with the script's existing
Write-CIStepSummary— consolidation is optional but out of scope for this issue. - Also called from
weekly-security-maintenance.yml.
Fix Guidance
Per-Violation Console Output
In the results processing section, after violations are collected:
if ($unpinnedDeps.Count -gt 0) {
Write-Host "`n❌ Found $($unpinnedDeps.Count) unpinned dependencies:" -ForegroundColor Red
$groupedByFile = $unpinnedDeps | Group-Object -Property File
foreach ($fileGroup in $groupedByFile) {
Write-Host "`n📄 $($fileGroup.Name)" -ForegroundColor Cyan
foreach ($dep in $fileGroup.Group) {
Write-Host " ⚠️ Line $($dep.Line): $($dep.Reference) (type: $($dep.Type))" -ForegroundColor Yellow
}
}
}
else {
Write-Host "✅ All dependencies are properly SHA-pinned." -ForegroundColor Green
}Per-Violation Annotations
After each Write-Host violation line:
Write-CIAnnotation -Message "Unpinned dependency: $($dep.Reference) (type: $($dep.Type))" `
-Level Warning `
-File $dep.File `
-Line $dep.LineUnit 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-DependencyPinning.Tests.ps1 has no mocks for Write-CIAnnotation, Write-CIStepSummary, or Write-Host. All CI helper mock infrastructure must be built from scratch:
- Mock
Write-Host— the script currently has zeroWrite-Hostcalls. New per-violation output requires mocks with-ParameterFilterto verify each unpinned dependency is logged with file, line, and reference. - Mock
Write-CIAnnotation— currently catch-only. New per-violation calls require mock assertions for correct-File,-Line,-Level Warning, and-Messageper unpinned dependency. - Mock
Write-CIStepSummary— already called at line 782 but never tested. Add mock andShould -Invokeassertion verifying the markdown content includes compliance score and dependency counts.
RPI Phase Testing Guidance
- Research: Audit
Test-DependencyPinning.Tests.ps1for CI helper coverage gaps; document the results processing flow and the existingWrite-CIStepSummarycall. - Plan: Design test cases for per-violation
Write-Host, per-violationWrite-CIAnnotation, and existingWrite-CIStepSummarycontent verification. - 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-DependencyPinning.ps1. Document: (1) the complete absence ofWrite-Hostcalls, (2) the catch-onlyWrite-CIAnnotationpattern (line 923), (3) the existingWrite-CIStepSummarycall (line 782) and its markdown content, (4) the workflowdependency-pinning-scan.ymlcompensating with inline::warningannotations and a separate "Add job summary" step, (5) theweekly-security-maintenance.ymlusage, (6) existing Pester test coverage and the complete absence of CI helper mocks, and (7)codecov.ymlandscripts/tests/pester.config.ps1coverage requirements (80% patch target). Identify the results processing section where per-violationWrite-HostandWrite-CIAnnotationcalls should be inserted.
Plan Phase
Plan CI output improvements for
Test-DependencyPinning.ps1. The plan should cover: (1) adding per-violationWrite-Hostoutput grouped by file following theInvoke-PSScriptAnalyzer.ps1pattern, (2) adding per-violationWrite-CIAnnotationcalls with Warning level, file path, and line number, (3) determining the correct insertion points in the results processing flow (before the existingWrite-CIStepSummarycall), (4) adding Pester tests with mocks forWrite-Host,Write-CIAnnotation(per-violation), andWrite-CIStepSummary(already exists but untested), and (5) ensuring patch coverage meets the 80% codecov gate.
Implement Phase
Implement CI output improvements for
Test-DependencyPinning.ps1. Steps: (1) In the results processing section, after violations are collected and beforeWrite-CIStepSummary(line 782), add grouped-by-fileWrite-Hostoutput with 📄 file headers (Cyan) and⚠️ per-violation detail lines (Yellow). (2) After eachWrite-Hostviolation line, addWrite-CIAnnotation -Message "..." -Level Warning -File $file -Line $line. (3) InTest-DependencyPinning.Tests.ps1, add mocks forWrite-Host,Write-CIAnnotation, andWrite-CIStepSummarywith-ParameterFilterassertions; ensure patch coverage ≥ 80%. Runnpm run lint:psandnpm run test:psto validate.
Review Phase
Review CI output changes to
Test-DependencyPinning.ps1. Verify: (1)Write-Hostprovides grouped-by-file output with per-violation detail lines, (2)Write-CIAnnotationis called once per unpinned dependency with Warning level and correct file/line, (3) existingWrite-CIStepSummarycall is unmodified, (4) Pester tests mock and assert all three CI helpers, (5)npm run lint:pspasses, (6) no regressions in existing tests, (7) patch coverage meets the 80% codecov gate, (8) output formats align with other scripts for consistency, and (9) the workflow's separate summary step remains functional alongside the script's nativeWrite-CIStepSummary.
References
- Affected script:
scripts/security/Test-DependencyPinning.ps1 - Tests:
scripts/tests/security/Test-DependencyPinning.Tests.ps1 - Workflow:
.github/workflows/dependency-pinning-scan.yml - Also used by:
.github/workflows/weekly-security-maintenance.yml - Reference implementation:
scripts/linting/Invoke-PSScriptAnalyzer.ps1(per-violation output pattern) - Step summary reference:
scripts/security/Test-DependencyPinning.ps1line 782 (already implemented) - 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)