Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 104 additions & 23 deletions .github/skills/issue-triage/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ 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.
version: "2.3"
compatibility: Requires GitHub CLI (gh) installed and authenticated. Run `gh auth login` before using.
---

# Issue Triage Skill
Expand All @@ -16,6 +16,27 @@ This skill helps triage open GitHub issues in the dotnet/maui repository by:
4. Suggesting milestones based on issue characteristics
5. Tracking progress through a triage session

## Prerequisites

**GitHub CLI (gh) must be installed and authenticated:**

```bash
# Install
# Windows:
winget install --id GitHub.cli

# macOS:
brew install gh

# Linux:
# See https://cli.github.com/manual/installation

# Authenticate (required before first use)
gh auth login
```

The scripts will check for `gh` and exit with installation instructions if not found.

## When to Use

- "Find issues to triage"
Expand All @@ -25,6 +46,10 @@ This skill helps triage open GitHub issues in the dotnet/maui repository by:

## Triage Workflow

**🚨 CRITICAL: ALWAYS use the skill scripts. NEVER use ad-hoc GitHub API queries.**

The scripts have proper filters, exclusions, and milestone logic built-in. Don't bypass them.

### Step 1: Initialize Session

Start by initializing a session to load current milestones and labels:
Expand All @@ -33,14 +58,29 @@ Start by initializing a session to load current milestones and labels:
pwsh .github/skills/issue-triage/scripts/init-triage-session.ps1
```

**What this does:**
- Fetches current milestones (SR4, SR5, etc.) from GitHub API
- Displays servicing milestones for reference during triage
- Creates session file to track progress

### 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:
**MANDATORY: Use query-issues.ps1 - it has the right filters!**

```bash
pwsh .github/skills/issue-triage/scripts/query-issues.ps1 -Limit 100 -OutputFormat triage
pwsh .github/skills/issue-triage/scripts/query-issues.ps1 -Limit 50 -OutputFormat triage
```

**What this does:**
- Queries GitHub with exclusion filters: `-label:s/needs-info -label:s/needs-repro -label:area-blazor -label:s/try-latest-version -label:s/move-to-vs-feedback`
- Returns issues without milestones
- Stores results for one-at-a-time presentation

**DON'T:**
- ❌ Use `github-mcp-server-list_issues` directly
- ❌ Use `github-mcp-server-search_issues` without the same filters
- ❌ Try to replicate the logic yourself - use the script!

### Step 3: Present ONE Issue at a Time

**IMPORTANT**: When user asks to triage, present only ONE issue at a time in this format:
Expand All @@ -65,7 +105,7 @@ pwsh .github/skills/issue-triage/scripts/query-issues.ps1 -Limit 100 -OutputForm
**Comment Summary** (if any):
- [Author] Comment preview...

**My Suggestion**: `Milestone` - Reason
**My Suggestion**: `Milestone` - Reason (based on init session output)

---

Expand All @@ -75,14 +115,33 @@ 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", "current SR", "Servicing")
- A milestone name (e.g., "Backlog", ".NET 10 SR5", ".NET 10 Servicing")
- "yes" to accept suggestion
- "skip" or "next" to move on without changes
- Specific instructions (e.g., "next SR and add regression label")

### Step 5: Apply Changes and Move to Next
### Step 5: Move to Next Issue

After user decision, automatically present the NEXT issue.

### Step 6: When Batch is Empty

After applying changes, automatically present the NEXT issue.
**🚨 CRITICAL: When you run out of issues, AUTOMATICALLY reload more issues.**

```bash
# Run query again to load next batch
pwsh .github/skills/issue-triage/scripts/query-issues.ps1 -Limit 50 -Skip <current_count> -OutputFormat triage
```

**DO NOT:**
- ❌ Stop and ask "Load more?"
- ❌ Say "No more issues found"
- ❌ Use different GitHub queries

**DO:**
- ✅ Automatically run `query-issues.ps1` again with `-Skip` parameter
- ✅ Continue presenting issues one at a time
- ✅ Only stop when query returns zero issues

## Script Parameters

Expand All @@ -100,16 +159,39 @@ After applying changes, automatically present the NEXT issue.

## Milestone Suggestion Logic

The script dynamically queries current milestones from dotnet/maui and suggests them based on issue characteristics:
**🚨 CRITICAL: ALWAYS use actual milestone names from init-triage-session.ps1 output. NEVER guess or assume milestone names.**

The skill dynamically queries current milestones from dotnet/maui at session initialization. Milestone names change frequently (e.g., SR4, SR5, SR6), so **always reference the session output** when suggesting milestones.

### Suggestion Guidelines

| Condition | Suggested Milestone | Reason |
|-----------|---------------------|--------|
| Linked PR has milestone | PR's milestone | "PR already has milestone" |
| Has `i/regression` label | Current SR milestone (soonest due) | "Regression - current SR milestone" |
| Has open linked PR | Servicing milestone (or next SR) | "Has open PR" |
| Has `i/regression` label | Highest numbered SR milestone | "Regression - needs servicing" |
| Has open linked PR | Current servicing milestone | "Has open PR" |
| Default | Backlog | "No PR, not a regression" |

**Note**: SR milestones are sorted by due date, so the soonest SR is suggested for regressions. Milestone names change monthly, so they are queried dynamically rather than hardcoded.
**Example Session Output:**
```
Servicing Releases:
- .NET 9 Servicing [246 open]
- .NET 10 Servicing [213 open]
- .NET 10 SR5 [55 open] ← Use this for .NET 10 regressions
- .NET 10.0 SR4 [103 open]

