diff --git a/.github/workflows/powershell.yaml b/.github/workflows/powershell.yaml index d83398c90..69896e1fa 100644 --- a/.github/workflows/powershell.yaml +++ b/.github/workflows/powershell.yaml @@ -28,11 +28,11 @@ jobs: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Run PSScriptAnalyzer - uses: microsoft/psscriptanalyzer-action@6b2948b1944407914a58661c49941824d149734f # v1.1 + uses: ./Actions/RunPSScriptAnalyzer with: path: .\ recurse: true - excludeRule: '"PSAvoidUsingInvokeExpression", "PSUseShouldProcessForStateChangingFunctions", "PSAvoidUsingWriteHost", "PSAvoidUsingCmdletAliases", "PSUseSingularNouns"' + excludeRule: 'PSAvoidUsingInvokeExpression, PSUseShouldProcessForStateChangingFunctions, PSAvoidUsingWriteHost, PSAvoidUsingCmdletAliases, PSUseSingularNouns' output: results.sarif # Upload the SARIF file generated in the previous step diff --git a/Actions/RunPSScriptAnalyzer/README.md b/Actions/RunPSScriptAnalyzer/README.md new file mode 100644 index 000000000..1228f52b2 --- /dev/null +++ b/Actions/RunPSScriptAnalyzer/README.md @@ -0,0 +1,29 @@ +# PowerShell Script Analyzer + +Run the PSScriptAnalyzer tool + +## INPUT + +### ENV variables + +none + +### Parameters + +| Name | Required | Description | Default value | +| :-- | :-: | :-- | :-- | +| shell | | The shell (powershell or pwsh) in which the PowerShell script in this action should run | pwsh | +| path | Yes | Specifies the path to the scripts or module to be analyzed. Wildcard characters are supported. | .\\ | +| excludeRule | | Comma separated list of PSScriptAnalyzer rules to exclude. Wildcard characters are supported. | | +| recurse | | Runs Script Analyzer on the files in the Path directory and all subdirectories recursively. | | +| output | Yes | Specifies where the path for the sarif file | results.sarif | + +## OUTPUT + +### ENV variables + +none + +### OUTPUT variables + +none diff --git a/Actions/RunPSScriptAnalyzer/RunPSScriptAnalyzer.ps1 b/Actions/RunPSScriptAnalyzer/RunPSScriptAnalyzer.ps1 new file mode 100644 index 000000000..e447f29bd --- /dev/null +++ b/Actions/RunPSScriptAnalyzer/RunPSScriptAnalyzer.ps1 @@ -0,0 +1,49 @@ +param ( + [string]$Path, + [string[]]$ExcludeRule, + [switch]$Recurse, + [string]$Output +) + +$analyzerModule = Get-Module -ListAvailable -Name PSScriptAnalyzer +if ($null -eq $analyzerModule) { + Install-Module -Name PSScriptAnalyzer -Force +} + +$sarifModule = Get-Module -ListAvailable -Name ConvertToSARIF +if ($null -eq $sarifModule) { + Install-Module -Name ConvertToSARIF -Force +} +Import-Module -Name ConvertToSARIF -Force + +$htPSA = [ordered]@{ Path = $Path } +if ($ExcludeRule) { + Write-Host "Excluding rules: $ExcludeRule" + $htPSA.add('ExcludeRule', $ExcludeRule) +} +if ($Recurse) { + Write-Host "Recurse: $Recurse" + $htPSA.add('Recurse', $true) +} +$htCTS = [ordered]@{ FilePath = $Output } + +$maxRetries = 3 +$retryCount = 0 +$success = $false + +Write-Output "Modules installed, now running tests." +while (-not $success -and $retryCount -lt $maxRetries) { + Try { + Invoke-ScriptAnalyzer @htPSA -Verbose | ConvertTo-SARIF @htCTS + $success = $true + } Catch { + Write-Host "::Error:: $_" + $retryCount++ + Write-Output "Retrying... ($retryCount/$maxRetries)" + } +} + +if (-not $success) { + Write-Host "::Error:: Failed after $maxRetries attempts." + exit 1 +} diff --git a/Actions/RunPSScriptAnalyzer/action.yml b/Actions/RunPSScriptAnalyzer/action.yml new file mode 100644 index 000000000..d442b6ead --- /dev/null +++ b/Actions/RunPSScriptAnalyzer/action.yml @@ -0,0 +1,39 @@ +name: Run PSScriptAnalyzer +author: Microsoft Corporation +branding: + icon: "check" + color: "gray-dark" +inputs: + shell: + description: Shell in which you want to run the action (powershell or pwsh) + required: false + default: pwsh + path: + description: 'Specifies the path to the scripts or module to be analyzed. Wildcard characters are supported.' + required: true + default: '.\' + excludeRule: + description: 'Comma separated list of PSScriptAnalyzer rules to exclude. Wildcard characters are supported.' + required: false + recurse: + description: 'Runs Script Analyzer on the files in the Path directory and all subdirectories recursively.' + required: false + output: + description: 'Specifies where the path for the sarif file' + required: true + default: 'results.sarif' +runs: + using: "composite" + steps: + - name: run + shell: ${{ inputs.shell }} + id: RunPSScriptAnalyzer + env: + _path: ${{ inputs.path }} + _excludeRule: ${{ inputs.excludeRule }} + _recurse: ${{ inputs.recurse }} + _output: ${{ inputs.output }} + run: | + ${{ github.action_path }}/../Invoke-AlGoAction.ps1 -ActionName "RunPSScriptAnalyzer" -Action { + ${{ github.action_path }}/RunPSScriptAnalyzer.ps1 -path $ENV:_path -excludeRule @($ENV:_excludeRule -Replace ' ','' -Split ',') -Recurse:$($ENV:_recurse -eq 'true') -output $ENV:_output + }