Skip to content

Commit 06ab106

Browse files
authored
CI Treat Errors As Warnings - ref #2295 (#2296)
1 parent 36b3164 commit 06ab106

File tree

6 files changed

+167
-13
lines changed

6 files changed

+167
-13
lines changed

src/Main.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1239,7 +1239,7 @@ function Invoke-Pester {
12391239

12401240
if ($PesterPreference.Output.CIFormat.Value -in 'AzureDevops', 'GithubActions') {
12411241
$errorMessage = (Format-ErrorMessage @formatErrorParams) -split [Environment]::NewLine
1242-
Write-CIErrorToScreen -CIFormat $PesterPreference.Output.CIFormat.Value -Header $errorMessage[0] -Message $errorMessage[1..($errorMessage.Count - 1)]
1242+
Write-CIErrorToScreen -CIFormat $PesterPreference.Output.CIFormat.Value -CILogLevel $PesterPreference.Output.CILogLevel.Value -Header $errorMessage[0] -Message $errorMessage[1..($errorMessage.Count - 1)]
12431243
}
12441244
else {
12451245
Write-ErrorToScreen @formatErrorParams -Throw:$PesterPreference.Run.Throw.Value

src/Pester.RSpec.ps1

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,9 @@ function New-PesterConfiguration {
408408
CIFormat: The CI format of error output in build logs, options are None, Auto, AzureDevops and GithubActions.
409409
Default value: 'Auto'
410410
411+
CILogLevel: The CI log level in build logs, options are Error and Warning.
412+
Default value: 'Error'
413+
411414
RenderMode: The mode used to render console output, options are Auto, Ansi, ConsoleColor and Plaintext.
412415
Default value: 'Auto'
413416

src/csharp/Pester/OutputConfiguration.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public class OutputConfiguration : ConfigurationSection
2525
private StringOption _verbosity;
2626
private StringOption _stackTraceVerbosity;
2727
private StringOption _ciFormat;
28+
private StringOption _ciLogLevel;
2829
private StringOption _renderMode;
2930

3031
public static OutputConfiguration Default { get { return new OutputConfiguration(); } }
@@ -40,6 +41,7 @@ public OutputConfiguration(IDictionary configuration) : this()
4041
configuration.AssignObjectIfNotNull<string>(nameof(Verbosity), v => Verbosity = v);
4142
configuration.AssignObjectIfNotNull<string>(nameof(StackTraceVerbosity), v => StackTraceVerbosity = v);
4243
configuration.AssignObjectIfNotNull<string>(nameof(CIFormat), v => CIFormat = v);
44+
configuration.AssignObjectIfNotNull<string>(nameof(CILogLevel), v => CILogLevel = v);
4345
configuration.AssignObjectIfNotNull<string>(nameof(RenderMode), v => RenderMode = v);
4446
}
4547
}
@@ -49,6 +51,7 @@ public OutputConfiguration() : base("Output configuration")
4951
Verbosity = new StringOption("The verbosity of output, options are None, Normal, Detailed and Diagnostic.", "Normal");
5052
StackTraceVerbosity = new StringOption("The verbosity of stacktrace output, options are None, FirstLine, Filtered and Full.", "Filtered");
5153
CIFormat = new StringOption("The CI format of error output in build logs, options are None, Auto, AzureDevops and GithubActions.", "Auto");
54+
CILogLevel = new StringOption("The CI log level in build logs, options are Error and Warning.", "Error");
5255
RenderMode = new StringOption("The mode used to render console output, options are Auto, Ansi, ConsoleColor and Plaintext.", "Auto");
5356
}
5457

@@ -100,6 +103,22 @@ public StringOption CIFormat
100103
}
101104
}
102105

