diff --git a/eng/common/scripts/Test-CodeownersForArtifacts.ps1 b/eng/common/scripts/Test-CodeownersForArtifacts.ps1 index e721fdd911ab..b87444911257 100644 --- a/eng/common/scripts/Test-CodeownersForArtifacts.ps1 +++ b/eng/common/scripts/Test-CodeownersForArtifacts.ps1 @@ -141,6 +141,47 @@ 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 getCheckPackageIssues([object] $CheckPackageResponse) { + if (!$CheckPackageResponse -or !$CheckPackageResponse.PSObject.Properties['issues']) { + return ,@() + } + + $issues = @() + foreach ($issue in @($CheckPackageResponse.issues)) { + if (!$issue) { + continue + } + + $issues += [PSCustomObject]@{ + Message = $issue.message + Prompt = $issue.next_step + } + } + + return ,@($issues) +} + $failedPackages = @() $prDiff = $null $isPrCheck = $false @@ -158,6 +199,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 @@ -173,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 } @@ -188,11 +241,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) { - LogError "Codeowners validation failed for package: $($pkgProperties.DirectoryPath)" - $output | Write-Host - $failedPackages += $pkgProperties.DirectoryPath + Write-Host " check-package output:" + if ($outputText) { + Write-Host $outputText + } else { + Write-Host " (no output)" + } + + if ($checkPackageExitCode) { + 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 } + Issues = getCheckPackageIssues -CheckPackageResponse $checkPackageResponse + HasParsedResponse = $null -ne $checkPackageResponse + } } else { Write-Host " Codeowners validation succeeded for package: $($pkgProperties.DirectoryPath)" } @@ -201,13 +269,31 @@ foreach ($pkgPropertiesFile in Get-ChildItem -Path $PackageInfoDirectory -Filter } } +LogGroupEnd + if ($failedPackages.Count -gt 0) { Write-Host "" + 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 ($directoryPath in $failedPackages) { - LogError " - $directoryPath does not have sufficient code owners coverage" + foreach ($failedPackage in $failedPackages) { + 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) { + if ($issue.Message) { + Write-Host " Error: $($issue.Message)" + } + + if ($issue.Prompt) { + Write-Host " Use this prompt template to fix: $($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