-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Add issue triage skill for GitHub issue management #33350
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,157 @@ | ||
| --- | ||
| name: issue-triage | ||
| description: Queries and triages open GitHub issues that need attention. Helps identify issues needing milestones, labels, or investigation. | ||
| metadata: | ||
| author: dotnet-maui | ||
| version: "2.1" | ||
| compatibility: Requires GitHub CLI (gh) authenticated with access to dotnet/maui repository. | ||
| --- | ||
|
|
||
| # Issue Triage Skill | ||
|
|
||
| This skill helps triage open GitHub issues in the dotnet/maui repository by: | ||
| 1. Initializing a session with current milestones and labels | ||
| 2. Loading a batch of issues into memory | ||
| 3. Presenting issues ONE AT A TIME for triage decisions | ||
| 4. Suggesting milestones based on issue characteristics | ||
| 5. Tracking progress through a triage session | ||
|
|
||
| ## When to Use | ||
|
|
||
| - "Find issues to triage" | ||
| - "Let's triage issues" | ||
| - "Grab me 10 issues to triage" | ||
| - "Triage Android issues" | ||
|
|
||
| ## Triage Workflow | ||
|
|
||
| ### Step 1: Initialize Session | ||
|
|
||
| Start by initializing a session to load current milestones and labels: | ||
|
|
||
| ```bash | ||
| pwsh .github/skills/issue-triage/scripts/init-triage-session.ps1 | ||
| ``` | ||
|
|
||
| ### Step 2: Load Issues Into Memory | ||
|
|
||
| Load a batch of issues (e.g., 20) but DO NOT display them all. Store them for one-at-a-time presentation: | ||
|
|
||
| ```bash | ||
| pwsh .github/skills/issue-triage/scripts/query-issues.ps1 -Limit 100 -OutputFormat triage | ||
| ``` | ||
|
|
||
| ### Step 3: Present ONE Issue at a Time | ||
|
|
||
| **IMPORTANT**: When user asks to triage, present only ONE issue at a time in this format: | ||
|
|
||
| ```markdown | ||
| ## Issue #XXXXX | ||
|
|
||
| **[Title]** | ||
|
|
||
| 🔗 [URL] | ||
|
|
||
| | Field | Value | | ||
| |-------|-------| | ||
| | **Author** | username (Syncfusion if applicable) | | ||
| | **Platform** | platform | | ||
| | **Area** | area | | ||
| | **Labels** | labels | | ||
| | **Linked PR** | PR info with milestone if available | | ||
| | **Regression** | Yes/No | | ||
| | **Comments** | count | | ||
|
|
||
| **Comment Summary** (if any): | ||
| - [Author] Comment preview... | ||
|
|
||
| **My Suggestion**: `Milestone` - Reason | ||
|
|
||
| --- | ||
|
|
||
| What would you like to do with this issue? | ||
| ``` | ||
|
|
||
| ### Step 4: Wait for User Decision | ||
|
|
||
| Wait for user to say: | ||
| - A milestone name (e.g., "Backlog", "SR3", ".NET 10 Servicing") | ||
| - "yes" to accept suggestion | ||
| - "skip" or "next" to move on without changes | ||
| - Specific instructions (e.g., "SR4 and add regression label") | ||
|
|
||
| ### Step 5: Apply Changes and Move to Next | ||
|
|
||
| After applying changes, automatically present the NEXT issue. | ||
|
|
||
| ## Script Parameters | ||
|
|
||
| ### query-issues.ps1 | ||
|
|
||
| | Parameter | Values | Default | Description | | ||
| |-----------|--------|---------|-------------| | ||
| | `-Platform` | android, ios, windows, maccatalyst, all | all | Filter by platform | | ||
| | `-Area` | Any area label (e.g., collectionview, shell) | "" | Filter by area | | ||
| | `-Limit` | 1-1000 | 50 | Maximum issues to fetch | | ||
| | `-Skip` | 0+ | 0 | Skip first N issues (for pagination) | | ||
| | `-OutputFormat` | table, json, markdown, triage | table | Output format | | ||
| | `-RequireAreaLabel` | switch | false | Only return issues with area-* labels | | ||
| | `-SkipDetails` | switch | false | Skip fetching PRs/comments (faster) | | ||
|
|
||
| ## Milestone Suggestion Logic | ||
|
|
||
| | Condition | Suggested Milestone | Reason | | ||
| |-----------|---------------------|--------| | ||
| | Linked PR has milestone | PR's milestone | "PR already has milestone" | | ||
| | Has `i/regression` + regressed in .NET 10 | .NET 10.0 SR3 | "Regression in .NET 10" | | ||
| | Has `i/regression` (other) | .NET 10.0 SR4 | "Regression" | | ||
| | Has open linked PR | .NET 10 Servicing | "Has open PR" | | ||
| | Default | Backlog | "No PR, not a regression" | | ||
|
|
||
| ## Applying Triage Decisions | ||
|
|
||
| ```bash | ||
| # Set milestone only | ||
| gh issue edit ISSUE_NUMBER --repo dotnet/maui --milestone "Backlog" | ||
|
|
||
| # Set milestone and add labels | ||
| gh issue edit ISSUE_NUMBER --repo dotnet/maui --milestone ".NET 10.0 SR3" --add-label "i/regression" | ||
|
|
||
| # Set milestone on both issue AND linked PR | ||
| gh issue edit ISSUE_NUMBER --repo dotnet/maui --milestone ".NET 10.0 SR3" | ||
| gh pr edit PR_NUMBER --repo dotnet/maui --milestone ".NET 10.0 SR3" | ||
| ``` | ||
|
|
||
| ## Common Milestone Choices | ||
|
|
||
| | Milestone | Use When | | ||
| |-----------|----------| | ||
| | `.NET 10.0 SR3` | Regressions in .NET 10, critical bugs with PRs ready | | ||
| | `.NET 10.0 SR4` | Important bugs, regressions being investigated | | ||
| | `.NET 10 Servicing` | General fixes with PRs, non-urgent improvements | | ||
| | `Backlog` | No PR, not a regression, nice-to-have fixes | | ||
|
|
||
| ## Label Quick Reference | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it might treat NET 10.0 SR3 and NET 10.0 SR4 as hardcoded values and looks like there's a couple of them used in instructuction |
||
|
|
||
| **Regression Labels:** | ||
| - `i/regression` - Confirmed regression | ||
| - `regressed-in-10.0.0` - Specific version | ||
|
|
||
| **Priority Labels:** | ||
| - `p/0` - Critical | ||
| - `p/1` - High | ||
| - `p/2` - Medium | ||
| - `p/3` - Low | ||
|
|
||
| **iOS 26 / macOS 26:** | ||
| - `version/iOS-26` - iOS 26 specific issue | ||
|
|
||
| ## Session Tracking (Optional) | ||
|
|
||
| ```bash | ||
| # Record triaged issue | ||
| pwsh .github/skills/issue-triage/scripts/record-triage.ps1 -IssueNumber 33272 -Milestone "Backlog" | ||
|
|
||
| # View session stats | ||
| cat CustomAgentLogsTmp/Triage/triage-*.json | jq '.Stats' | ||
| ``` | ||
203 changes: 203 additions & 0 deletions
203
.github/skills/issue-triage/scripts/init-triage-session.ps1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,203 @@ | ||
| #!/usr/bin/env pwsh | ||
| <# | ||
| .SYNOPSIS | ||
| Initializes a triage session by loading current milestones, labels, and creating a session tracker. | ||
|
|
||
| .DESCRIPTION | ||
| This script prepares for an issue triage session by: | ||
| 1. Querying all open milestones from dotnet/maui | ||
| 2. Loading common labels for quick reference | ||
| 3. Creating a session file to track triaged issues | ||
|
|
||
| Run this at the start of a triage session to have current milestone/label data available. | ||
|
|
||
| .PARAMETER SessionName | ||
| Optional name for the triage session (default: timestamp-based) | ||
|
|
||
| .PARAMETER OutputDir | ||
| Directory to store session files (default: CustomAgentLogsTmp/Triage) | ||
|
|
||
| .EXAMPLE | ||
| ./init-triage-session.ps1 | ||
| # Initializes a new triage session with defaults | ||
|
|
||
| .EXAMPLE | ||
| ./init-triage-session.ps1 -SessionName "android-triage" | ||
| # Creates a named session for Android issue triage | ||
| #> | ||
|
|
||
| param( | ||
| [Parameter(Mandatory = $false)] | ||
| [string]$SessionName = "", | ||
|
|
||
| [Parameter(Mandatory = $false)] | ||
| [string]$OutputDir = "CustomAgentLogsTmp/Triage" | ||
| ) | ||
|
|
||
| $ErrorActionPreference = "Stop" | ||
|
|
||
| Write-Host "╔═══════════════════════════════════════════════════════════╗" -ForegroundColor Cyan | ||
| Write-Host "║ Initializing Triage Session ║" -ForegroundColor Cyan | ||
| Write-Host "╚═══════════════════════════════════════════════════════════╝" -ForegroundColor Cyan | ||
|
|
||
| # Create output directory | ||
| if (-not (Test-Path $OutputDir)) { | ||
| New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null | ||
| } | ||
|
|
||
| # Generate session name if not provided | ||
| if ($SessionName -eq "") { | ||
| $SessionName = "triage-$(Get-Date -Format 'yyyy-MM-dd-HHmm')" | ||
| } | ||
|
|
||
| $sessionFile = Join-Path $OutputDir "$SessionName.json" | ||
|
|
||
| Write-Host "" | ||
| Write-Host "Session: $SessionName" -ForegroundColor Green | ||
| Write-Host "Output: $sessionFile" -ForegroundColor DarkGray | ||
|
|
||
| # Query open milestones | ||
| Write-Host "" | ||
| Write-Host "Fetching open milestones..." -ForegroundColor Cyan | ||
|
|
||
| $milestones = @() | ||
| try { | ||
| $msResult = gh api repos/dotnet/maui/milestones --jq '.[] | {number, title, due_on, open_issues}' 2>&1 | ||
| $msLines = $msResult -split "`n" | Where-Object { $_ -match "^\{" } | ||
|
|
||
| foreach ($line in $msLines) { | ||
| $ms = $line | ConvertFrom-Json | ||
| $milestones += [PSCustomObject]@{ | ||
| Number = $ms.number | ||
| Title = $ms.title | ||
| DueOn = $ms.due_on | ||
| OpenIssues = $ms.open_issues | ||
| } | ||
| } | ||
|
|
||
| # Sort by title for easy reference | ||
| $milestones = $milestones | Sort-Object Title | ||
|
|
||
| Write-Host " Found $($milestones.Count) open milestones:" -ForegroundColor Green | ||
|
|
||
| # Group milestones by type | ||
| $srMilestones = $milestones | Where-Object { $_.Title -match "SR\d|Servicing" } | ||
| $backlog = $milestones | Where-Object { $_.Title -eq "Backlog" } | ||
| $otherMs = $milestones | Where-Object { $_.Title -notmatch "SR\d|Servicing" -and $_.Title -ne "Backlog" } | ||
|
|
||
| Write-Host "" | ||
| Write-Host " Servicing Releases:" -ForegroundColor Yellow | ||
| foreach ($ms in $srMilestones) { | ||
| $dueInfo = "" | ||
| if ($ms.DueOn -and $ms.DueOn -is [string] -and $ms.DueOn.Length -ge 10) { | ||
| $dueInfo = " (due: $($ms.DueOn.Substring(0, 10)))" | ||
| } | ||
| Write-Host " - $($ms.Title)$dueInfo [$($ms.OpenIssues) open]" | ||
| } | ||
|
|
||
| if ($backlog) { | ||
| Write-Host "" | ||
| Write-Host " Backlog:" -ForegroundColor Yellow | ||
| Write-Host " - $($backlog.Title) [$($backlog.OpenIssues) open]" | ||
| } | ||
|
|
||
| if ($otherMs.Count -gt 0) { | ||
| Write-Host "" | ||
| Write-Host " Other:" -ForegroundColor Yellow | ||
| foreach ($ms in $otherMs | Select-Object -First 5) { | ||
| Write-Host " - $($ms.Title) [$($ms.OpenIssues) open]" | ||
| } | ||
| if ($otherMs.Count -gt 5) { | ||
| Write-Host " ... and $($otherMs.Count - 5) more" | ||
| } | ||
| } | ||
| } | ||
| catch { | ||
| Write-Host " Failed to fetch milestones: $_" -ForegroundColor Red | ||
| } | ||
|
|
||
| # Query common labels | ||
| Write-Host "" | ||
| Write-Host "Fetching labels..." -ForegroundColor Cyan | ||
|
|
||
| $labels = @{ | ||
| Platforms = @() | ||
| Areas = @() | ||
| Status = @() | ||
| Priority = @() | ||
| Regression = @() | ||
| Other = @() | ||
| } | ||
|
|
||
| try { | ||
| $labelResult = gh api repos/dotnet/maui/labels --paginate --jq '.[].name' 2>&1 | ||
| $allLabels = $labelResult -split "`n" | Where-Object { $_ -ne "" } | ||
|
|
||
| foreach ($label in $allLabels) { | ||
| if ($label -match "^platform/") { | ||
| $labels.Platforms += $label | ||
| } | ||
| elseif ($label -match "^area-") { | ||
| $labels.Areas += $label | ||
| } | ||
| elseif ($label -match "^s/") { | ||
| $labels.Status += $label | ||
| } | ||
| elseif ($label -match "^p/") { | ||
| $labels.Priority += $label | ||
| } | ||
| elseif ($label -match "regression|regressed") { | ||
| $labels.Regression += $label | ||
| } | ||
| } | ||
|
|
||
| Write-Host " Platforms: $($labels.Platforms.Count) labels" | ||
| Write-Host " Areas: $($labels.Areas.Count) labels" | ||
| Write-Host " Status: $($labels.Status.Count) labels" | ||
| Write-Host " Priority: $($labels.Priority.Count) labels" | ||
| Write-Host " Regression: $($labels.Regression.Count) labels" | ||
| } | ||
| catch { | ||
| Write-Host " Failed to fetch labels: $_" -ForegroundColor Red | ||
| } | ||
|
|
||
| # Create session object | ||
| $session = [PSCustomObject]@{ | ||
| Name = $SessionName | ||
| StartedAt = (Get-Date).ToString("o") | ||
| Milestones = $milestones | ||
| Labels = $labels | ||
| TriagedIssues = @() | ||
| Stats = @{ | ||
| Total = 0 | ||
| Backlog = 0 | ||
| Servicing = 0 | ||
| SR = 0 | ||
| Skipped = 0 | ||
| } | ||
| } | ||
|
|
||
| # Save session file | ||
| $session | ConvertTo-Json -Depth 10 | Out-File -FilePath $sessionFile -Encoding UTF8 | ||
|
|
||
| Write-Host "" | ||
| Write-Host "═══════════════════════════════════════════════════════════" -ForegroundColor Cyan | ||
| Write-Host "" | ||
| Write-Host "Session initialized! Quick reference:" -ForegroundColor Green | ||
| Write-Host "" | ||
| Write-Host " Common Milestones:" -ForegroundColor Yellow | ||
| $srMilestones | ForEach-Object { Write-Host " $($_.Title)" } | ||
| Write-Host " Backlog" | ||
| Write-Host "" | ||
| Write-Host " Priority Labels:" -ForegroundColor Yellow | ||
| $labels.Priority | ForEach-Object { Write-Host " $_" } | ||
| Write-Host "" | ||
| Write-Host " Regression Labels:" -ForegroundColor Yellow | ||
| $labels.Regression | Select-Object -First 5 | ForEach-Object { Write-Host " $_" } | ||
| Write-Host "" | ||
| Write-Host " Session file: $sessionFile" -ForegroundColor DarkGray | ||
| Write-Host "" | ||
| Write-Host "Ready to triage! Run query-issues.ps1 to load issues." -ForegroundColor Green | ||
|
|
||
| # Return session for pipeline usage | ||
| return $session |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.