Skip to content

refactor(scripts): refactor security scripts to use shared SecurityHelpers and CIHelpers modules #290

@WilliamBerryiii

Description

@WilliamBerryiii

Note

Partial Completion Status (assessed 2026-02-13)

Completed:

  • SecurityHelpers.psm1 and SecurityClasses.psm1 shared modules created in scripts/security/Modules/
  • CIHelpers.psm1 shared module created and imported by multiple scripts
  • Prerequisites for this issue (shared module creation) are satisfied

Remaining:

  • Test-SHAStaleness.ps1 still contains duplicate Write-SecurityLog and Write-OutputResult functions (~105 lines)
  • Update-ActionSHAPinning.ps1 still contains duplicate Write-SecurityLog, Add-SecurityIssue, and Write-OutputResult functions (~150 lines)
  • Neither script imports SecurityHelpers.psm1 — ~255 lines of duplicate code remain
  • Inline ##vso[...] commands not yet replaced with CIHelpers function calls

Summary

Refactor Test-SHAStaleness.ps1 and Update-ActionSHAPinning.ps1 to import and use the shared SecurityHelpers.psm1 and CIHelpers.psm1 modules, removing duplicate function definitions.

Prerequisites

This issue depends on:

  • #TBD - Create CIHelpers.psm1 shared module for CI platform detection and output
  • #TBD - Create SecurityHelpers.psm1 shared module for security script utilities

Do not start this issue until the prerequisite issues are completed.

Problem

After creating the shared modules, the security scripts will still contain their original duplicate implementations. This issue tracks removing those duplicates and importing the shared modules.

Code to remove from Test-SHAStaleness.ps1:

  • Lines 78-112: Write-SecurityLog function (~35 lines)
  • Lines 653-720+: Write-OutputResult function (~70 lines)
  • Lines 709-718: Inline Azure DevOps ##vso commands

Code to remove from Update-ActionSHAPinning.ps1:

  • Lines 289-308: Write-SecurityLog function (~20 lines)
  • Lines 311-349: Add-SecurityIssue function (~40 lines)
  • Lines 351-440+: Write-OutputResult function (~90 lines)
  • Lines 424-438: Inline Azure DevOps ##vso commands

Total duplicate code to remove: ~255 lines

Solution

Step 1: Add module imports

Add to the top of each script, after the param() block:

# Import shared modules
$modulesPath = Join-Path $PSScriptRoot "Modules"
Import-Module (Join-Path $modulesPath "SecurityHelpers.psm1") -Force
Import-Module (Join-Path $PSScriptRoot "../lib/Modules/CIHelpers.psm1") -Force

Step 2: Replace function calls

Original Call Replacement
Write-SecurityLog -Message $msg -Level Warning Write-SecurityLog -Message $msg -Level Warning -LogPath $LogPath -OutputFormat $OutputFormat
Add-SecurityIssue -Type ... -Severity ... New-SecurityIssue -Type ... -Severity ... (capture return value)
Write-OutputResult -OutputFormat $format -Results $results Write-SecurityReport -OutputFormat $format -Results $results -OutputPath $OutputPath
Write-Output "##vso[task.logissue type=warning...]" Write-CIAnnotation -Type warning -Message $msg -File $file
Write-Output "##vso[task.complete result=SucceededWithIssues]" Set-CITaskResult -Result SucceededWithIssues

Step 3: Remove duplicate functions

Delete the following function definitions:

  • function Write-SecurityLog { ... }
  • function Add-SecurityIssue { ... }
  • function Write-OutputResult { ... }

Step 4: Update script-level variables

Replace script-scoped issue tracking:

# Before
$script:SecurityIssues = @()
$script:SecurityIssues += $issue

# After
$SecurityIssues = [System.Collections.Generic.List[PSCustomObject]]::new()
$SecurityIssues.Add((New-SecurityIssue -Type $type -Severity $severity ...))

Implementation Details

Test-SHAStaleness.ps1 changes:

# Add after param() block:
Import-Module (Join-Path $PSScriptRoot "Modules/SecurityHelpers.psm1") -Force
Import-Module (Join-Path $PSScriptRoot "../lib/Modules/CIHelpers.psm1") -Force

# Remove: Lines 78-112 (Write-SecurityLog)
# Remove: Lines 653-720+ (Write-OutputResult)

# Replace inline ##vso commands (lines 709-718):
# Before:
$Message = "##vso[task.logissue type=warning;sourcepath=$($Dep.File);][$($Dep.Severity)] $($Dep.Message)"
Write-Output "##vso[task.complete result=SucceededWithIssues]"

# After:
Write-CIAnnotation -Type warning -Message "[$($Dep.Severity)] $($Dep.Message)" -File $Dep.File
Set-CITaskResult -Result SucceededWithIssues

Update-ActionSHAPinning.ps1 changes:

# Add after param() block (around line 50):
Import-Module (Join-Path $PSScriptRoot "Modules/SecurityHelpers.psm1") -Force
Import-Module (Join-Path $PSScriptRoot "../lib/Modules/CIHelpers.psm1") -Force

# Remove: Lines 289-308 (Write-SecurityLog)
# Remove: Lines 311-349 (Add-SecurityIssue)
# Remove: Lines 351-440+ (Write-OutputResult)

# Replace Add-SecurityIssue calls:
# Before:
$script:SecurityIssues += @{ Type = $Type; Severity = $Severity; ... }

# After:
$issue = New-SecurityIssue -Type $Type -Severity $Severity -Title $Title -Description $Description
$SecurityIssues.Add($issue)

# Replace ##vso commands (lines 424-438):
# Before:
Write-Output "##vso[task.logissue type=warning;sourcepath=$sourcePath]$message"

# After:
Write-CIAnnotation -Type warning -Message $message -File $sourcePath

Validation

  1. Run existing tests:
Invoke-Pester -Path scripts/tests/security/ -Output Detailed
  1. Test each script manually with different output formats:
# Test-SHAStaleness.ps1
./scripts/security/Test-SHAStaleness.ps1 -OutputFormat console
./scripts/security/Test-SHAStaleness.ps1 -OutputFormat json -OutputPath ./test-output.json

# Update-ActionSHAPinning.ps1
./scripts/security/Update-ActionSHAPinning.ps1 -OutputReport -WhatIf
  1. Verify line count reduction:
# Before refactoring, note line counts
(Get-Content scripts/security/Test-SHAStaleness.ps1).Count
(Get-Content scripts/security/Update-ActionSHAPinning.ps1).Count

# After refactoring, verify ~255 lines removed total

Acceptance Criteria

  • Both scripts import SecurityHelpers.psm1 and CIHelpers.psm1
  • No duplicate Write-SecurityLog, Add-SecurityIssue, or Write-OutputResult functions remain
  • No inline ##vso[...] commands remain (all use CIHelpers functions)
  • Existing tests pass without modification
  • Scripts produce identical output in all formats (json, console, azdo, github)
  • Combined line count reduction of at least 200 lines

Metadata

Metadata

Labels

maintenanceMaintenance work, no version bumpsecuritySecurity-related changes or concerns

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions