Skip to content

Commit 24cac04

Browse files
🩹 [Patch]: Default to built-in Invoke-ScriptAnalyzer settings (#19)
This pull request introduces improved handling of the settings file for the ScriptAnalyzer GitHub Action, adds a new test scenario for default settings, and updates CI workflows and documentation to reflect these changes. The main goals are to make the settings file optional, clarify precedence, and ensure robust testing and reporting. **Key changes:** Settings file handling and usage: * The action now treats the settings file as optional; if not provided or not found, it falls back to ScriptAnalyzer defaults. Settings file precedence is clarified and documented, and code is updated to handle missing files gracefully without throwing errors. (`scripts/main.ps1` [[1]](diffhunk://#diff-dc2e5a659836b1b73abb03421c567f5018c2755677c4a0aa764cb26117b68011L5-L15) `scripts/tests/PSScriptAnalyzer/PSScriptAnalyzer.Tests.ps1` [[2]](diffhunk://#diff-506030604c5eac4d6d266aa14f0e8cf3a8121425c1f579406e3a003d5b091ac9L14-R32) [[3]](diffhunk://#diff-506030604c5eac4d6d266aa14f0e8cf3a8121425c1f579406e3a003d5b091ac9R76-R87) [[4]](diffhunk://#diff-506030604c5eac4d6d266aa14f0e8cf3a8121425c1f579406e3a003d5b091ac9L91-R122) `README.md` [[5]](diffhunk://#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5L91-R125) Continuous Integration workflow improvements: * All `actions/checkout` steps in workflow files now set `persist-credentials: false` for improved security and consistency. (`.github/workflows/Action-Test.yml` [[1]](diffhunk://#diff-a12ae5c885b0673c0ff6f70c2670886907590d624626e07da4c52e01aeaf56a4R29-R30) [[2]](diffhunk://#diff-a12ae5c885b0673c0ff6f70c2670886907590d624626e07da4c52e01aeaf56a4R54-R55) [[3]](diffhunk://#diff-a12ae5c885b0673c0ff6f70c2670886907590d624626e07da4c52e01aeaf56a4R80-R81) [[4]](diffhunk://#diff-a12ae5c885b0673c0ff6f70c2670886907590d624626e07da4c52e01aeaf56a4R133-R134) [[5]](diffhunk://#diff-a12ae5c885b0673c0ff6f70c2670886907590d624626e07da4c52e01aeaf56a4R155-R179) `.github/workflows/Auto-Release.yml` [[6]](diffhunk://#diff-d3f6900ee5159d4bc4ba6d893e2dd8443c2691b0490d7351cffbd7a37ed8d95aR30-R31) `.github/workflows/Linter.yml` [[7]](diffhunk://#diff-482e65806ed9e4a7320f14964764086b91fed4a28d12e4efde1776472e147e79R24) * A new test job, `ActionTestSrcWithManifestDefault`, is added to verify the action's behavior when no settings file is present (i.e., default settings are used). The workflow aggregation and environment variable naming are updated for clarity and maintainability. (`.github/workflows/Action-Test.yml` [[1]](diffhunk://#diff-a12ae5c885b0673c0ff6f70c2670886907590d624626e07da4c52e01aeaf56a4R98-R123) [[2]](diffhunk://#diff-a12ae5c885b0673c0ff6f70c2670886907590d624626e07da4c52e01aeaf56a4R155-R179) `tests/Get-AggregatedStatus.ps1` [[3]](diffhunk://#diff-dc50f3891fd8a2d62df15437f55b45ed09c908756bd8bfdc11fd71826abda1b7L23-R92) Documentation and configuration updates: * The README is updated to clearly explain settings file precedence and provide usage examples for all scenarios (custom, default, and none). (`README.md` [README.mdL91-R125](diffhunk://#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5L91-R125)) * Linter workflow configuration is updated to include new validation options and disables certain Biome and zizmor validations for clarity. (`.github/workflows/Linter.yml` [.github/workflows/Linter.ymlR34-R36](diffhunk://#diff-482e65806ed9e4a7320f14964764086b91fed4a28d12e4efde1776472e147e79R34-R36)) --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 1783982 commit 24cac04

File tree

7 files changed

+191
-72
lines changed

7 files changed

+191
-72
lines changed

.github/workflows/Action-Test.yml

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ jobs:
2626
steps:
2727
- name: Checkout repo
2828
uses: actions/checkout@v5
29+
with:
30+
persist-credentials: false
2931

3032
- name: Action-Test
3133
uses: ./
@@ -49,6 +51,8 @@ jobs:
4951
steps:
5052
- name: Checkout repo
5153
uses: actions/checkout@v5
54+
with:
55+
persist-credentials: false
5256

5357
- name: Action-Test
5458
uses: ./
@@ -73,6 +77,8 @@ jobs:
7377
steps:
7478
- name: Checkout repo
7579
uses: actions/checkout@v5
80+
with:
81+
persist-credentials: false
7682

7783
- name: Action-Test
7884
uses: ./
@@ -89,6 +95,32 @@ jobs:
8995
Write-Host "Outcome: ${{ steps.action-test.outcome }}"
9096
Write-Host "Conclusion: ${{ steps.action-test.conclusion }}"
9197
98+
ActionTestSrcWithManifestDefault:
99+
name: Action-Test - [Src-WithManifest-Default]
100+
runs-on: ubuntu-latest
101+
outputs:
102+
Outcome: ${{ steps.action-test.outcome }}
103+
Conclusion: ${{ steps.action-test.conclusion }}
104+
steps:
105+
- name: Checkout repo
106+
uses: actions/checkout@v5
107+
with:
108+
persist-credentials: false
109+
110+
- name: Action-Test
111+
uses: ./
112+
continue-on-error: true
113+
id: action-test
114+
with:
115+
Path: src
116+
WorkingDirectory: tests/srcWithManifestTestRepo
117+
118+
- name: Status
119+
shell: pwsh
120+
run: |
121+
Write-Host "Outcome: ${{ steps.action-test.outcome }}"
122+
Write-Host "Conclusion: ${{ steps.action-test.conclusion }}"
123+
92124
ActionTestOutputs:
93125
name: Action-Test - [outputs]
94126
runs-on: ubuntu-latest
@@ -98,6 +130,8 @@ jobs:
98130
steps:
99131
- name: Checkout repo
100132
uses: actions/checkout@v5
133+
with:
134+
persist-credentials: false
101135

102136
- name: Action-Test
103137
uses: ./
@@ -118,25 +152,28 @@ jobs:
118152
- ActionTestSrcSourceCode
119153
- ActionTestSrcCustom
120154
- ActionTestSrcWithManifest
155+
- ActionTestSrcWithManifestDefault
121156
- ActionTestOutputs
122157
if: always()
123158
runs-on: ubuntu-latest
124159
env:
125-
ActionTestSrcSourceCodeOutcome: ${{ needs.ActionTestSrcSourceCode.outputs.Outcome }}
126-
ActionTestSrcSourceCodeConclusion: ${{ needs.ActionTestSrcSourceCode.outputs.Conclusion }}
127-
ActionTestSrcCustomOutcome: ${{ needs.ActionTestSrcCustom.outputs.Outcome }}
128-
ActionTestSrcCustomConclusion: ${{ needs.ActionTestSrcCustom.outputs.Conclusion }}
129-
ActionTestSrcWithManifestOutcome: ${{ needs.ActionTestSrcWithManifest.outputs.Outcome }}
130-
ActionTestSrcWithManifestConclusion: ${{ needs.ActionTestSrcWithManifest.outputs.Conclusion }}
131-
ActionTestOutputsOutcome: ${{ needs.ActionTestOutputs.outputs.Outcome }}
132-
ActionTestOutputsConclusion: ${{ needs.ActionTestOutputs.outputs.Conclusion }}
160+
SourceCodeOutcome: ${{ needs.ActionTestSrcSourceCode.outputs.Outcome }}
161+
SourceCodeConclusion: ${{ needs.ActionTestSrcSourceCode.outputs.Conclusion }}
162+
CustomOutcome: ${{ needs.ActionTestSrcCustom.outputs.Outcome }}
163+
CustomConclusion: ${{ needs.ActionTestSrcCustom.outputs.Conclusion }}
164+
WithManifestOutcome: ${{ needs.ActionTestSrcWithManifest.outputs.Outcome }}
165+
WithManifestConclusion: ${{ needs.ActionTestSrcWithManifest.outputs.Conclusion }}
166+
WithManifestDefaultOutcome: ${{ needs.ActionTestSrcWithManifestDefault.outputs.Outcome }}
167+
WithManifestDefaultConclusion: ${{ needs.ActionTestSrcWithManifestDefault.outputs.Conclusion }}
168+
OutputsOutcome: ${{ needs.ActionTestOutputs.outputs.Outcome }}
169+
OutputsConclusion: ${{ needs.ActionTestOutputs.outputs.Conclusion }}
133170
steps:
134171
- name: Checkout repo
135172
uses: actions/checkout@v5
173+
with:
174+
persist-credentials: false
136175

137176
- name: Aggregated Status
138177
uses: PSModule/Github-Script@v1
139178
with:
140-
Script: |
141-
# Aggregated Status
142-
tests/Get-AggregatedStatus.ps1
179+
Script: tests/Get-AggregatedStatus.ps1

.github/workflows/Auto-Release.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ jobs:
2727
steps:
2828
- name: Checkout Code
2929
uses: actions/checkout@v5
30+
with:
31+
persist-credentials: false
3032

3133
- name: Auto-Release
3234
uses: PSModule/Auto-Release@v1

.github/workflows/Linter.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ jobs:
2121
- name: Checkout repo
2222
uses: actions/checkout@v5
2323
with:
24+
persist-credentials: false
2425
fetch-depth: 0
2526

2627
- name: Lint code base
@@ -30,4 +31,7 @@ jobs:
3031
VALIDATE_JSON_PRETTIER: false
3132
VALIDATE_MARKDOWN_PRETTIER: false
3233
VALIDATE_YAML_PRETTIER: false
34+
VALIDATE_BIOME_FORMAT: false
35+
VALIDATE_BIOME_LINT: false
36+
VALIDATE_GITHUB_ACTIONS_ZIZMOR: false
3337
FILTER_REGEX_EXCLUDE: '.*Set-PSModuleTest\.ps1$'

README.md

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,16 +88,41 @@ The action provides the following outputs:
8888
Choose a path for your code to test into the `Path` input. This can be a
8989
directory or a file.
9090

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

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

99-
You can override this by setting the `SettingsFilePath` input to point to your
100-
custom settings file.
98+
The action determines which settings to use in the following order:
99+
100+
1. **Custom Path**: If you provide a `SettingsFilePath` input, the action uses that file.
101+
2. **Default Action Path**: If no `SettingsFilePath` is provided, the action looks for a settings file at:
102+
`.github/linters/.powershell-psscriptanalyzer.psd1`
103+
3. **PSScriptAnalyzer Defaults**: If no settings file is found in either location, the action uses
104+
the default settings from the `Invoke-ScriptAnalyzer` cmdlet (all built-in rules with default severity).
105+
106+
**Example configurations:**
107+
108+
```yaml
109+
# Use a custom settings file
110+
- uses: PSModule/Invoke-ScriptAnalyzer@v2
111+
with:
112+
Path: src
113+
SettingsFilePath: config/custom-rules.psd1
114+
115+
# Use the default action path (.github/linters/.powershell-psscriptanalyzer.psd1)
116+
- uses: PSModule/Invoke-ScriptAnalyzer@v2
117+
with:
118+
Path: src
119+
120+
# Use PSScriptAnalyzer defaults (no settings file)
121+
- uses: PSModule/Invoke-ScriptAnalyzer@v2
122+
with:
123+
Path: src
124+
SettingsFilePath: '' # Explicitly skip settings file
125+
```
101126
102127
For more info on how to create a settings file, see the [Settings Documentation](./Settings.md) file.
103128

scripts/main.ps1

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,25 @@
22
$testPath = Resolve-Path -Path "$PSScriptRoot/tests/PSScriptAnalyzer" | Select-Object -ExpandProperty Path
33
$path = [string]::IsNullOrEmpty($env:PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_Path) ? '.' : $env:PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_Path
44
$codePath = Resolve-Path -Path $path | Select-Object -ExpandProperty Path
5-
$settingsFilePath = Resolve-Path -Path $env:PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_SettingsFilePath | Select-Object -ExpandProperty Path
5+
6+
# Try to resolve the settings file path, but allow it to be null if not found
7+
[string]$settingsFilePath = ''
8+
if (-not [string]::IsNullOrEmpty($env:PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_SettingsFilePath)) {
9+
try {
10+
$settingsFilePath = Resolve-Path -Path $env:PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_SettingsFilePath -ErrorAction Stop |
11+
Select-Object -ExpandProperty Path
12+
Write-Information "Using settings file: $settingsFilePath"
13+
} catch {
14+
Write-Warning "Settings file not found at path: $($env:PSMODULE_INVOKE_SCRIPTANALYZER_INPUT_SettingsFilePath). Using default settings."
15+
}
16+
}
617

718
[pscustomobject]@{
819
CodePath = $codePath
920
TestPath = $testPath
1021
SettingsFilePath = $settingsFilePath
1122
} | Format-List | Out-String
1223

13-
if (!(Test-Path -Path $settingsFilePath)) {
14-
throw "Settings file not found at path: $settingsFilePath"
15-
}
1624
Set-GitHubOutput -Name CodePath -Value $codePath
1725
Set-GitHubOutput -Name TestPath -Value $testPath
1826
Set-GitHubOutput -Name SettingsFilePath -Value $settingsFilePath

scripts/tests/PSScriptAnalyzer/PSScriptAnalyzer.Tests.ps1

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,25 @@
1111
Justification = 'Write-Host is used for log output.'
1212
)]
1313
[CmdLetBinding()]
14-
Param(
14+
param(
1515
[Parameter(Mandatory)]
1616
[string] $Path,
1717

18-
[Parameter(Mandatory)]
18+
[Parameter()]
1919
[string] $SettingsFilePath
2020
)
2121

2222
BeforeDiscovery {
23-
LogGroup "PSScriptAnalyzer tests using settings file [$SettingsFilePath]" {
24-
$settings = Import-PowerShellDataFile -Path $SettingsFilePath
23+
$hasSettingsFile = -not [string]::IsNullOrEmpty($SettingsFilePath)
24+
$settingsDescription = $hasSettingsFile ? "settings file [$SettingsFilePath]" : 'default settings'
25+
26+
LogGroup "PSScriptAnalyzer tests using $settingsDescription" {
27+
if ($hasSettingsFile) {
28+
$settings = Import-PowerShellDataFile -Path $SettingsFilePath
29+
} else {
30+
$settings = @{}
31+
}
32+
2533
$rules = [Collections.Generic.List[System.Collections.Specialized.OrderedDictionary]]::new()
2634
$ruleObjects = Get-ScriptAnalyzerRule -Verbose:$false | Sort-Object -Property Severity, CommonName
2735
$Severeties = $ruleObjects | Select-Object -ExpandProperty Severity -Unique
@@ -65,13 +73,18 @@ BeforeDiscovery {
6573

6674
Describe 'PSScriptAnalyzer' {
6775
BeforeAll {
68-
$relativeSettingsFilePath = if ($SettingsFilePath.StartsWith($PSScriptRoot)) {
69-
$SettingsFilePath.Replace($PSScriptRoot, 'Action:').Trim('\').Trim('/')
70-
} elseif ($SettingsFilePath.StartsWith($env:GITHUB_WORKSPACE)) {
71-
$SettingsFilePath.Replace($env:GITHUB_WORKSPACE, 'Workspace:').Trim('\').Trim('/')
72-
} else {
73-
$SettingsFilePath
76+
$hasSettingsFile = -not [string]::IsNullOrEmpty($SettingsFilePath)
77+
78+
if ($hasSettingsFile) {
79+
$relativeSettingsFilePath = if ($SettingsFilePath.StartsWith($PSScriptRoot)) {
80+
$SettingsFilePath.Replace($PSScriptRoot, 'Action:').Trim('\').Trim('/')
81+
} elseif ($SettingsFilePath.StartsWith($env:GITHUB_WORKSPACE)) {
82+
$SettingsFilePath.Replace($env:GITHUB_WORKSPACE, 'Workspace:').Trim('\').Trim('/')
83+
} else {
84+
$SettingsFilePath
85+
}
7486
}
87+
7588
$Path = Resolve-Path -Path $Path | Select-Object -ExpandProperty Path
7689
$relativePath = if ($Path.StartsWith($PSScriptRoot)) {
7790
$Path.Replace($PSScriptRoot, 'Action:').Trim('\').Trim('/').Replace('\', '/')
@@ -88,9 +101,25 @@ Describe 'PSScriptAnalyzer' {
88101
GITHUB_WORKSPACE = $env:GITHUB_WORKSPACE
89102
}
90103

91-
LogGroup "Invoke-ScriptAnalyzer -Path [$relativePath] -Settings [$relativeSettingsFilePath]" {
92-
$testResults = Invoke-ScriptAnalyzer -Path $Path -Settings $SettingsFilePath -Recurse -Verbose
104+
$invokeParams = @{
105+
Path = $Path
106+
Recurse = $true
107+
}
108+
109+
if ($hasSettingsFile) {
110+
$invokeParams['Settings'] = $SettingsFilePath
93111
}
112+
113+
$logMessage = if ($hasSettingsFile) {
114+
"Invoke-ScriptAnalyzer -Path '$relativePath' -Recurse -Settings '$relativeSettingsFilePath'"
115+
} else {
116+
"Invoke-ScriptAnalyzer -Path '$relativePath' -Recurse (using default settings)"
117+
}
118+
119+
LogGroup $logMessage {
120+
$testResults = Invoke-ScriptAnalyzer @invokeParams
121+
}
122+
94123
LogGroup "TestResults [$($testResults.Count)]" {
95124
$testResults | Select-Object -Property * | Format-List | Out-String -Stream | ForEach-Object {
96125
Write-Verbose $_ -Verbose

0 commit comments

Comments
 (0)