Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 40 additions & 3 deletions .github/workflows/Action-Test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ jobs:
steps:
- name: Checkout repo
uses: actions/checkout@v5
with:
persist-credentials: false

- name: Action-Test
uses: ./
Expand All @@ -49,6 +51,8 @@ jobs:
steps:
- name: Checkout repo
uses: actions/checkout@v5
with:
persist-credentials: false

- name: Action-Test
uses: ./
Expand All @@ -73,6 +77,8 @@ jobs:
steps:
- name: Checkout repo
uses: actions/checkout@v5
with:
persist-credentials: false

- name: Action-Test
uses: ./
Expand All @@ -89,6 +95,32 @@ jobs:
Write-Host "Outcome: ${{ steps.action-test.outcome }}"
Write-Host "Conclusion: ${{ steps.action-test.conclusion }}"

ActionTestSrcWithManifestDefault:
name: Action-Test - [Src-WithManifest-Default]
runs-on: ubuntu-latest
outputs:
Outcome: ${{ steps.action-test.outcome }}
Conclusion: ${{ steps.action-test.conclusion }}
steps:
- name: Checkout repo
uses: actions/checkout@v5
with:
persist-credentials: false

- name: Action-Test
uses: ./
continue-on-error: true
id: action-test
with:
Path: src
WorkingDirectory: tests/srcWithManifestTestRepo

- name: Status
shell: pwsh
run: |
Write-Host "Outcome: ${{ steps.action-test.outcome }}"
Write-Host "Conclusion: ${{ steps.action-test.conclusion }}"

ActionTestOutputs:
name: Action-Test - [outputs]
runs-on: ubuntu-latest
Expand All @@ -98,6 +130,8 @@ jobs:
steps:
- name: Checkout repo
uses: actions/checkout@v5
with:
persist-credentials: false

- name: Action-Test
uses: ./
Expand All @@ -118,6 +152,7 @@ jobs:
- ActionTestSrcSourceCode
- ActionTestSrcCustom
- ActionTestSrcWithManifest
- ActionTestSrcWithManifestDefault
- ActionTestOutputs
if: always()
runs-on: ubuntu-latest
Expand All @@ -128,15 +163,17 @@ jobs:
ActionTestSrcCustomConclusion: ${{ needs.ActionTestSrcCustom.outputs.Conclusion }}
ActionTestSrcWithManifestOutcome: ${{ needs.ActionTestSrcWithManifest.outputs.Outcome }}
ActionTestSrcWithManifestConclusion: ${{ needs.ActionTestSrcWithManifest.outputs.Conclusion }}
ActionTestSrcWithManifestDefaultOutcome: ${{ needs.ActionTestSrcWithManifestDefault.outputs.Outcome }}
ActionTestSrcWithManifestDefaultConclusion: ${{ needs.ActionTestSrcWithManifestDefault.outputs.Conclusion }}
ActionTestOutputsOutcome: ${{ needs.ActionTestOutputs.outputs.Outcome }}
ActionTestOutputsConclusion: ${{ needs.ActionTestOutputs.outputs.Conclusion }}
steps:
- name: Checkout repo
uses: actions/checkout@v5
with:
persist-credentials: false

- name: Aggregated Status
uses: PSModule/Github-Script@v1
with:
Script: |
# Aggregated Status
tests/Get-AggregatedStatus.ps1
Script: tests/Get-AggregatedStatus.ps1
2 changes: 2 additions & 0 deletions .github/workflows/Auto-Release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ jobs:
steps:
- name: Checkout Code
uses: actions/checkout@v5
with:
persist-credentials: false

- name: Auto-Release
uses: PSModule/Auto-Release@v1
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/Linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ jobs:
- name: Checkout repo
uses: actions/checkout@v5
with:
persist-credentials: false
fetch-depth: 0

- name: Lint code base
Expand All @@ -30,4 +31,7 @@ jobs:
VALIDATE_JSON_PRETTIER: false
VALIDATE_MARKDOWN_PRETTIER: false
VALIDATE_YAML_PRETTIER: false
VALIDATE_BIOME_FORMAT: false
VALIDATE_BIOME_LINT: false
VALIDATE_GITHUB_ACTIONS_ZIZMOR: false
FILTER_REGEX_EXCLUDE: '.*Set-PSModuleTest\.ps1$'
35 changes: 30 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,41 @@ The action provides the following outputs:
Choose a path for your code to test into the `Path` input. This can be a
directory or a file.

2. **Configure settings file**
2. **Configure settings file (Optional)**
Create a custom settings file to customize the analysis. The settings file is
a hashtable that defines the rules to include, exclude, or customize. The
settings file is in the format of a `.psd1` file.

