From ddf797db021c4027f0b834d2969e3b9ccab2cd24 Mon Sep 17 00:00:00 2001 From: Daniel Jurek Date: Wed, 24 Jun 2026 15:47:02 -0700 Subject: [PATCH 1/6] Improve codeowners check-package JSON output Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../scripts/Test-CodeownersForArtifacts.ps1 | 77 +++++++++++++++++-- 1 file changed, 72 insertions(+), 5 deletions(-) diff --git a/eng/common/scripts/Test-CodeownersForArtifacts.ps1 b/eng/common/scripts/Test-CodeownersForArtifacts.ps1 index e721fdd911ab..7aa6fb63d61d 100644 --- a/eng/common/scripts/Test-CodeownersForArtifacts.ps1 +++ b/eng/common/scripts/Test-CodeownersForArtifacts.ps1 @@ -141,6 +141,42 @@ function shouldSkipCodeownersInPrContext([PSCustomObject] $PackageProperties, [P return $true } +function getCheckPackageOutputText([array] $OutputLines) { + if (!$OutputLines) { + return "" + } + + return ((@($OutputLines) | ForEach-Object { "$_" }) -join [Environment]::NewLine).Trim() +} + +function getCheckPackageResponse([string] $OutputText) { + if (!$OutputText) { + return $null + } + + try { + return $OutputText | ConvertFrom-Json -ErrorAction Stop + } + catch { + return $null + } +} + +function getSuggestedPrompts([object] $CheckPackageResponse) { + if (!$CheckPackageResponse -or !$CheckPackageResponse.PSObject.Properties['issues']) { + return ,@() + } + + $prompts = @() + foreach ($issue in @($CheckPackageResponse.issues)) { + if ($issue.next_step) { + $prompts += $issue.next_step + } + } + + return ,@($prompts | Sort-Object -Unique) +} + $failedPackages = @() $prDiff = $null $isPrCheck = $false @@ -158,6 +194,8 @@ if ($PrDiffFile) { Write-Host "SDK types to validate: $($SdkTypes -join ', ')" +LogGroupStart "Validating CODEOWNERS for Artifacts" + foreach ($pkgPropertiesFile in Get-ChildItem -Path $PackageInfoDirectory -Filter '*.json' -File) { $pkgProperties = Get-Content -Raw -Path $pkgPropertiesFile | ConvertFrom-Json $artifactDetails = $pkgProperties.ArtifactDetails @@ -188,11 +226,26 @@ foreach ($pkgPropertiesFile in Get-ChildItem -Path $PackageInfoDirectory -Filter --directory-path $pkgProperties.DirectoryPath ` --repo $Repo ` --output json 2>&1 + $checkPackageExitCode = $LASTEXITCODE + $outputText = getCheckPackageOutputText -OutputLines $output - if ($LASTEXITCODE) { + Write-Host " check-package output:" + if ($outputText) { + Write-Host $outputText + } else { + Write-Host " (no output)" + } + + if ($checkPackageExitCode) { LogError "Codeowners validation failed for package: $($pkgProperties.DirectoryPath)" - $output | Write-Host - $failedPackages += $pkgProperties.DirectoryPath + $checkPackageResponse = getCheckPackageResponse -OutputText $outputText + $failedPackages += [PSCustomObject]@{ + Name = $pkgProperties.Name + DirectoryPath = $pkgProperties.DirectoryPath + ResponseError = if ($checkPackageResponse) { $checkPackageResponse.response_error } else { $null } + SuggestedPrompts = getSuggestedPrompts -CheckPackageResponse $checkPackageResponse + HasParsedResponse = $null -ne $checkPackageResponse + } } else { Write-Host " Codeowners validation succeeded for package: $($pkgProperties.DirectoryPath)" } @@ -201,11 +254,25 @@ foreach ($pkgPropertiesFile in Get-ChildItem -Path $PackageInfoDirectory -Filter } } +LogGroupEnd + if ($failedPackages.Count -gt 0) { Write-Host "" Write-Host "Failed Packages:" - foreach ($directoryPath in $failedPackages) { - LogError " - $directoryPath does not have sufficient code owners coverage" + foreach ($failedPackage in $failedPackages) { + LogError " - $($failedPackage.DirectoryPath) does not have sufficient code owners coverage" + if ($failedPackage.ResponseError) { + Write-Host " $($failedPackage.ResponseError)" + } + + if ($failedPackage.HasParsedResponse -and @($failedPackage.SuggestedPrompts).Count -gt 0) { + Write-Host " Suggested prompt(s):" + foreach ($prompt in $failedPackage.SuggestedPrompts) { + Write-Host " $prompt" + } + } elseif (!$failedPackage.HasParsedResponse) { + Write-Host " Unable to parse check-package output; see grouped output above." + } } LogError "Codeowners validation failed for one or more packages. See http://aka.ms/azsdk/codeowners for instructions to fix the issue." exit 1 From a50c39392dea06ce3783d8ecc64f4add1621afe6 Mon Sep 17 00:00:00 2001 From: Daniel Jurek Date: Fri, 26 Jun 2026 15:07:33 -0700 Subject: [PATCH 2/6] Refine output --- .../scripts/Test-CodeownersForArtifacts.ps1 | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/eng/common/scripts/Test-CodeownersForArtifacts.ps1 b/eng/common/scripts/Test-CodeownersForArtifacts.ps1 index 7aa6fb63d61d..b630579e9c1a 100644 --- a/eng/common/scripts/Test-CodeownersForArtifacts.ps1 +++ b/eng/common/scripts/Test-CodeownersForArtifacts.ps1 @@ -162,19 +162,24 @@ function getCheckPackageResponse([string] $OutputText) { } } -function getSuggestedPrompts([object] $CheckPackageResponse) { +function getCheckPackageIssues([object] $CheckPackageResponse) { if (!$CheckPackageResponse -or !$CheckPackageResponse.PSObject.Properties['issues']) { return ,@() } - $prompts = @() + $issues = @() foreach ($issue in @($CheckPackageResponse.issues)) { - if ($issue.next_step) { - $prompts += $issue.next_step + if (!$issue) { + continue + } + + $issues += [PSCustomObject]@{ + Message = $issue.message + Prompt = $issue.next_step } } - return ,@($prompts | Sort-Object -Unique) + return ,@($issues) } $failedPackages = @() @@ -237,13 +242,13 @@ foreach ($pkgPropertiesFile in Get-ChildItem -Path $PackageInfoDirectory -Filter } if ($checkPackageExitCode) { - LogError "Codeowners validation failed for package: $($pkgProperties.DirectoryPath)" + Write-Host "Codeowners validation failed for package: $($pkgProperties.DirectoryPath)" $checkPackageResponse = getCheckPackageResponse -OutputText $outputText $failedPackages += [PSCustomObject]@{ Name = $pkgProperties.Name DirectoryPath = $pkgProperties.DirectoryPath ResponseError = if ($checkPackageResponse) { $checkPackageResponse.response_error } else { $null } - SuggestedPrompts = getSuggestedPrompts -CheckPackageResponse $checkPackageResponse + Issues = getCheckPackageIssues -CheckPackageResponse $checkPackageResponse HasParsedResponse = $null -ne $checkPackageResponse } } else { @@ -257,24 +262,28 @@ foreach ($pkgPropertiesFile in Get-ChildItem -Path $PackageInfoDirectory -Filter LogGroupEnd if ($failedPackages.Count -gt 0) { + LogError "Codeowners validation failed for one or more packages. See http://aka.ms/azsdk/codeowners for instructions to fix the issue." Write-Host "" Write-Host "Failed Packages:" foreach ($failedPackage in $failedPackages) { LogError " - $($failedPackage.DirectoryPath) does not have sufficient code owners coverage" - if ($failedPackage.ResponseError) { - Write-Host " $($failedPackage.ResponseError)" - } - - if ($failedPackage.HasParsedResponse -and @($failedPackage.SuggestedPrompts).Count -gt 0) { - Write-Host " Suggested prompt(s):" - foreach ($prompt in $failedPackage.SuggestedPrompts) { - Write-Host " $prompt" + if ($failedPackage.HasParsedResponse -and @($failedPackage.Issues).Count -gt 0) { + Write-Host " Issue details:" + foreach ($issue in $failedPackage.Issues) { + if ($issue.Message) { + Write-Host " Error: $($issue.Message)" + } + + if ($issue.Prompt) { + Write-Host " Prompt: $($issue.Prompt)" + } } + } elseif ($failedPackage.ResponseError) { + Write-Host " $($failedPackage.ResponseError)" } elseif (!$failedPackage.HasParsedResponse) { Write-Host " Unable to parse check-package output; see grouped output above." } } - LogError "Codeowners validation failed for one or more packages. See http://aka.ms/azsdk/codeowners for instructions to fix the issue." exit 1 } exit 0 From b5a5d0f42b152841cbe4fd4cc1007c1fad36496b Mon Sep 17 00:00:00 2001 From: Daniel Jurek Date: Mon, 29 Jun 2026 09:59:12 -0700 Subject: [PATCH 3/6] Language --- eng/common/scripts/Test-CodeownersForArtifacts.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/common/scripts/Test-CodeownersForArtifacts.ps1 b/eng/common/scripts/Test-CodeownersForArtifacts.ps1 index b630579e9c1a..8668e25caf8c 100644 --- a/eng/common/scripts/Test-CodeownersForArtifacts.ps1 +++ b/eng/common/scripts/Test-CodeownersForArtifacts.ps1 @@ -275,7 +275,7 @@ if ($failedPackages.Count -gt 0) { } if ($issue.Prompt) { - Write-Host " Prompt: $($issue.Prompt)" + Write-Host " Use this prompt template to fix: $($issue.Prompt)" } } } elseif ($failedPackage.ResponseError) { From 86cd6ca3bbad181a4224717d2e1807512fc289eb Mon Sep 17 00:00:00 2001 From: Daniel Jurek Date: Wed, 8 Jul 2026 13:25:34 -0700 Subject: [PATCH 4/6] Write-Host to prevent DevOps from expanding the logging group in the UI --- eng/common/scripts/Test-CodeownersForArtifacts.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/common/scripts/Test-CodeownersForArtifacts.ps1 b/eng/common/scripts/Test-CodeownersForArtifacts.ps1 index 8668e25caf8c..ee0bb4bf6b45 100644 --- a/eng/common/scripts/Test-CodeownersForArtifacts.ps1 +++ b/eng/common/scripts/Test-CodeownersForArtifacts.ps1 @@ -262,11 +262,11 @@ foreach ($pkgPropertiesFile in Get-ChildItem -Path $PackageInfoDirectory -Filter LogGroupEnd if ($failedPackages.Count -gt 0) { - LogError "Codeowners validation failed for one or more packages. See http://aka.ms/azsdk/codeowners for instructions to fix the issue." Write-Host "" + Write-Host "Codeowners validation failed for one or more packages. See http://aka.ms/azsdk/codeowners for instructions to fix the issue." Write-Host "Failed Packages:" foreach ($failedPackage in $failedPackages) { - LogError " - $($failedPackage.DirectoryPath) does not have sufficient code owners coverage" + Write-Host " - $($failedPackage.DirectoryPath) does not have sufficient code owners coverage" if ($failedPackage.HasParsedResponse -and @($failedPackage.Issues).Count -gt 0) { Write-Host " Issue details:" foreach ($issue in $failedPackage.Issues) { From cd7b0789e18230fdb2ebe4f4601997440531f80f Mon Sep 17 00:00:00 2001 From: Daniel Jurek Date: Wed, 8 Jul 2026 14:24:20 -0700 Subject: [PATCH 5/6] Structure for $failedPackages --- .../scripts/Test-CodeownersForArtifacts.ps1 | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/eng/common/scripts/Test-CodeownersForArtifacts.ps1 b/eng/common/scripts/Test-CodeownersForArtifacts.ps1 index ee0bb4bf6b45..fdec89e623ef 100644 --- a/eng/common/scripts/Test-CodeownersForArtifacts.ps1 +++ b/eng/common/scripts/Test-CodeownersForArtifacts.ps1 @@ -216,9 +216,19 @@ foreach ($pkgPropertiesFile in Get-ChildItem -Path $PackageInfoDirectory -Filter Write-Host "Validating codeowners for package: $($pkgProperties.Name) $($pkgProperties.DirectoryPath)" - if (!$isPrCheck -and !$pkgProperties.ReleaseStatus) { - LogError "Package $($pkgProperties.Name) at $($pkgProperties.DirectoryPath) is missing a ReleaseStatus property." - $failedPackages += $pkgProperties.DirectoryPath + $hasReleaseStatus = $pkgProperties.PSObject.Properties['ReleaseStatus'] -and + ![string]::IsNullOrWhiteSpace([string]$pkgProperties.ReleaseStatus) + + if (!$isPrCheck -and !$hasReleaseStatus) { + $responseError = "Package $($pkgProperties.Name) at $($pkgProperties.DirectoryPath) is missing a ReleaseStatus property." + LogError $responseError + $failedPackages += [PSCustomObject]@{ + Name = $pkgProperties.Name + DirectoryPath = $pkgProperties.DirectoryPath + ResponseError = $responseError + Issues = @() + HasParsedResponse = $false + } continue } From eaf17675ea1de261c788f3c4701e1b2b0884976c Mon Sep 17 00:00:00 2001 From: Daniel Jurek Date: Wed, 8 Jul 2026 14:27:39 -0700 Subject: [PATCH 6/6] s --- eng/common/scripts/Test-CodeownersForArtifacts.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/common/scripts/Test-CodeownersForArtifacts.ps1 b/eng/common/scripts/Test-CodeownersForArtifacts.ps1 index fdec89e623ef..b87444911257 100644 --- a/eng/common/scripts/Test-CodeownersForArtifacts.ps1 +++ b/eng/common/scripts/Test-CodeownersForArtifacts.ps1 @@ -273,7 +273,7 @@ LogGroupEnd if ($failedPackages.Count -gt 0) { Write-Host "" - Write-Host "Codeowners validation failed for one or more packages. See http://aka.ms/azsdk/codeowners for instructions to fix the issue." + Write-Host "Codeowners validation failed for one or more packages. See https://aka.ms/azsdk/codeowners for instructions to fix the issue." Write-Host "Failed Packages:" foreach ($failedPackage in $failedPackages) { Write-Host " - $($failedPackage.DirectoryPath) does not have sufficient code owners coverage"