diff --git a/.github/workflows/Action-Test.yml b/.github/workflows/Action-Test.yml index c27b734..2829d54 100644 --- a/.github/workflows/Action-Test.yml +++ b/.github/workflows/Action-Test.yml @@ -121,6 +121,70 @@ jobs: Write-Host "Outcome: ${{ steps.action-test.outcome }}" Write-Host "Conclusion: ${{ steps.action-test.conclusion }}" + ActionTestReportPaths: + name: Action-Test - [Report Paths] + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + + - name: Action-Test + uses: ./ + id: action-test + with: + Path: src + WorkingDirectory: tests/srcTestRepo + TestResult_Enabled: true + TestResult_OutputFormat: NUnitXml + TestResult_OutputPath: artifacts/TestResult/results.xml + CodeCoverage_Enabled: true + CodeCoverage_OutputFormat: JaCoCo + CodeCoverage_OutputPath: artifacts/CodeCoverage/coverage.xml + CodeCoverage_Path: ../../src/tests/PSScriptAnalyzer/PSScriptAnalyzer.Tests.ps1 + + - name: Assert report paths + shell: pwsh + run: | + tests/Assert-ReportPaths.ps1 ` + -WorkingDirectory tests/srcTestRepo ` + -TestResultPath artifacts/TestResult/results.xml ` + -CodeCoveragePath artifacts/CodeCoverage/coverage.xml ` + -ArtifactDirectory artifacts ` + -UnexpectedDirectory TestResult,CodeCoverage,.temp + + ActionTestInvokePesterDefaultReportPaths: + name: Action-Test - [Invoke-Pester Default Report Paths] + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + + - name: Action-Test + uses: ./ + id: action-test + with: + Path: src + WorkingDirectory: tests/srcTestRepo + TestResult_Enabled: true + TestResult_OutputFormat: NUnitXml + CodeCoverage_Enabled: true + CodeCoverage_OutputFormat: JaCoCo + CodeCoverage_Path: ../../src/tests/PSScriptAnalyzer/PSScriptAnalyzer.Tests.ps1 + + - name: Assert report paths + shell: pwsh + run: | + tests/Assert-ReportPaths.ps1 ` + -WorkingDirectory tests/srcTestRepo ` + -TestResultPath TestResult/PSScriptAnalyzer-TestResult-Report.xml ` + -CodeCoveragePath CodeCoverage/PSScriptAnalyzer-CodeCoverage-Report.xml ` + -ArtifactDirectory . ` + -UnexpectedDirectory .temp + ActionTestOutputs: name: Action-Test - [outputs] runs-on: ubuntu-latest @@ -153,6 +217,8 @@ jobs: - ActionTestSrcCustom - ActionTestSrcWithManifest - ActionTestSrcWithManifestDefault + - ActionTestReportPaths + - ActionTestInvokePesterDefaultReportPaths - ActionTestOutputs if: always() runs-on: ubuntu-latest @@ -165,6 +231,8 @@ jobs: WithManifestConclusion: ${{ needs.ActionTestSrcWithManifest.outputs.Conclusion }} WithManifestDefaultOutcome: ${{ needs.ActionTestSrcWithManifestDefault.outputs.Outcome }} WithManifestDefaultConclusion: ${{ needs.ActionTestSrcWithManifestDefault.outputs.Conclusion }} + ReportPathsResult: ${{ needs.ActionTestReportPaths.result }} + InvokePesterDefaultReportPathsResult: ${{ needs.ActionTestInvokePesterDefaultReportPaths.result }} OutputsOutcome: ${{ needs.ActionTestOutputs.outputs.Outcome }} OutputsConclusion: ${{ needs.ActionTestOutputs.outputs.Conclusion }} steps: diff --git a/README.md b/README.md index 27f0017..8a7945d 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,21 @@ customize rule selection, severity filtering, and custom rule inclusion. | `TestDrive_Enabled` | Enable TestDrive. | false | | | `TestRegistry_Enabled` | Enable TestRegistry. | false | | +When a report output path is empty, `Invoke-Pester` uses its default location +relative to `WorkingDirectory`: + +```text +TestResult/PSScriptAnalyzer-TestResult-Report.xml +CodeCoverage/PSScriptAnalyzer-CodeCoverage-Report.xml +``` + +Set either input to override only that report's location: + +```text +TestResult_OutputPath: artifacts/TestResult/results.xml +CodeCoverage_OutputPath: artifacts/CodeCoverage/coverage.xml +``` + ## Outputs The action provides the following outputs: diff --git a/action.yml b/action.yml index 4efa4b1..81ff981 100644 --- a/action.yml +++ b/action.yml @@ -282,7 +282,7 @@ runs: Script: ${{ github.action_path }}/src/main.ps1 - name: Invoke-Pester - uses: PSModule/Invoke-Pester@4ff33199141fdf22568990b6107fe3148ae93a1c # v5.1.0 + uses: PSModule/Invoke-Pester@c5494aba3c07d7bfd81bdbbc9f301e8fa4a729fb # v5.1.1 id: test env: SettingsFilePath: ${{ fromJson(steps.paths.outputs.result).SettingsFilePath }} diff --git a/tests/Assert-ReportPaths.ps1 b/tests/Assert-ReportPaths.ps1 new file mode 100644 index 0000000..ab96d75 --- /dev/null +++ b/tests/Assert-ReportPaths.ps1 @@ -0,0 +1,73 @@ +[CmdletBinding()] +param( + [Parameter(Mandatory)] + [string] $WorkingDirectory, + + [Parameter(Mandatory)] + [string] $TestResultPath, + + [Parameter(Mandatory)] + [string] $CodeCoveragePath, + + [Parameter(Mandatory)] + [string] $ArtifactDirectory, + + [string[]] $UnexpectedDirectory = @() +) + +function Assert-ReportPath { + <# + .SYNOPSIS + Confirms that an action report is generated in the fixture artifact directory. + #> + [CmdletBinding()] + param( + [Parameter(Mandatory)] + [string] $Path, + + [Parameter(Mandatory)] + [string] $ReportName, + + [Parameter(Mandatory)] + [string] $ArtifactDirectory + ) + + $resolvedPath = [System.IO.Path]::GetFullPath($Path) + $resolvedArtifactDirectory = [System.IO.Path]::GetFullPath($ArtifactDirectory).TrimEnd( + [System.IO.Path]::DirectorySeparatorChar, + [System.IO.Path]::AltDirectorySeparatorChar + ) + [System.IO.Path]::DirectorySeparatorChar + + if (-not $resolvedPath.StartsWith($resolvedArtifactDirectory, [System.StringComparison]::OrdinalIgnoreCase)) { + throw "Expected $ReportName report beneath [$resolvedArtifactDirectory], but found [$resolvedPath]." + } + + foreach ($reportPath in @($resolvedPath, [System.IO.Path]::ChangeExtension($resolvedPath, '.json'))) { + if (-not (Test-Path -Path $reportPath -PathType Leaf)) { + throw "Expected $ReportName report at [$reportPath]." + } + } + + try { + $null = [xml](Get-Content -Path $resolvedPath -Raw) + } catch { + throw "Expected an XML $ReportName report at [$resolvedPath]." + } +} + +$resolvedWorkingDirectory = [System.IO.Path]::GetFullPath($WorkingDirectory) +$artifactDirectory = Join-Path -Path $resolvedWorkingDirectory -ChildPath $ArtifactDirectory + +Assert-ReportPath -Path (Join-Path -Path $resolvedWorkingDirectory -ChildPath $TestResultPath) ` + -ReportName 'test result' ` + -ArtifactDirectory $artifactDirectory +Assert-ReportPath -Path (Join-Path -Path $resolvedWorkingDirectory -ChildPath $CodeCoveragePath) ` + -ReportName 'code coverage' ` + -ArtifactDirectory $artifactDirectory + +foreach ($unexpectedDirectory in $UnexpectedDirectory) { + $unexpectedPath = Join-Path -Path $resolvedWorkingDirectory -ChildPath $unexpectedDirectory + if (Test-Path -Path $unexpectedPath) { + throw "Did not expect generated action state at [$unexpectedPath]." + } +} diff --git a/tests/Get-AggregatedStatus.ps1 b/tests/Get-AggregatedStatus.ps1 index 2ca554c..a8be615 100644 --- a/tests/Get-AggregatedStatus.ps1 +++ b/tests/Get-AggregatedStatus.ps1 @@ -51,6 +51,16 @@ $jobs = @( Outcome = @{ Actual = $env:WithManifestDefaultOutcome; Expected = 'failure' } Conclusion = @{ Actual = $env:WithManifestDefaultConclusion; Expected = 'success' } } + @{ + Name = 'Action-Test - [Report Paths]' + Outcome = @{ Actual = $env:ReportPathsResult; Expected = 'success' } + Conclusion = @{ Actual = $env:ReportPathsResult; Expected = 'success' } + } + @{ + Name = 'Action-Test - [Invoke-Pester Default Report Paths]' + Outcome = @{ Actual = $env:InvokePesterDefaultReportPathsResult; Expected = 'success' } + Conclusion = @{ Actual = $env:InvokePesterDefaultReportPathsResult; Expected = 'success' } + } @{ Name = 'Action-Test - [outputs]' Outcome = @{ Actual = $env:OutputsOutcome; Expected = 'success' }