Add Get-RepositoryLabels.ps1 script to triage-meeting-prep skill#6191
Add Get-RepositoryLabels.ps1 script to triage-meeting-prep skill#6191lauren-ciha wants to merge 10 commits intomainfrom
Conversation
- Add copyright headers to PowerShell scripts - Add Set-StrictMode -Version 2.0 and ErrorActionPreference - Fix null reference issues for author, milestone, and reaction counts - Add explicit exit 0 for successful execution - Add license field to SKILL.md frontmatter - Fix broken emoji in template-summary.md - Fix duplicate step/phase numbering in workflow-triage-prep.md
StrictMode and ErrorActionPreference must be inside the begin block when using begin/process/end pipeline structure
Update workflow-triage-prep.md to match the actual JSON schema produced by Save-TriageState.ps1: - Replace noAreaIssues/closedIssues structure with flat 'issues' object - Remove non-existent fields: firstSeen, weeksPending, lastSuggestedAction, reviewPath - Add actual fields: generatedAt, issueCount, state, author, commentCount, reactionCount, labels, milestone - Update pseudocode references from previousState.allIssues to previousState.issues Addresses PR review comment about schema repetition/inconsistency.
…tation" This reverts commit 47ad69d.
The issue number is already used as the dictionary key, so storing it again inside the value object is redundant. Removed from: - Save-TriageState.ps1 - Compare-TriageState.ps1 - workflow-triage-prep.md documentation schema Addresses PR review comment about information repetition.
Addresses 5 review comments from copilot-pull-request-reviewer: Save-TriageState.ps1: - Fix triageDate and generatedAt to use ToUniversalTime() for proper UTC Compare-TriageState.ps1: - Fix state comparison to use case-insensitive (-ieq) since GitHub API returns uppercase OPEN/CLOSED - Fix summary output timestamp to use ToUniversalTime() for proper UTC
…gress Addresses review comments from copilot-pull-request-reviewer: Get-TriageIssues.ps1 & Get-IssueDetails.ps1: - Add ValidatePattern to validate owner/repo format for Repository parameter - Prevents potential injection via malformed repository names All scripts: - Change progress Write-Host to Write-Verbose for automation support - Users can now control verbosity with -Verbose switch - Summary output Write-Host retained (user-facing display) Note: .WriteError() suggestion deferred as larger refactor. See Generated Files/prReview/6179/fixPlan/overview.md for details.
- New script to fetch all label definitions from a GitHub repository - Supports filtering by label name pattern (e.g., 'area-*') - Three output formats: json, summary, and table - Color output: hex color codes displayed in their actual colors - Dark colors shown with light background for visibility - Updated SKILL.md with script documentation and examples
There was a problem hiding this comment.
Pull request overview
This pull request adds a new PowerShell script Get-RepositoryLabels.ps1 to the triage-meeting-prep Agent Skills folder, providing functionality to fetch and display GitHub repository label definitions with support for filtering and multiple output formats. The script includes color visualization using ANSI escape sequences to display label colors in their actual hues.
Changes:
- New
Get-RepositoryLabels.ps1script with JSON, summary, and table output formats - Color rendering feature with brightness-based background adjustment for visibility
- Updated
SKILL.mdwith documentation for the new script, including parameters and use cases
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
.github/skills/triage-meeting-prep/scripts/Get-RepositoryLabels.ps1 |
New script to fetch repository labels with filtering, color visualization, and multiple output formats |
.github/skills/triage-meeting-prep/SKILL.md |
Added documentation for Get-RepositoryLabels.ps1 with parameters, examples, and use cases; minor text update to References section |
| # Parse hex color to RGB | ||
| $r = [Convert]::ToInt32($HexColor.Substring(0, 2), 16) | ||
| $g = [Convert]::ToInt32($HexColor.Substring(2, 2), 16) | ||
| $b = [Convert]::ToInt32($HexColor.Substring(4, 2), 16) |
There was a problem hiding this comment.
The Get-ColoredText function doesn't validate that the hex color string is exactly 6 characters long before calling Substring. If GitHub returns a malformed color (e.g., shorter than 6 characters or empty), the Substring calls will throw an ArgumentOutOfRangeException. Add validation to check the hex color length and handle malformed data gracefully, either by using a default color or skipping color formatting.
| # Calculate column widths | ||
| $nameWidth = ($labels | ForEach-Object { $_.name.Length } | Measure-Object -Maximum).Maximum | ||
| $nameWidth = [Math]::Max($nameWidth, 4) + 2 # At least "Name" width + padding | ||
|
|
||
| $descWidth = ($labels | ForEach-Object { | ||
| $desc = if ($_.description) { $_.description } else { '(no description)' } | ||
| $desc.Length | ||
| } | Measure-Object -Maximum).Maximum | ||
| $descWidth = [Math]::Max($descWidth, 11) + 2 # At least "Description" width + padding |
There was a problem hiding this comment.
When no labels are found or all labels are filtered out, the Measure-Object -Maximum operation on lines 228 and 231-234 will return $null for the Maximum property, which could cause issues with the subsequent [Math]::Max calls. Consider adding a check to handle the case when $labels is empty or when Measure-Object returns $null, and provide appropriate default width values or a message indicating no labels were found.
| # Calculate column widths | |
| $nameWidth = ($labels | ForEach-Object { $_.name.Length } | Measure-Object -Maximum).Maximum | |
| $nameWidth = [Math]::Max($nameWidth, 4) + 2 # At least "Name" width + padding | |
| $descWidth = ($labels | ForEach-Object { | |
| $desc = if ($_.description) { $_.description } else { '(no description)' } | |
| $desc.Length | |
| } | Measure-Object -Maximum).Maximum | |
| $descWidth = [Math]::Max($descWidth, 11) + 2 # At least "Description" width + padding | |
| # If there are no labels to display, avoid table rendering and width calculations | |
| if (-not $labels -or $labels.Count -eq 0) { | |
| Write-Host "" | |
| Write-Host "No labels found to display." -ForegroundColor Yellow | |
| break | |
| } | |
| # Calculate column widths | |
| $nameMax = ($labels | ForEach-Object { $_.name.Length } | Measure-Object -Maximum).Maximum | |
| if ($null -eq $nameMax) { | |
| $nameMax = 0 | |
| } | |
| $nameWidth = [Math]::Max($nameMax, 4) + 2 # At least "Name" width + padding | |
| $descMax = ($labels | ForEach-Object { | |
| $desc = if ($_.description) { $_.description } else { '(no description)' } | |
| $desc.Length | |
| } | Measure-Object -Maximum).Maximum | |
| if ($null -eq $descMax) { | |
| $descMax = 0 | |
| } | |
| $descWidth = [Math]::Max($descMax, 11) + 2 # At least "Description" width + padding |
| .PARAMETER IncludeEmpty | ||
| If specified, includes labels that have no description. | ||
| By default, labels without descriptions are included but highlighted in summary view. | ||
|
|
There was a problem hiding this comment.
The documentation says the IncludeEmpty parameter "includes labels that have no description" and that "by default, labels without descriptions are included but highlighted in summary view." However, the parameter is never referenced in the code, making the documentation misleading. Either remove this parameter documentation or implement the functionality.
| .PARAMETER IncludeEmpty | |
| If specified, includes labels that have no description. | |
| By default, labels without descriptions are included but highlighted in summary view. |
| function Get-ColoredText { | ||
| param( | ||
| [string]$HexColor, | ||
| [string]$Text | ||
| ) |
There was a problem hiding this comment.
The Get-ColoredText helper function doesn't follow PowerShell best practices for error handling. According to the PowerShell Cmdlet Development Guidelines (guideline 1000003), functions should handle errors properly and include proper parameter validation. The function should validate that HexColor is not null or empty, and that it's a valid 6-character hex string before attempting to parse it.
| # Parse hex color to RGB | ||
| $r = [Convert]::ToInt32($HexColor.Substring(0, 2), 16) | ||
| $g = [Convert]::ToInt32($HexColor.Substring(2, 2), 16) | ||
| $b = [Convert]::ToInt32($HexColor.Substring(4, 2), 16) | ||
|
|
There was a problem hiding this comment.
The [Convert]::ToInt32 calls will throw a FormatException if the hex color contains invalid characters (non-hexadecimal). While the script has ErrorActionPreference set to 'Stop', there's no try-catch block around the color parsing to provide a helpful error message. Consider wrapping the Get-ColoredText calls in try-catch blocks or adding validation within the function to handle malformed color data gracefully and provide clear error messages about which label has an invalid color.
| # Parse hex color to RGB | |
| $r = [Convert]::ToInt32($HexColor.Substring(0, 2), 16) | |
| $g = [Convert]::ToInt32($HexColor.Substring(2, 2), 16) | |
| $b = [Convert]::ToInt32($HexColor.Substring(4, 2), 16) | |
| # Validate hex color format before parsing | |
| if (-not $HexColor -or $HexColor.Length -ne 6 -or $HexColor -notmatch '^[0-9A-Fa-f]{6}$') { | |
| $labelInfo = if ($Text) { " for label '$Text'" } else { '' } | |
| throw "Invalid hex color '$HexColor'$labelInfo. Expected 6 hexadecimal characters (0-9, A-F)." | |
| } | |
| # Parse hex color to RGB with error handling | |
| try { | |
| $r = [Convert]::ToInt32($HexColor.Substring(0, 2), 16) | |
| $g = [Convert]::ToInt32($HexColor.Substring(2, 2), 16) | |
| $b = [Convert]::ToInt32($HexColor.Substring(4, 2), 16) | |
| } | |
| catch { | |
| $labelInfo = if ($Text) { " for label '$Text'" } else { '' } | |
| throw "Failed to parse hex color '$HexColor'$labelInfo: $($_.Exception.Message)" | |
| } | |
| [Parameter()] | ||
| [switch]$IncludeEmpty |
There was a problem hiding this comment.
The IncludeEmpty parameter is defined but never used in the script. This parameter should either be implemented to filter out empty descriptions, or removed entirely if not needed. Based on the parameter documentation (lines 32-34), it appears this was intended to filter labels without descriptions, but the current implementation always shows all labels regardless of this parameter's value.
A microsoft employee must use /azp run to validate using the pipelines below.
WARNING:
Comments made by azure-pipelines bot maybe inaccurate.
Please see pipeline link to verify that the build is being ran.
For status checks on the main branch, please use TransportPackage-Foundation-PR
(https://microsoft.visualstudio.com/ProjectReunion/_build?definitionId=81063&_a=summary)
and run the build against your PR branch with the default parameters.