Other:
- .NET 11 Planning [167 open]
- .NET 11.0-preview1 [8 open]

Backlog:
- Backlog [3037 open]
```

**How to suggest milestones:**
- ✅ "Assign to `.NET 10 SR5`" (from session output)
- ❌ "Assign to `.NET 10 SR2`" (guessing, might not exist)
- ❌ "Assign to current SR" (ambiguous, multiple active)

## Applying Triage Decisions

Expand All @@ -125,17 +207,6 @@ gh issue edit ISSUE_NUMBER --repo dotnet/maui --milestone "MILESTONE_NAME"
gh pr edit PR_NUMBER --repo dotnet/maui --milestone "MILESTONE_NAME"
```

## Common Milestone Types

| Milestone Type | Use When |
|----------------|----------|
| Current SR (e.g., SR3) | Regressions, critical bugs with PRs ready |
| Next SR (e.g., SR4) | Important bugs, regressions being investigated |
| Servicing | General fixes with PRs, non-urgent improvements |
| Backlog | No PR, not a regression, nice-to-have fixes |

**Note**: Use `init-triage-session.ps1` to see current milestone names.

## Label Quick Reference

**Regression Labels:**
Expand All @@ -151,6 +222,16 @@ gh pr edit PR_NUMBER --repo dotnet/maui --milestone "MILESTONE_NAME"
**iOS 26 / macOS 26:**
- `version/iOS-26` - iOS 26 specific issue

## Common Mistakes to Avoid

| Mistake | Why It's Wrong | Correct Approach |
|---------|----------------|------------------|
| ❌ Using `github-mcp-server-list_issues` directly | Missing exclusion filters (needs-info, needs-repro, etc.) | ✅ Use `query-issues.ps1` script |
| ❌ Stopping when batch is empty | There are likely more issues available | ✅ Automatically run `query-issues.ps1 -Skip N` |
| ❌ Suggesting milestone names like "SR2" | Milestone doesn't exist, based on assumptions | ✅ Use actual milestone names from `init-triage-session.ps1` output |
| ❌ Asking "Load more?" when out of issues | Creates unnecessary interruption | ✅ Just load more automatically |
| ❌ Using ad-hoc API queries with custom filters | Likely to miss or include wrong issues | ✅ Trust the skill's scripts - they have the right logic |

## Session Tracking (Optional)

