|
1 | | -#Requires -Modules GitHub |
| 1 | +#Requires -Modules GitHub |
2 | 2 |
|
| 3 | +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( |
| 4 | + 'PSAvoidUsingWriteHost', '', |
| 5 | + Justification = 'Outputs to GitHub Actions logs.' |
| 6 | +)] |
3 | 7 | [CmdletBinding()] |
4 | 8 | param() |
5 | 9 |
|
6 | | -begin { |
7 | | - $scriptName = $MyInvocation.MyCommand.Name |
8 | | - Write-Debug "[$scriptName] - Start" |
| 10 | +$owner = $env:GITHUB_REPOSITORY_OWNER |
| 11 | +$repo = $env:GITHUB_REPOSITORY_NAME |
| 12 | +$runId = $env:GITHUB_RUN_ID |
| 13 | + |
| 14 | +$files = Get-GitHubArtifact -Owner $owner -Repository $repo -WorkflowRunID $runId -Name '*-TestResults' | |
| 15 | + Save-GitHubArtifact -Path 'TestResults' -Force -Expand -PassThru | Get-ChildItem -Recurse -Filter *.json | Sort-Object Name -Unique |
| 16 | + |
| 17 | +LogGroup 'List files' { |
| 18 | + $files.Name | Out-String |
9 | 19 | } |
10 | 20 |
|
11 | | -process { |
12 | | - try { |
13 | | - Write-Output "Hello, $Subject!" |
14 | | - } catch { |
15 | | - throw $_ |
| 21 | +$sourceCodeTestSuites = $env:PSMODULE_GET_PESTERTESTRESULTS_INPUT_SourceCodeTestSuites | ConvertFrom-Json |
| 22 | +$psModuleTestSuites = $env:PSMODULE_GET_PESTERTESTRESULTS_INPUT_PSModuleTestSuites | ConvertFrom-Json |
| 23 | +$moduleTestSuites = $env:PSMODULE_GET_PESTERTESTRESULTS_INPUT_ModuleTestSuites | ConvertFrom-Json |
| 24 | + |
| 25 | +LogGroup 'Expected test suites' { |
| 26 | + |
| 27 | + # Build an array of expected test suite objects |
| 28 | + $expectedTestSuites = @() |
| 29 | + |
| 30 | + # SourceCodeTestSuites: expected file names start with "SourceCode-" |
| 31 | + foreach ($suite in $sourceCodeTestSuites) { |
| 32 | + $expectedTestSuites += [pscustomobject]@{ |
| 33 | + Name = "PSModuleTest-SourceCode-$($suite.OSName)-TestResult-Report" |
| 34 | + Category = 'SourceCode' |
| 35 | + OSName = $suite.OSName |
| 36 | + TestName = $null |
| 37 | + } |
| 38 | + $expectedTestSuites += [pscustomobject]@{ |
| 39 | + Name = "PSModuleLint-SourceCode-$($suite.OSName)-TestResult-Report" |
| 40 | + Category = 'SourceCode' |
| 41 | + OSName = $suite.OSName |
| 42 | + TestName = $null |
| 43 | + } |
| 44 | + } |
| 45 | + |
| 46 | + # PSModuleTestSuites: expected file names start with "Module-" |
| 47 | + foreach ($suite in $psModuleTestSuites) { |
| 48 | + $expectedTestSuites += [pscustomobject]@{ |
| 49 | + Name = "PSModuleTest-Module-$($suite.OSName)-TestResult-Report" |
| 50 | + Category = 'PSModuleTest' |
| 51 | + OSName = $suite.OSName |
| 52 | + TestName = $null |
| 53 | + } |
| 54 | + $expectedTestSuites += [pscustomobject]@{ |
| 55 | + Name = "PSModuleLint-Module-$($suite.OSName)-TestResult-Report" |
| 56 | + Category = 'PSModuleTest' |
| 57 | + OSName = $suite.OSName |
| 58 | + TestName = $null |
| 59 | + } |
| 60 | + } |
| 61 | + |
| 62 | + # ModuleTestSuites: expected file names use the TestName as prefix |
| 63 | + foreach ($suite in $moduleTestSuites) { |
| 64 | + $expectedTestSuites += [pscustomobject]@{ |
| 65 | + Name = "$($suite.TestName)-$($suite.OSName)-TestResult-Report" |
| 66 | + Category = 'ModuleTest' |
| 67 | + OSName = $suite.OSName |
| 68 | + TestName = $suite.TestName |
| 69 | + } |
| 70 | + } |
| 71 | + |
| 72 | + $expectedTestSuites = $expectedTestSuites | Sort-Object Category, Name |
| 73 | + $expectedTestSuites | Format-Table | Out-String |
| 74 | +} |
| 75 | +$isFailure = $false |
| 76 | + |
| 77 | +$testResults = [System.Collections.Generic.List[psobject]]::new() |
| 78 | +$failedTests = [System.Collections.Generic.List[psobject]]::new() |
| 79 | +$unexecutedTests = [System.Collections.Generic.List[psobject]]::new() |
| 80 | +$totalErrors = 0 |
| 81 | + |
| 82 | +foreach ($expected in $expectedTestSuites) { |
| 83 | + $file = $files | Where-Object { $_.BaseName -eq $expected.Name } |
| 84 | + $result = if ($file) { |
| 85 | + $object = $file | Get-Content | ConvertFrom-Json |
| 86 | + [pscustomobject]@{ |
| 87 | + Result = $object.Result |
| 88 | + Executed = $object.Executed |
| 89 | + ResultFilePresent = $true |
| 90 | + Tests = [int]([math]::Round(($object | Measure-Object -Sum -Property TotalCount).Sum)) |
| 91 | + Passed = [int]([math]::Round(($object | Measure-Object -Sum -Property PassedCount).Sum)) |
| 92 | + Failed = [int]([math]::Round(($object | Measure-Object -Sum -Property FailedCount).Sum)) |
| 93 | + NotRun = [int]([math]::Round(($object | Measure-Object -Sum -Property NotRunCount).Sum)) |
| 94 | + Inconclusive = [int]([math]::Round(($object | Measure-Object -Sum -Property InconclusiveCount).Sum)) |
| 95 | + Skipped = [int]([math]::Round(($object | Measure-Object -Sum -Property SkippedCount).Sum)) |
| 96 | + } |
| 97 | + } else { |
| 98 | + [pscustomobject]@{ |
| 99 | + Result = $null |
| 100 | + Executed = $null |
| 101 | + ResultFilePresent = $false |
| 102 | + Tests = $null |
| 103 | + Passed = $null |
| 104 | + Failed = $null |
| 105 | + NotRun = $null |
| 106 | + Inconclusive = $null |
| 107 | + Skipped = $null |
| 108 | + } |
| 109 | + } |
| 110 | + |
| 111 | + # Determine if there’s any failure for this single test file |
| 112 | + $testFailure = ( |
| 113 | + $result.Result -ne 'Passed' -or |
| 114 | + $result.Executed -ne $true -or |
| 115 | + $result.ResultFilePresent -eq $false -or |
| 116 | + $result.Tests -eq 0 -or |
| 117 | + $result.Passed -eq 0 -or |
| 118 | + $result.Failed -gt 0 -or |
| 119 | + $result.Inconclusive -gt 0 |
| 120 | + ) |
| 121 | + |
| 122 | + if ($testFailure) { |
| 123 | + $conclusion = 'Failed' |
| 124 | + $color = $PSStyle.Foreground.Red |
| 125 | + $isFailure = $true |
| 126 | + } else { |
| 127 | + $conclusion = 'Passed' |
| 128 | + $color = $PSStyle.Foreground.Green |
| 129 | + } |
| 130 | + $result | Add-Member -NotePropertyName 'Conclusion' -NotePropertyValue $conclusion |
| 131 | + |
| 132 | + $reset = $PSStyle.Reset |
| 133 | + $logGroupName = $expected.Name -replace '-TestResult-Report.*', '' |
| 134 | + |
| 135 | + LogGroup " - $color$logGroupName$reset" { |
| 136 | + if ($result.Executed -eq $false) { |
| 137 | + $unexecutedTests.Add($expected.Name) |
| 138 | + Write-GitHubError "Test was not executed as reported in file: $($expected.Name)" |
| 139 | + $totalErrors++ |
| 140 | + } elseif ($result.Result -eq 'Failed') { |
| 141 | + $failedTests.Add($expected.Name) |
| 142 | + Write-GitHubError "Test result explicitly marked as Failed in file: $($expected.Name)" |
| 143 | + $totalErrors++ |
| 144 | + } |
| 145 | + $result | Format-Table | Out-String |
| 146 | + } |
| 147 | + |
| 148 | + if ($result.ResultFilePresent) { |
| 149 | + $testResults.Add($result) |
16 | 150 | } |
17 | 151 | } |
18 | 152 |
|
19 | | -end { |
20 | | - Write-Debug "[$scriptName] - End" |
| 153 | +Write-Output ('─' * 50) |
| 154 | +$total = [pscustomobject]@{ |
| 155 | + Tests = [int]([math]::Round(($testResults | Measure-Object -Sum -Property Tests).Sum)) |
| 156 | + Passed = [int]([math]::Round(($testResults | Measure-Object -Sum -Property Passed).Sum)) |
| 157 | + Failed = [int]([math]::Round(($testResults | Measure-Object -Sum -Property Failed).Sum)) |
| 158 | + NotRun = [int]([math]::Round(($testResults | Measure-Object -Sum -Property NotRun).Sum)) |
| 159 | + Inconclusive = [int]([math]::Round(($testResults | Measure-Object -Sum -Property Inconclusive).Sum)) |
| 160 | + Skipped = [int]([math]::Round(($testResults | Measure-Object -Sum -Property Skipped).Sum)) |
21 | 161 | } |
| 162 | + |
| 163 | + |
| 164 | +$color = if ($isFailure) { $PSStyle.Foreground.Red } else { $PSStyle.Foreground.Green } |
| 165 | +$reset = $PSStyle.Reset |
| 166 | +LogGroup " - $color`Summary$reset" { |
| 167 | + $total | Format-Table | Out-String |
| 168 | + if ($total.Failed -gt 0) { |
| 169 | + Write-GitHubError "There are $($total.Failed) failed tests of $($total.Tests) tests" |
| 170 | + $totalErrors += $total.Failed |
| 171 | + } |
| 172 | + if ($total.Inconclusive -gt 0) { |
| 173 | + Write-GitHubError "There are $($total.Inconclusive) inconclusive tests of $($total.Tests) tests" |
| 174 | + $totalErrors += $total.Inconclusive |
| 175 | + } |
| 176 | + if ($failedTests.Count -gt 0) { |
| 177 | + Write-Host 'Failed Test Files' |
| 178 | + $failedTests | ForEach-Object { Write-Host " - $_" } |
| 179 | + } |
| 180 | + if ($unexecutedTests.Count -gt 0) { |
| 181 | + Write-Host 'Unexecuted Test Files' |
| 182 | + $unexecutedTests | ForEach-Object { Write-Host " - $_" } |
| 183 | + } |
| 184 | +} |
| 185 | + |
| 186 | +exit $totalErrors |
0 commit comments