By default, the action looks for a settings file at:
`.github/linters/.powershell-psscriptanalyzer.psd1`
**Settings File Precedence:**

You can override this by setting the `SettingsFilePath` input to point to your
custom settings file.
The action determines which settings to use in the following order:

1. **Custom Path**: If you provide a `SettingsFilePath` input, the action uses that file.
2. **Default Action Path**: If no `SettingsFilePath` is provided, the action looks for a settings file at:
`.github/linters/.powershell-psscriptanalyzer.psd1`
3. **PSScriptAnalyzer Defaults**: If no settings file is found in either location, the action uses
the default settings from the `Invoke-ScriptAnalyzer` cmdlet (all built-in rules with default severity).

**Example configurations:**

```yaml
# Use a custom settings file
- uses: PSModule/Invoke-ScriptAnalyzer@v2
with:
Path: src
SettingsFilePath: config/custom-rules.psd1

# Use the default action path (.github/linters/.powershell-psscriptanalyzer.psd1)
- uses: PSModule/Invoke-ScriptAnalyzer@v2
with:
Path: src

# Use PSScriptAnalyzer defaults (no settings file)
- uses: PSModule/Invoke-ScriptAnalyzer@v2
with:
Path: src
SettingsFilePath: '' # Explicitly skip settings file
```

For more info on how to create a settings file, see the [Settings Documentation](./Settings.md) file.

Expand Down
22 changes: 18 additions & 4 deletions scripts/main.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,31 @@
$testPath = Resolve-Path -Path "$PSScriptRoot/tests/PSScriptAnalyzer" | Select-Object -ExpandProperty Path
$path = [string]::IsNullOrEmpty($env:PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_Path) ? '.' : $env:PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_Path
$codePath = Resolve-Path -Path $path | Select-Object -ExpandProperty Path
$settingsFilePath = Resolve-Path -Path $env:PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_SettingsFilePath | Select-Object -ExpandProperty Path

# Try to resolve the settings file path, but allow it to be null if not found
$settingsFilePath = $null
if (-not [string]::IsNullOrEmpty($env:PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_SettingsFilePath)) {
try {
$settingsFilePath = Resolve-Path -Path $env:PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_SettingsFilePath -ErrorAction Stop |
Select-Object -ExpandProperty Path
Write-Information "Using settings file: $settingsFilePath"
} catch {
Write-Warning "Settings file not found at path: $($env:PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_SettingsFilePath). Using default settings."
}
} else {
$settingsFilePath = ''
}

if ([string]::IsNullOrEmpty($settingsFilePath)) {
Write-Information 'No settings file specified or found. Using default PSScriptAnalyzer settings.'
}

[pscustomobject]@{
CodePath = $codePath
TestPath = $testPath
SettingsFilePath = $settingsFilePath
} | Format-List | Out-String