```bash
Expand Down
39 changes: 35 additions & 4 deletions .github/skills/issue-triage/scripts/init-triage-session.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,39 @@ Write-Host "╔═════════════════════
Write-Host "║ Initializing Triage Session ║" -ForegroundColor Cyan
Write-Host "╚═══════════════════════════════════════════════════════════╝" -ForegroundColor Cyan

# Check for GitHub CLI prerequisite
Write-Host ""
Write-Host "Checking prerequisites..." -ForegroundColor Cyan
try {
$ghPath = (Get-Command gh -ErrorAction Stop).Source
Write-Host " ✅ GitHub CLI found: $ghPath" -ForegroundColor Green
} catch {
Write-Host ""
Write-Host " ❌ GitHub CLI (gh) is not installed" -ForegroundColor Red
Write-Host ""
Write-Host " The issue-triage skill requires GitHub CLI for querying issues." -ForegroundColor Yellow
Write-Host ""
Write-Host " Installation:" -ForegroundColor Cyan
Write-Host " Windows: winget install --id GitHub.cli" -ForegroundColor White
Write-Host " macOS: brew install gh" -ForegroundColor White
Write-Host " Linux: See https://cli.github.com/manual/installation" -ForegroundColor White
Write-Host ""
Write-Host " After installation, authenticate with: gh auth login" -ForegroundColor Cyan
Write-Host ""
exit 1
}

Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prerequisite check validates that gh CLI is installed, but it only reports success without verifying authentication status. After the check passes, the script still uses gh api at line 153 to fetch labels, which will fail if the user hasn't authenticated with gh auth login. Consider adding an authentication check (e.g., gh auth status) or catching the authentication error at line 153 with a more specific error message directing users to run gh auth login.

Suggested change
# Verify GitHub CLI authentication
try {
# gh auth status will throw if not authenticated or if there is a problem with the auth setup
gh auth status 1>$null 2>$null
Write-Host " ✅ GitHub CLI authentication verified" -ForegroundColor Green
} catch {
Write-Host ""
Write-Host " ❌ GitHub CLI (gh) is not authenticated" -ForegroundColor Red
Write-Host ""
Write-Host " The issue-triage skill requires an authenticated GitHub CLI session" -ForegroundColor Yellow
Write-Host " to query milestones, labels, and issues via the GitHub API." -ForegroundColor Yellow
Write-Host ""
Write-Host " Please authenticate with:" -ForegroundColor Cyan
Write-Host " gh auth login" -ForegroundColor White
Write-Host ""
exit 1
}

Copilot uses AI. Check for mistakes.
# Verify GitHub CLI authentication
$authStatus = gh auth status 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Host ""
Write-Host " ❌ GitHub CLI (gh) is not authenticated" -ForegroundColor Red
Write-Host " Run: gh auth login" -ForegroundColor Cyan
Write-Host ""
exit 1
}
Write-Host " ✅ GitHub CLI authenticated" -ForegroundColor Green

# Create output directory
if (-not (Test-Path $OutputDir)) {
New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null
Expand All @@ -62,11 +95,9 @@ 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 "^\{" }
$msData = Invoke-RestMethod -Uri "https://api.github.com/repos/dotnet/maui/milestones?state=open&per_page=100"

foreach ($line in $msLines) {
$ms = $line | ConvertFrom-Json
foreach ($ms in $msData) {
$milestones += [PSCustomObject]@{
Number = $ms.number
Title = $ms.title
Expand Down
30 changes: 30 additions & 0 deletions .github/skills/issue-triage/scripts/query-issues.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,36 @@ param(

$ErrorActionPreference = "Stop"

# Check for GitHub CLI prerequisite
try {
$null = Get-Command gh -ErrorAction Stop
} catch {
Write-Host ""
Write-Host "❌ GitHub CLI (gh) is not installed" -ForegroundColor Red
Write-Host ""
Write-Host "The issue-triage skill requires GitHub CLI for querying issues." -ForegroundColor Yellow
Write-Host ""
Write-Host "Installation:" -ForegroundColor Cyan
Write-Host " Windows: winget install --id GitHub.cli" -ForegroundColor White
Write-Host " macOS: brew install gh" -ForegroundColor White
Write-Host " Linux: See https://cli.github.com/manual/installation" -ForegroundColor White
Write-Host ""
Write-Host "After installation, authenticate with: gh auth login" -ForegroundColor Cyan
Write-Host ""
exit 1
}

Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to init-triage-session.ps1, this prerequisite check validates that gh CLI is installed but doesn't verify authentication status. The script uses gh commands later (lines 150, 229, 348) which will fail if the user hasn't authenticated. Consider adding an authentication check (e.g., gh auth status) or providing more specific error messages when gh commands fail due to missing authentication.

Suggested change
# Verify GitHub CLI authentication status
& gh auth status 1>$null 2>$null
if ($LASTEXITCODE -ne 0) {
Write-Host ""
Write-Host "❌ GitHub CLI (gh) is not authenticated" -ForegroundColor Red
Write-Host ""
Write-Host "The issue-triage skill requires an authenticated GitHub CLI session to query issues." -ForegroundColor Yellow
Write-Host ""
Write-Host "Please authenticate by running:" -ForegroundColor Cyan
Write-Host " gh auth login" -ForegroundColor White
Write-Host ""
exit 1
}

Copilot uses AI. Check for mistakes.
# Verify GitHub CLI authentication
$authStatus = gh auth status 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Host ""
Write-Host "❌ GitHub CLI (gh) is not authenticated" -ForegroundColor Red
Write-Host "Run: gh auth login" -ForegroundColor Cyan
Write-Host ""
exit 1
}
Write-Host "✅ GitHub CLI authenticated" -ForegroundColor Green

Write-Host "Querying GitHub issues..." -ForegroundColor Cyan

# Labels to exclude from triage results
Expand Down