106+
public StringOption CILogLevel
107+
{
108+
get { return _ciLogLevel; }
109+
set
110+
{
111+
if (_ciLogLevel == null)
112+
{
113+
_ciLogLevel = value;
114+
}
115+
else
116+
{
117+
_ciLogLevel = new StringOption(_ciLogLevel, value?.Value);
118+
}
119+
}
120+
}
121+
103122
public StringOption RenderMode
104123
{
105124
get { return _renderMode; }

src/functions/Output.ps1

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ function Write-PesterHostMessage {
150150
$message = "$($message -replace '(?m)^', "$fg$bg")$($ANSIcodes.ResetAll)"
151151

152152
& $SafeCommands['Write-Host'] -Object $message -NoNewLine:$NoNewLine
153-
} else {
153+
}
154+
else {
154155
if ($RenderMode -eq 'Plaintext') {
155156
if ($PSBoundParameters.ContainsKey('ForegroundColor')) {
156157
$null = $PSBoundParameters.Remove('ForegroundColor')
@@ -627,7 +628,7 @@ function Get-WriteScreenPlugin ($Verbosity) {
627628

628629
if ($PesterPreference.Output.CIFormat.Value -in 'AzureDevops', 'GithubActions') {
629630
$errorMessage = (Format-ErrorMessage @formatErrorParams) -split [Environment]::NewLine
630-
Write-CIErrorToScreen -CIFormat $PesterPreference.Output.CIFormat.Value -Header $errorHeader -Message $errorMessage
631+
Write-CIErrorToScreen -CIFormat $PesterPreference.Output.CIFormat.Value -CILogLevel $PesterPreference.Output.CILogLevel.Value -Header $errorHeader -Message $errorMessage
631632
}
632633
else {
633634
Write-PesterHostMessage -ForegroundColor $ReportTheme.Fail $errorHeader
@@ -700,7 +701,7 @@ function Get-WriteScreenPlugin ($Verbosity) {
700701

701702
if ($PesterPreference.Output.CIFormat.Value -in 'AzureDevops', 'GithubActions') {
702703
$errorMessage = (Format-ErrorMessage @formatErrorParams) -split [Environment]::NewLine
703-
Write-CIErrorToScreen -CIFormat $PesterPreference.Output.CIFormat.Value -Header $errorHeader -Message $errorMessage
704+
Write-CIErrorToScreen -CIFormat $PesterPreference.Output.CIFormat.Value -CILogLevel $PesterPreference.Output.CILogLevel.Value -Header $errorHeader -Message $errorMessage
704705
}
705706
else {
706707
Write-PesterHostMessage -ForegroundColor $ReportTheme.Fail $errorHeader
@@ -775,6 +776,10 @@ function Get-WriteScreenPlugin ($Verbosity) {
775776
throw "Unsupported CI format '$($PesterPreference.Output.CIFormat.Value)'"
776777
}
777778

779+
if ($PesterPreference.Output.CILogLevel.Value -notin 'Error', 'Warning') {
780+
throw "Unsupported CI log level '$($PesterPreference.Output.CILogLevel.Value)'"
781+
}
782+
778783
$humanTime = "$(Get-HumanTime ($_test.Duration)) ($(Get-HumanTime $_test.UserDuration)|$(Get-HumanTime $_test.FrameworkDuration))"
779784

780785
if ($PesterPreference.Debug.ShowNavigationMarkers.Value) {
@@ -817,7 +822,7 @@ function Get-WriteScreenPlugin ($Verbosity) {
817822

818823
if ($PesterPreference.Output.CIFormat.Value -in 'AzureDevops', 'GithubActions') {
819824
$errorMessage = (Format-ErrorMessage @formatErrorParams) -split [Environment]::NewLine
820-
Write-CIErrorToScreen -CIFormat $PesterPreference.Output.CIFormat.Value -Header "$margin[-] $out $humanTime" -Message $errorMessage
825+
Write-CIErrorToScreen -CIFormat $PesterPreference.Output.CIFormat.Value -CILogLevel $PesterPreference.Output.CILogLevel.Value -Header "$margin[-] $out $humanTime" -Message $errorMessage
821826
}
822827
else {
823828
Write-PesterHostMessage -ForegroundColor $ReportTheme.Fail "$margin[-] $out" -NoNewLine
@@ -920,7 +925,7 @@ function Get-WriteScreenPlugin ($Verbosity) {
920925

921926
if ($PesterPreference.Output.CIFormat.Value -in 'AzureDevops', 'GithubActions') {
922927
$errorMessage = (Format-ErrorMessage @formatErrorParams) -split [Environment]::NewLine
923-
Write-CIErrorToScreen -CIFormat $PesterPreference.Output.CIFormat.Value -Header $errorHeader -Message $errorMessage
928+
Write-CIErrorToScreen -CIFormat $PesterPreference.Output.CIFormat.Value -CILogLevel $PesterPreference.Output.CILogLevel.Value -Header $errorHeader -Message $errorMessage
924929
}
925930
else {
926931
Write-PesterHostMessage -ForegroundColor $ReportTheme.BlockFail $errorHeader
@@ -945,6 +950,10 @@ function Format-CIErrorMessage {
945950
[ValidateSet('AzureDevops', 'GithubActions', IgnoreCase)]
946951
[string] $CIFormat,
947952

953+
[Parameter(Mandatory)]
954+
[ValidateSet('Error', 'Warning', IgnoreCase)]
955+
[string] $CILogLevel,
956+
948957
[Parameter(Mandatory)]
949958
[string] $Header,
950959

@@ -962,20 +971,33 @@ function Format-CIErrorMessage {
962971

963972
# header task issue error, so it gets reported to build log
964973
# https://docs.microsoft.com/en-us/azure/devops/pipelines/scripts/logging-commands?view=azure-devops&tabs=powershell#example-log-an-error
965-
$headerTaskIssueError = "##vso[task.logissue type=error] $Header"
966-
$lines.Add($headerTaskIssueError)
974+
# https://learn.microsoft.com/en-us/azure/devops/pipelines/scripts/logging-commands?view=azure-devops&tabs=powershell#example-log-a-warning-about-a-specific-place-in-a-file
975+
switch ($CILogLevel) {
976+
"Error" { $logIssueType = 'error' }
977+
"Warning" { $logIssueType = 'warning' }
978+
Default { $logIssueType = 'error' }
979+
}
980+
981+
$headerLoggingCommand = "##vso[task.logissue type=$logIssueType] $Header"
982+
$lines.Add($headerLoggingCommand)
967983

968984
# Add subsequent messages as errors, but do not get reported to build log
969985
foreach ($line in $Message) {
970-
$lines.Add("##[error] $line")
986+
$lines.Add("##[$logIssueType] $line")
971987
}
972988
}
973989
elseif ($CIFormat -eq 'GithubActions') {
974990

975991
# header error, so it gets reported to build log
976992
# https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
977-
$headerError = "::error::$($Header.TrimStart())"
978-
$lines.Add($headerError)
993+
# https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message
994+
switch ($CILogLevel) {
995+
"Error" { $headerWorkflowCommand = "::error::$($Header.TrimStart())" }
996+
"Warning" { $headerWorkflowCommand = "::warning::$($Header.TrimStart())" }
997+
Default { $headerWorkflowCommand = "::error::$($Header.TrimStart())" }
998+
}
999+
1000+
$lines.Add($headerWorkflowCommand)
9791001

9801002
# Add rest of messages inside expandable group
9811003
# https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#grouping-log-lines
@@ -998,6 +1020,10 @@ function Write-CIErrorToScreen {
9981020
[ValidateSet('AzureDevops', 'GithubActions', IgnoreCase)]
9991021
[string] $CIFormat,
10001022

1023+
[Parameter(Mandatory)]
1024+
[ValidateSet('Error', 'Warning', IgnoreCase)]
1025+
[string] $CILogLevel,
1026+
10011027
[Parameter(Mandatory)]
10021028
[string] $Header,
10031029

tst/Pester.RSpec.Configuration.ts.ps1

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ i -PassThru:$PassThru {
9898
[PesterConfiguration]::Default.Output.CIFormat.Value | Verify-Equal Auto
9999
}
100100

101+
t "Output.CILogLevel is Error" {
102+
[PesterConfiguration]::Default.Output.CILogLevel.Value | Verify-Equal 'Error'
103+
}
104+
101105
t "Output.RenderMode is Auto" {
102106
[PesterConfiguration]::Default.Output.RenderMode.Value | Verify-Equal 'Auto'
103107
}
@@ -1118,6 +1122,45 @@ i -PassThru:$PassThru {
11181122
}
11191123
}
11201124

1125+
b "Output.CILogLevel" {
1126+
t "Each option can be set and updated" {
1127+
$c = [PesterConfiguration] @{
1128+
Run = @{
1129+
ScriptBlock = { }
1130+
PassThru = $true
1131+
}
1132+
}
1133+
1134+
foreach ($option in "Error", "Warning") {
1135+
$c.Output.CILogLevel = $option
1136+
$r = Invoke-Pester -Configuration $c
1137+
$r.Configuration.Output.CILogLevel.Value | Verify-Equal $option
1138+
}
1139+
}
1140+
1141+
t "Exception is thrown when incorrect option is set" {
1142+
$sb = {
1143+
Describe "a" {
1144+
It "b" {}
1145+
}
1146+
}
1147+
1148+
$c = [PesterConfiguration] @{
1149+
Run = @{
1150+
ScriptBlock = $sb
1151+
PassThru = $true
1152+
Throw = $true
1153+
}
1154+
Output = @{
1155+
CIFormat = 'None'
1156+
CILogLevel = 'Something'
1157+
}
1158+
}
1159+
1160+
{ Invoke-Pester -Configuration $c } | Verify-Throw
1161+
}
1162+
}
1163+
11211164
b 'Output.RenderMode' {
11221165
t 'Output.RenderMode is Plaintext when set to Auto (default) and env:NO_COLOR is set' {
11231166
$c = [PesterConfiguration] @{

tst/functions/Output.Tests.ps1

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,31 @@ InModuleScope -ModuleName Pester -ScriptBlock {
624624
)
625625
}
626626
) {
627-
Format-CIErrorMessage -CIFormat 'AzureDevops' -Header $Header -Message $Message | Should -Be $Expected
627+
Format-CIErrorMessage -CIFormat 'AzureDevops' -CILogLevel 'Error' -Header $Header -Message $Message | Should -Be $Expected
628+
}
629+
}
630+
631+
Context "Azure Devops Warning Format" {
632+
It "Header '<header>' and Message '<message>' returns '<expected>'" -TestCases @(
633+
@{
634+
Header = 'header'
635+
Message = 'message'
636+
Expected = @(
637+
'##vso[task.logissue type=warning] header',
638+
'##[warning] message'
639+
)
640+
}
641+
@{
642+
Header = 'header'
643+
Message = @('message1', 'message2')
644+
Expected = @(
645+
'##vso[task.logissue type=warning] header',
646+
'##[warning] message1',
647+
'##[warning] message2'
648+
)
649+
}
650+
) {
651+
Format-CIErrorMessage -CIFormat 'AzureDevops' -CILogLevel 'Warning' -Header $Header -Message $Message | Should -Be $Expected
628652
}
629653
}
630654

@@ -663,7 +687,46 @@ InModuleScope -ModuleName Pester -ScriptBlock {
663687
)
664688
}
665689
) {
666-
Format-CIErrorMessage -CIFormat 'GithubActions' -Header $Header -Message $Message | Should -Be $Expected
690+
Format-CIErrorMessage -CIFormat 'GithubActions' -CILogLevel 'Error' -Header $Header -Message $Message | Should -Be $Expected
691+
}
692+
}
693+
694+
Context 'Github Actions Warning Format' {
695+
It "Header '<header>' and Message '<message>' returns '<expected>'" -TestCases @(
696+
@{
697+
Header = 'header'
698+
Message = 'message'
699+
Expected = @(
700+
'::warning::header',
701+
'::group::Message',
702+
'message',
703+
'::endgroup::'
704+
)
705+
}
706+
@{
707+
Header = 'header'
708+
Message = @('message1', 'message2')
709+
Expected = @(
710+
'::warning::header',
711+
'::group::Message',
712+
'message1',
713+
'message2',
714+
'::endgroup::'
715+
)
716+
}
717+
@{
718+
Header = 'header'
719+
Message = @(' message1', ' message2')
720+
Expected = @(
721+
'::warning::header',
722+
'::group::Message',
723+
'message1',
724+
'message2',
725+
'::endgroup::'
726+
)
727+
}
728+
) {
729+
Format-CIErrorMessage -CIFormat 'GithubActions' -CILogLevel 'Warning' -Header $Header -Message $Message | Should -Be $Expected
667730
}
668731
}
669732
}

0 commit comments

Comments
 (0)