if (!(Test-Path -Path $settingsFilePath)) {
throw "Settings file not found at path: $settingsFilePath"
}
Set-GitHubOutput -Name CodePath -Value $codePath
Set-GitHubOutput -Name TestPath -Value $testPath
Set-GitHubOutput -Name SettingsFilePath -Value $settingsFilePath
53 changes: 41 additions & 12 deletions scripts/tests/PSScriptAnalyzer/PSScriptAnalyzer.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,25 @@
Justification = 'Write-Host is used for log output.'
)]
[CmdLetBinding()]
Param(
param(
[Parameter(Mandatory)]
[string] $Path,

[Parameter(Mandatory)]
[Parameter()]
[string] $SettingsFilePath
)

BeforeDiscovery {
LogGroup "PSScriptAnalyzer tests using settings file [$SettingsFilePath]" {
$settings = Import-PowerShellDataFile -Path $SettingsFilePath
$hasSettingsFile = -not [string]::IsNullOrEmpty($SettingsFilePath)
$settingsDescription = $hasSettingsFile ? "settings file [$SettingsFilePath]" : 'default settings'

LogGroup "PSScriptAnalyzer tests using $settingsDescription" {
if ($hasSettingsFile) {
$settings = Import-PowerShellDataFile -Path $SettingsFilePath
} else {
$settings = @{}
}

$rules = [Collections.Generic.List[System.Collections.Specialized.OrderedDictionary]]::new()
$ruleObjects = Get-ScriptAnalyzerRule -Verbose:$false | Sort-Object -Property Severity, CommonName
$Severeties = $ruleObjects | Select-Object -ExpandProperty Severity -Unique
Expand Down Expand Up @@ -65,13 +73,18 @@ BeforeDiscovery {

Describe 'PSScriptAnalyzer' {
BeforeAll {
$relativeSettingsFilePath = if ($SettingsFilePath.StartsWith($PSScriptRoot)) {
$SettingsFilePath.Replace($PSScriptRoot, 'Action:').Trim('\').Trim('/')
} elseif ($SettingsFilePath.StartsWith($env:GITHUB_WORKSPACE)) {
$SettingsFilePath.Replace($env:GITHUB_WORKSPACE, 'Workspace:').Trim('\').Trim('/')
} else {
$SettingsFilePath
$hasSettingsFile = -not [string]::IsNullOrEmpty($SettingsFilePath)

if ($hasSettingsFile) {
$relativeSettingsFilePath = if ($SettingsFilePath.StartsWith($PSScriptRoot)) {
$SettingsFilePath.Replace($PSScriptRoot, 'Action:').Trim('\').Trim('/')
} elseif ($SettingsFilePath.StartsWith($env:GITHUB_WORKSPACE)) {
$SettingsFilePath.Replace($env:GITHUB_WORKSPACE, 'Workspace:').Trim('\').Trim('/')
} else {
$SettingsFilePath
}
}

$Path = Resolve-Path -Path $Path | Select-Object -ExpandProperty Path
$relativePath = if ($Path.StartsWith($PSScriptRoot)) {
$Path.Replace($PSScriptRoot, 'Action:').Trim('\').Trim('/').Replace('\', '/')
Expand All @@ -88,9 +101,25 @@ Describe 'PSScriptAnalyzer' {
GITHUB_WORKSPACE = $env:GITHUB_WORKSPACE
}

LogGroup "Invoke-ScriptAnalyzer -Path [$relativePath] -Settings [$relativeSettingsFilePath]" {
$testResults = Invoke-ScriptAnalyzer -Path $Path -Settings $SettingsFilePath -Recurse -Verbose
$invokeParams = @{
Path = $Path
Recurse = $true
}

if ($hasSettingsFile) {
$invokeParams['Settings'] = $SettingsFilePath
}

$logMessage = if ($hasSettingsFile) {
"Invoke-ScriptAnalyzer -Path '$relativePath' -Recurse -Settings '$relativeSettingsFilePath'"
} else {
"Invoke-ScriptAnalyzer -Path '$relativePath' -Recurse (using default settings)"
}

LogGroup $logMessage {
$testResults = Invoke-ScriptAnalyzer @invokeParams
}

LogGroup "TestResults [$($testResults.Count)]" {
$testResults | Select-Object -Property * | Format-List | Out-String -Stream | ForEach-Object {
Write-Verbose $_ -Verbose
Expand Down
74 changes: 44 additions & 30 deletions tests/Get-AggregatedStatus.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,25 @@
}

# Build an array of objects for each job
$ActionTestSrcSourceCodeExpectedOutcome = 'success'
$ActionTestSrcSourceCodeOutcomeResult = $env:ActionTestSrcSourceCodeOutcome -eq $ActionTestSrcSourceCodeExpectedOutcome
$ActionTestSrcSourceCodeExpectedConclusion = 'success'
$ActionTestSrcSourceCodeConclusionResult = $env:ActionTestSrcSourceCodeConclusion -eq $ActionTestSrcSourceCodeExpectedConclusion
$SourceCodeExpectedOutcome = 'success'
$SourceCodeOutcomeResult = $env:SourceCodeOutcome -eq $SourceCodeExpectedOutcome
$SourceCodeExpectedConclusion = 'success'
$SourceCodeConclusionResult = $env:SourceCodeConclusion -eq $SourceCodeExpectedConclusion

$ActionTestSrcCustomExpectedOutcome = 'success'
$ActionTestSrcCustomOutcomeResult = $env:ActionTestSrcCustomOutcome -eq $ActionTestSrcCustomExpectedOutcome
$ActionTestSrcCustomExpectedConclusion = 'success'
$ActionTestSrcCustomConclusionResult = $env:ActionTestSrcCustomConclusion -eq $ActionTestSrcCustomExpectedConclusion
$CustomExpectedOutcome = 'success'
$CustomOutcomeResult = $env:CustomOutcome -eq $CustomExpectedOutcome
$CustomExpectedConclusion = 'success'
$CustomConclusionResult = $env:CustomConclusion -eq $CustomExpectedConclusion

$ActionTestSrcWithManifestExpectedOutcome = 'failure'
$ActionTestSrcWithManifestOutcomeResult = $env:ActionTestSrcWithManifestOutcome -eq $ActionTestSrcWithManifestExpectedOutcome
$ActionTestSrcWithManifestExpectedConclusion = 'success'
$ActionTestSrcWithManifestConclusionResult = $env:ActionTestSrcWithManifestConclusion -eq $ActionTestSrcWithManifestExpectedConclusion
$WithManifestExpectedOutcome = 'failure'
$WithManifestOutcomeResult = $env:WithManifestOutcome -eq $WithManifestExpectedOutcome
$WithManifestExpectedConclusion = 'success'
$WithManifestConclusionResult = $env:WithManifestConclusion -eq $WithManifestExpectedConclusion

$WithManifestDefaultExpectedOutcome = 'failure'
$WithManifestDefaultOutcomeResult = $env:WithManifestDefaultOutcome -eq $WithManifestDefaultExpectedOutcome
$WithManifestDefaultExpectedConclusion = 'success'
$WithManifestDefaultConclusionResult = $env:WithManifestDefaultConclusion -eq $WithManifestDefaultExpectedConclusion

$ActionTestOutputsExpectedOutcome = 'success'
$ActionTestOutputsOutcomeResult = $env:ActionTestOutputsOutcome -eq $ActionTestOutputsExpectedOutcome
Expand All @@ -43,30 +48,39 @@ $ActionTestOutputsConclusionResult = $env:ActionTestOutputsConclusion -eq $Actio
$jobs = @(
[PSCustomObject]@{
Name = 'Action-Test - [Src-SourceCode]'
Outcome = $env:ActionTestSrcSourceCodeOutcome
ExpectedOutcome = $ActionTestSrcSourceCodeExpectedOutcome
PassedOutcome = $ActionTestSrcSourceCodeOutcomeResult
Conclusion = $env:ActionTestSrcSourceCodeConclusion
ExpectedConclusion = $ActionTestSrcSourceCodeExpectedConclusion
PassedConclusion = $ActionTestSrcSourceCodeConclusionResult
Outcome = $env:SourceCodeOutcome
ExpectedOutcome = $SourceCodeExpectedOutcome
PassedOutcome = $SourceCodeOutcomeResult
Conclusion = $env:SourceCodeConclusion
ExpectedConclusion = $SourceCodeExpectedConclusion
PassedConclusion = $SourceCodeConclusionResult
},
[PSCustomObject]@{
Name = 'Action-Test - [Src-Custom]'
Outcome = $env:ActionTestSrcCustomOutcome
ExpectedOutcome = $ActionTestSrcCustomExpectedOutcome
PassedOutcome = $ActionTestSrcCustomOutcomeResult
Conclusion = $env:ActionTestSrcCustomConclusion
ExpectedConclusion = $ActionTestSrcCustomExpectedConclusion
PassedConclusion = $ActionTestSrcCustomConclusionResult
Outcome = $env:CustomOutcome
ExpectedOutcome = $CustomExpectedOutcome
PassedOutcome = $CustomOutcomeResult
Conclusion = $env:CustomConclusion
ExpectedConclusion = $CustomExpectedConclusion
PassedConclusion = $CustomConclusionResult
},
[PSCustomObject]@{
Name = 'Action-Test - [Src-WithManifest]'
Outcome = $env:ActionTestSrcWithManifestOutcome
ExpectedOutcome = $ActionTestSrcWithManifestExpectedOutcome
PassedOutcome = $ActionTestSrcWithManifestOutcomeResult
Conclusion = $env:ActionTestSrcWithManifestConclusion
ExpectedConclusion = $ActionTestSrcWithManifestExpectedConclusion
PassedConclusion = $ActionTestSrcWithManifestConclusionResult
Outcome = $env:WithManifestOutcome
ExpectedOutcome = $WithManifestExpectedOutcome
PassedOutcome = $WithManifestOutcomeResult
Conclusion = $env:WithManifestConclusion
ExpectedConclusion = $WithManifestExpectedConclusion
PassedConclusion = $WithManifestConclusionResult
},
[PSCustomObject]@{
Name = 'Action-Test - [Src-WithManifest-Default]'
Outcome = $env:WithManifestDefaultOutcome
ExpectedOutcome = $WithManifestDefaultExpectedOutcome
PassedOutcome = $WithManifestDefaultOutcomeResult
Conclusion = $env:WithManifestDefaultConclusion
ExpectedConclusion = $WithManifestDefaultExpectedConclusion
PassedConclusion = $WithManifestDefaultConclusionResult
},
[PSCustomObject]@{
Name = 'Action-Test - [outputs]'
Expand Down
Loading