Initial commit
This commit is contained in:
599
commands/backlog.md
Normal file
599
commands/backlog.md
Normal file
@@ -0,0 +1,599 @@
|
||||
---
|
||||
description: Find suitable JIRA tickets from the backlog to work on based on priority and activity
|
||||
argument-hint: [project-key] [--assignee username] [--days-inactive N]
|
||||
---
|
||||
|
||||
## Name
|
||||
jira:backlog
|
||||
|
||||
## Synopsis
|
||||
```
|
||||
/jira:backlog [project-key] [--assignee username] [--days-inactive N]
|
||||
```
|
||||
|
||||
## Description
|
||||
|
||||
The `jira:backlog` command helps identify suitable tickets from the JIRA backlog to work on by **intelligently analyzing** unassigned tickets and bot-assigned tickets. Unlike simple filtering, this command reads ticket descriptions, comments, and activity patterns to recommend the best candidates for work.
|
||||
|
||||
**Key Feature:** The command selects **2 tickets from each priority level** (Critical, High, Normal, Low) that are **actually available to pick up** (unassigned or assigned to bots only), giving you a balanced view across all priorities so you can choose based on your expertise and preference.
|
||||
|
||||
**Important:** This command only recommends tickets that are **unassigned** or **assigned to bots** (like "OCP DocsBot"). Tickets assigned to real people are excluded, even if they have no recent activity, because they may already be claimed by someone.
|
||||
|
||||
This command is particularly useful for:
|
||||
- Finding tickets to work on when you have available capacity
|
||||
- Identifying unassigned or abandoned tickets that need attention
|
||||
- Getting a mix of priorities to choose from (not just critical)
|
||||
- Understanding ticket context before starting work
|
||||
|
||||
How it works:
|
||||
- Searches for unassigned tickets or tickets with no activity for 28+ days (configurable)
|
||||
- **Filters for availability** - keeps only unassigned or bot-assigned tickets
|
||||
- **Analyzes ticket content** - reads descriptions, comments, and activity patterns
|
||||
- **Evaluates suitability** - identifies tickets that are ready vs. need verification vs. may be abandoned
|
||||
- **Selects intelligently** - chooses the most suitable 2 tickets from each priority level
|
||||
- Provides comprehensive summaries with recommendations for each ticket
|
||||
|
||||
## Prerequisites
|
||||
|
||||
This command requires JIRA credentials to be configured via the JIRA MCP server setup, even though it uses direct API calls instead of MCP commands.
|
||||
|
||||
### 1. Install the Jira Plugin
|
||||
|
||||
If you haven't already installed the Jira plugin, see the [Jira Plugin README](../README.md#installation) for installation instructions.
|
||||
|
||||
### 2. Configure JIRA Credentials via MCP Configuration File
|
||||
|
||||
**⚠️ Important:** While this command does NOT use MCP commands to query JIRA, it DOES read credentials from the MCP server configuration file. You must configure the MCP server settings even if you're only using this command.
|
||||
|
||||
**Why not use MCP commands?** The MCP approach has performance issues when fetching large datasets:
|
||||
- Each MCP response must be processed by Claude, consuming tokens
|
||||
- Large result sets (even with pagination) cause 413 errors from Claude due to tool result size limits
|
||||
- Processing hundreds of tickets through MCP commands creates excessive context usage
|
||||
- Direct API calls allow us to stream data to disk without intermediate processing
|
||||
|
||||
**Solution:** This command uses `curl` to fetch data directly from JIRA and save to disk, then processes it with Python. It reads JIRA credentials from `~/.config/claude-code/mcp.json` - the same file used by the MCP server.
|
||||
|
||||
**Required Configuration File Format:**
|
||||
|
||||
Create or edit `~/.config/claude-code/mcp.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"atlassian": {
|
||||
"command": "npx",
|
||||
"args": ["mcp-atlassian"],
|
||||
"env": {
|
||||
"JIRA_URL": "https://issues.redhat.com",
|
||||
"JIRA_USERNAME": "your-email@redhat.com",
|
||||
"JIRA_API_TOKEN": "your-atlassian-api-token-here",
|
||||
"JIRA_PERSONAL_TOKEN": "your-redhat-jira-personal-token-here"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Field Descriptions:**
|
||||
- `JIRA_URL`: Your JIRA instance URL (e.g., `https://issues.redhat.com` for Red Hat JIRA)
|
||||
- `JIRA_USERNAME`: Your JIRA username/email address
|
||||
- `JIRA_API_TOKEN`: Atlassian API token from [Atlassian API Token Management Page](https://id.atlassian.com/manage-profile/security/api-tokens)
|
||||
- `JIRA_PERSONAL_TOKEN`: Red Hat JIRA Personal Access Token from [Red Hat Jira PAT Management Page](https://issues.redhat.com/secure/ViewProfile.jspa?selectedTab=com.atlassian.pats.pats-plugin:jira-user-personal-access-tokens)
|
||||
|
||||
**Note:** The command will use `JIRA_PERSONAL_TOKEN` if available (preferred for Red Hat JIRA), otherwise falls back to `JIRA_API_TOKEN`.
|
||||
|
||||
### 3. Start Local MCP Server with Podman
|
||||
|
||||
**⚠️ Recommended Setup:** Use the podman containerized approach. We tested npx methods on October 31, 2025, and encountered 404 errors and missing dependencies. The containerized setup works reliably.
|
||||
|
||||
**Steps:**
|
||||
|
||||
1. **First, ensure your `~/.config/claude-code/mcp.json` is created with credentials** (see example above)
|
||||
|
||||
2. **Start the MCP server container using credentials from mcp.json:**
|
||||
|
||||
```bash
|
||||
# Extract credentials from your mcp.json file
|
||||
JIRA_URL=$(jq -r '.mcpServers.atlassian.env.JIRA_URL' ~/.config/claude-code/mcp.json)
|
||||
JIRA_USERNAME=$(jq -r '.mcpServers.atlassian.env.JIRA_USERNAME' ~/.config/claude-code/mcp.json)
|
||||
JIRA_API_TOKEN=$(jq -r '.mcpServers.atlassian.env.JIRA_API_TOKEN' ~/.config/claude-code/mcp.json)
|
||||
JIRA_PERSONAL_TOKEN=$(jq -r '.mcpServers.atlassian.env.JIRA_PERSONAL_TOKEN' ~/.config/claude-code/mcp.json)
|
||||
|
||||
# Start the container
|
||||
podman run -d --name mcp-atlassian -p 8080:8080 \
|
||||
-e "JIRA_URL=${JIRA_URL}" \
|
||||
-e "JIRA_USERNAME=${JIRA_USERNAME}" \
|
||||
-e "JIRA_API_TOKEN=${JIRA_API_TOKEN}" \
|
||||
-e "JIRA_PERSONAL_TOKEN=${JIRA_PERSONAL_TOKEN}" \
|
||||
-e "JIRA_SSL_VERIFY=true" \
|
||||
ghcr.io/sooperset/mcp-atlassian:latest --transport sse --port 8080 -vv
|
||||
```
|
||||
|
||||
3. **Verify the container is running:**
|
||||
```bash
|
||||
podman ps | grep mcp-atlassian
|
||||
```
|
||||
|
||||
4. **Restart Claude Code** to ensure it reads the mcp.json configuration
|
||||
|
||||
**Managing the Container:**
|
||||
```bash
|
||||
# Check if container is running
|
||||
podman ps | grep mcp-atlassian
|
||||
|
||||
# View logs
|
||||
podman logs mcp-atlassian
|
||||
|
||||
# Stop the container
|
||||
podman stop mcp-atlassian
|
||||
|
||||
# Start the container again
|
||||
podman start mcp-atlassian
|
||||
|
||||
# Remove the container (you'll need to run 'podman run' again)
|
||||
podman rm mcp-atlassian
|
||||
```
|
||||
|
||||
### 4. Verify MCP Server Configuration
|
||||
|
||||
To verify your MCP server is properly configured and can connect to JIRA, you can test it with a simple JIRA query in Claude Code:
|
||||
|
||||
```bash
|
||||
Ask Claude Code to run: "Use the mcp__atlassian__jira_get_issue tool to fetch OCPBUGS-1"
|
||||
```
|
||||
|
||||
If the MCP server is properly configured, you should see issue details returned. If you see an error:
|
||||
- **"Tool not found"**: The MCP server is not properly registered with Claude Code. Re-run the `claude mcp add` command.
|
||||
- **"Authentication failed"** or **401/403 errors**: Check your `JIRA_PERSONAL_TOKEN` and `JIRA_USERNAME` are correct.
|
||||
- **"Connection refused"**: If using a local MCP server, ensure the podman container is running (`podman ps`).
|
||||
- **"Could not find issue"**: Your authentication works! This just means the specific issue doesn't exist or you don't have access.
|
||||
|
||||
See the [full JIRA Plugin README](../README.md) for complete setup instructions and troubleshooting.
|
||||
|
||||
## Implementation
|
||||
|
||||
The command executes the following workflow:
|
||||
|
||||
1. **Extract Credentials from MCP Configuration File**
|
||||
- Read credentials from `~/.config/claude-code/mcp.json`
|
||||
- Extract from the `atlassian` MCP server configuration:
|
||||
```bash
|
||||
MCP_CONFIG="$HOME/.config/claude-code/mcp.json"
|
||||
|
||||
JIRA_URL=$(jq -r '.mcpServers.atlassian.env.JIRA_URL' "$MCP_CONFIG")
|
||||
JIRA_EMAIL=$(jq -r '.mcpServers.atlassian.env.JIRA_USERNAME // .mcpServers.atlassian.env.JIRA_EMAIL' "$MCP_CONFIG")
|
||||
JIRA_PERSONAL_TOKEN=$(jq -r '.mcpServers.atlassian.env.JIRA_PERSONAL_TOKEN' "$MCP_CONFIG")
|
||||
JIRA_API_TOKEN=$(jq -r '.mcpServers.atlassian.env.JIRA_API_TOKEN' "$MCP_CONFIG")
|
||||
|
||||
# Use JIRA_PERSONAL_TOKEN if available, otherwise fall back to JIRA_API_TOKEN
|
||||
AUTH_TOKEN="${JIRA_PERSONAL_TOKEN:-$JIRA_API_TOKEN}"
|
||||
```
|
||||
- If any required credentials are missing or the file doesn't exist, display error:
|
||||
```bash
|
||||
Error: JIRA credentials not configured.
|
||||
|
||||
This command requires JIRA credentials from the MCP server configuration file.
|
||||
Please create or edit ~/.config/claude-code/mcp.json with your JIRA credentials.
|
||||
|
||||
See Prerequisites section for the required mcp.json format and setup instructions.
|
||||
```
|
||||
|
||||
2. **Parse Arguments and Set Defaults**
|
||||
- Parse project key from $1 (required): "OCPBUGS", "JIRA", "HYPE", etc.
|
||||
- Parse optional --assignee filter (defaults to "Unassigned")
|
||||
- Parse optional --days-inactive (defaults to 28 days)
|
||||
- Validate project key format (uppercase, may contain hyphens)
|
||||
- Create working directory: `mkdir -p .work/jira-backlog/{project-key}/`
|
||||
|
||||
3. **Construct JQL Query**
|
||||
- Build base JQL query:
|
||||
```jql
|
||||
project = {project-key}
|
||||
AND status NOT IN (Closed, Resolved, Done, Verified, Release Pending, ON_QA)
|
||||
AND (
|
||||
assignee IS EMPTY
|
||||
OR updated <= -{days-inactive}d
|
||||
)
|
||||
ORDER BY priority DESC, updated ASC
|
||||
```
|
||||
- If --assignee provided, replace assignee filter with: `AND assignee = {username} AND updated <= -{days-inactive}d`
|
||||
- URL-encode the JQL query for use in API requests
|
||||
|
||||
4. **Fetch All Backlog Tickets Using curl with Pagination**
|
||||
|
||||
**Fetch Strategy:**
|
||||
- Fetch 1000 tickets per request (JIRA's maximum `maxResults` value)
|
||||
- Use pagination (`startAt` parameter) to fetch all tickets
|
||||
- Save each batch directly to disk to avoid memory issues
|
||||
- Continue until all tickets are fetched
|
||||
|
||||
**Authentication:**
|
||||
- For Red Hat JIRA (Data Center): Use Bearer token with `JIRA_PERSONAL_TOKEN` (recommended)
|
||||
- For JIRA Cloud: Can use Basic Auth with `email:api_token`, but Bearer token also works
|
||||
|
||||
**Important API Details:**
|
||||
- Use `/rest/api/2/search` endpoint (API v2 works reliably with Red Hat JIRA)
|
||||
- Use `Authorization: Bearer ${JIRA_PERSONAL_TOKEN}` header for authentication
|
||||
- Check HTTP response code to detect authentication failures
|
||||
|
||||
**Batch Processing Loop:**
|
||||
```bash
|
||||
START_AT=0
|
||||
BATCH_NUM=0
|
||||
TOTAL_FETCHED=0
|
||||
|
||||
while true; do
|
||||
# Construct API URL with pagination
|
||||
API_URL="${JIRA_URL}/rest/api/2/search?\
|
||||
jql=${ENCODED_JQL}&\
|
||||
startAt=${START_AT}&\
|
||||
maxResults=1000&\
|
||||
fields=summary,status,priority,assignee,reporter,created,updated,description,labels,components,watches,comment"
|
||||
|
||||
# Fetch batch using curl with Bearer token authentication
|
||||
HTTP_CODE=$(curl -s -w "%{http_code}" \
|
||||
-o "batch-${BATCH_NUM}.json" \
|
||||
-H "Authorization: Bearer ${AUTH_TOKEN}" \
|
||||
-H "Accept: application/json" \
|
||||
"${API_URL}")
|
||||
|
||||
# Check HTTP response code
|
||||
if [ "$HTTP_CODE" -ne 200 ]; then
|
||||
echo "Error: HTTP $HTTP_CODE received"
|
||||
cat "batch-${BATCH_NUM}.json"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Parse response to check if more results exist
|
||||
BATCH_SIZE=$(jq '.issues | length' "batch-${BATCH_NUM}.json")
|
||||
TOTAL=$(jq '.total' "batch-${BATCH_NUM}.json")
|
||||
|
||||
TOTAL_FETCHED=$((TOTAL_FETCHED + BATCH_SIZE))
|
||||
|
||||
echo "✓ Fetched ${BATCH_SIZE} tickets (${TOTAL_FETCHED}/${TOTAL} total)"
|
||||
|
||||
# Check if done
|
||||
if [ ${TOTAL_FETCHED} -ge ${TOTAL} ] || [ ${BATCH_SIZE} -eq 0 ]; then
|
||||
break
|
||||
fi
|
||||
|
||||
# Move to next batch
|
||||
START_AT=$((START_AT + 1000))
|
||||
BATCH_NUM=$((BATCH_NUM + 1))
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "✓ Fetching complete: ${TOTAL_FETCHED} tickets downloaded in $((BATCH_NUM + 1)) batch(es)"
|
||||
```
|
||||
|
||||
**Why curl instead of MCP:**
|
||||
- Direct file streaming avoids Claude's tool result size limits (413 errors)
|
||||
- Can handle thousands of tickets without token consumption
|
||||
- Faster - no intermediate serialization through MCP protocol
|
||||
- More reliable for large datasets
|
||||
|
||||
5. **Process Batches with Python to Filter and Group by Priority**
|
||||
|
||||
Create a Python script (`.work/jira-backlog/{project-key}/process_batches.py`) that:
|
||||
|
||||
**Inputs:**
|
||||
- All batch files: `.work/jira-backlog/{project-key}/batch-*.json`
|
||||
|
||||
**Processing Logic:**
|
||||
```python
|
||||
import json
|
||||
import glob
|
||||
from collections import defaultdict
|
||||
|
||||
# Load all batches
|
||||
all_tickets = []
|
||||
for batch_file in sorted(glob.glob('.work/jira-backlog/{project-key}/batch-*.json')):
|
||||
with open(batch_file) as f:
|
||||
data = json.load(f)
|
||||
all_tickets.extend(data['issues'])
|
||||
|
||||
# Filter for available tickets
|
||||
available_tickets = []
|
||||
for ticket in all_tickets:
|
||||
assignee = ticket['fields'].get('assignee')
|
||||
|
||||
# Include if unassigned
|
||||
if assignee is None:
|
||||
available_tickets.append(ticket)
|
||||
continue
|
||||
|
||||
# Include if assigned to a bot
|
||||
assignee_name = assignee.get('displayName', '').lower()
|
||||
if 'bot' in assignee_name:
|
||||
available_tickets.append(ticket)
|
||||
continue
|
||||
|
||||
# Otherwise exclude (assigned to real person)
|
||||
|
||||
# Group by priority
|
||||
priority_buckets = defaultdict(list)
|
||||
for ticket in available_tickets:
|
||||
priority_name = ticket['fields']['priority']['name']
|
||||
|
||||
# Normalize priority names
|
||||
if priority_name in ['Critical', 'Blocker']:
|
||||
priority_buckets['Critical'].append(ticket)
|
||||
elif priority_name in ['High', 'Major']:
|
||||
priority_buckets['High'].append(ticket)
|
||||
elif priority_name in ['Normal', 'Medium']:
|
||||
priority_buckets['Normal'].append(ticket)
|
||||
elif priority_name in ['Low', 'Minor', 'Trivial']:
|
||||
priority_buckets['Low'].append(ticket)
|
||||
|
||||
# Save filtered results
|
||||
with open('.work/jira-backlog/{project-key}/filtered.json', 'w') as f:
|
||||
json.dump(priority_buckets, f, indent=2)
|
||||
|
||||
# Save statistics
|
||||
stats = {p: len(tickets) for p, tickets in priority_buckets.items()}
|
||||
with open('.work/jira-backlog/{project-key}/stats.json', 'w') as f:
|
||||
json.dump(stats, f, indent=2)
|
||||
|
||||
print(f"Filtered {len(available_tickets)} available tickets from {len(all_tickets)} total")
|
||||
print(f"Priority distribution: {stats}")
|
||||
```
|
||||
|
||||
**Outputs:**
|
||||
- `.work/jira-backlog/{project-key}/filtered.json` - All filtered tickets grouped by priority
|
||||
- `.work/jira-backlog/{project-key}/stats.json` - Priority distribution statistics
|
||||
|
||||
**Run the script:**
|
||||
```bash
|
||||
python .work/jira-backlog/${PROJECT_KEY}/process_batches.py
|
||||
```
|
||||
|
||||
6. **Intelligently Analyze and Select Best Tickets from Each Priority**
|
||||
|
||||
**CRITICAL:** This is NOT a mechanical selection process. You must read and analyze ticket content to make intelligent decisions.
|
||||
|
||||
**Load Filtered Data:**
|
||||
- Read filtered tickets from `.work/jira-backlog/{project-key}/filtered.json`
|
||||
- Data is already grouped by priority level (Critical, High, Normal, Low)
|
||||
|
||||
For each priority level (Critical, High, Normal, Low):
|
||||
|
||||
**Step 6a: Extract Tickets for Human-Readable Analysis**
|
||||
- Take the first 10 tickets from each priority bucket (or all available if fewer than 10)
|
||||
- For each ticket, format in a readable way showing:
|
||||
- Key, summary, status, assignee, reporter
|
||||
- Days since last update, number of comments, watchers
|
||||
- Description preview (first 300-400 characters)
|
||||
- Last 1-3 comments (author, date, first 200 characters of body)
|
||||
- Components and labels
|
||||
- **Output this formatted data** so you can read and analyze it
|
||||
- DO NOT analyze inside Python/bash - extract the data in readable format first
|
||||
|
||||
**Step 6b: Analyze Ticket Suitability**
|
||||
Read the formatted data and evaluate each ticket for:
|
||||
|
||||
**Age Classifications (consider when prioritizing):**
|
||||
- **Very Fresh (< 30 days):** Highest priority - likely still relevant and active
|
||||
- **Recent (30-60 days):** Good candidates - still relatively fresh
|
||||
- **Getting Stale (60-90 days):** Verify still relevant before recommending
|
||||
- **Old (90-120 days):** Lower priority - may need verification/grooming
|
||||
- **Very Old (120+ days):** Lowest priority - likely needs re-evaluation before work
|
||||
|
||||
**Disqualifying Factors (skip these tickets):**
|
||||
- **Assigned to real people (non-bots)** - these tickets should have been filtered out in Step 3, but double-check
|
||||
- Status is "Verified", "Release Pending", "ON_QA", "Done" (already complete)
|
||||
- Zero comments AND very old (120+ days) - likely abandoned
|
||||
- Comments indicate "duplicate", "won't fix", "closed as"
|
||||
- Comments show work is blocked or waiting on external dependencies
|
||||
|
||||
**Positive Indicators (prioritize these):**
|
||||
- **Unassigned or bot-assigned** - available for anyone to pick up
|
||||
- **Recency matters:** Fresher tickets (< 60 days) should be weighted higher
|
||||
- Active discussion in comments showing real investigation (but not claimed by someone)
|
||||
- Clear, reproducible issue with steps to reproduce
|
||||
- Recent comments (< 30 days) saying "needs investigation", "looking for owner", "ready for work"
|
||||
- Has must-gather, logs, or reproduction environment attached/linked
|
||||
- Well-defined scope and acceptance criteria
|
||||
- Clear description with some comments showing interest
|
||||
|
||||
**Step 6c: Select Best 2 from Each Priority**
|
||||
- Based on your analysis, select the 2 MOST SUITABLE tickets from each priority level
|
||||
- **Selection Criteria (in order of importance):**
|
||||
1. **Recency:** Fresher tickets (< 60 days) strongly preferred to ensure relevance
|
||||
2. **Clarity:** Clear reproduction steps, well-defined scope, available resources (must-gather, logs)
|
||||
3. **Impact:** User-facing issues, customer cases, or significant system problems
|
||||
4. **Activity:** Active discussion/comments showing the issue is real and being tracked
|
||||
- If a priority level has fewer than 2 suitable tickets, include what's available
|
||||
- Document WHY each ticket was selected (your reasoning, including age classification)
|
||||
- Flag tickets that need verification before work can start
|
||||
- In your recommendation, mention the ticket age using the classifications above
|
||||
|
||||
7. **Format Output Report**
|
||||
Generate a formatted report organized by priority:
|
||||
|
||||
```bash
|
||||
# Backlog Tickets for {project-key}
|
||||
|
||||
## Search Criteria
|
||||
- Project: {project-key}
|
||||
- Assignee: {assignee or "Unassigned"}
|
||||
- Days Inactive: {days-inactive}+
|
||||
- Total Tickets Found: {count}
|
||||
|
||||
---
|
||||
|
||||
## Critical Priority ({count} tickets)
|
||||
|
||||
### 1. {ISSUE-KEY}: {Summary}
|
||||
**Status:** {status} | **Updated:** {days} days ago | **Reporter:** {name}
|
||||
**Components:** {components} | **Labels:** {labels}
|
||||
**Watchers:** {count} | **Comments:** {count}
|
||||
|
||||
**Context:**
|
||||
{2-3 sentence summary of the ticket}
|
||||
|
||||
**Recent Activity:**
|
||||
- {Most recent comment summary or "No recent comments"}
|
||||
- {Status change or "No status changes"}
|
||||
- {Blocker/Question if identified}
|
||||
|
||||
**Recommendation:** {Why this ticket is suitable to work on or what's needed before starting}
|
||||
|
||||
---
|
||||
|
||||
### 2. {ISSUE-KEY}: {Summary}
|
||||
...
|
||||
|
||||
---
|
||||
|
||||
## High Priority ({count} tickets)
|
||||
...
|
||||
|
||||
## Normal Priority ({count} tickets)
|
||||
...
|
||||
|
||||
## Low Priority ({count} tickets)
|
||||
...
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
- Critical: {count} tickets available
|
||||
- High: {count} tickets available
|
||||
- Normal: {count} tickets available
|
||||
- Low: {count} tickets available
|
||||
|
||||
**Suggested Next Steps:**
|
||||
1. Review the tickets above and select one that matches your expertise
|
||||
2. Check if the ticket has clear acceptance criteria - if not, consider grooming it first using `/jira:grooming {issue-key}`
|
||||
3. Use `/jira:solve {issue-key} {remote}` to start working on the ticket
|
||||
```
|
||||
|
||||
8. **Display Report to User**
|
||||
- Show the formatted report
|
||||
- Provide guidance on next steps
|
||||
- Suggest using `/jira:grooming` for tickets lacking clarity
|
||||
- Suggest using `/jira:solve` to start working on selected ticket
|
||||
|
||||
9. **Save Report (Optional)**
|
||||
- Offer to save report to `.work/jira-backlog/{project-key}-{timestamp}.md`
|
||||
- Useful for tracking backlog trends over time
|
||||
|
||||
**Error Handling:**
|
||||
- **Missing credentials file**: If `~/.config/claude-code/mcp.json` doesn't exist, display:
|
||||
```bash
|
||||
Error: JIRA credentials not configured.
|
||||
|
||||
This command requires JIRA credentials from the MCP server configuration file.
|
||||
File not found: ~/.config/claude-code/mcp.json
|
||||
|
||||
Please create this file with your JIRA credentials.
|
||||
See Prerequisites section for the required mcp.json format and setup instructions.
|
||||
```
|
||||
- **Invalid credentials in file**: If credentials are missing from mcp.json, display:
|
||||
```bash
|
||||
Error: JIRA credentials incomplete in ~/.config/claude-code/mcp.json
|
||||
|
||||
Required fields in .mcpServers.atlassian.env:
|
||||
- JIRA_URL (e.g., https://issues.redhat.com)
|
||||
- JIRA_USERNAME (your JIRA email/username)
|
||||
- JIRA_PERSONAL_TOKEN (preferred) or JIRA_API_TOKEN
|
||||
|
||||
See Prerequisites section for the required mcp.json format.
|
||||
```
|
||||
- **Authentication failure**: If curl returns 401/403, display:
|
||||
```bash
|
||||
Error: JIRA authentication failed (HTTP 401/403)
|
||||
|
||||
Please verify your JIRA credentials in ~/.config/claude-code/mcp.json:
|
||||
1. Check that JIRA_PERSONAL_TOKEN is correct and not expired
|
||||
2. Verify JIRA_USERNAME matches your JIRA account
|
||||
3. Ensure JIRA_URL is correct (e.g., https://issues.redhat.com)
|
||||
4. Test authentication: curl -H "Authorization: Bearer YOUR_TOKEN" YOUR_JIRA_URL/rest/api/2/myself
|
||||
|
||||
To regenerate your token, visit:
|
||||
https://issues.redhat.com/secure/ViewProfile.jspa?selectedTab=com.atlassian.pats.pats-plugin:jira-user-personal-access-tokens
|
||||
```
|
||||
- **Invalid project key**: Display error with example format (e.g., "OCPBUGS", "JIRA", "HYPE")
|
||||
- **No tickets found**:
|
||||
- Explain why (e.g., all tickets have assignees and recent activity)
|
||||
- Suggest relaxing search criteria (lower --days-inactive threshold)
|
||||
- Suggest trying different project or removing assignee filter
|
||||
- **curl errors**: Check exit code and display helpful error message
|
||||
- **jq not found**: Inform user to install jq (`brew install jq` on macOS, `apt-get install jq` on Linux)
|
||||
- **Rate limiting**: If API returns 429, implement exponential backoff (wait 60s, retry)
|
||||
|
||||
**Performance Considerations:**
|
||||
- **Large batch size:** Fetch 1000 tickets per request (JIRA's maximum) for efficiency
|
||||
- **Direct file storage:** Stream responses directly to disk, avoid loading into memory
|
||||
- **No token consumption:** Using curl avoids Claude's context/token limits
|
||||
- **Parallel-safe:** Can process very large backlogs (10,000+ tickets) without issues
|
||||
- **Field filtering:** Only request needed fields to minimize response size
|
||||
- **Python processing:** All filtering/analysis happens in Python, not in Claude context
|
||||
- **Minimal Claude interaction:** Only present final filtered/analyzed results to user
|
||||
|
||||
## Return Value
|
||||
|
||||
- **Console Output**: Formatted report showing suggested tickets organized by priority
|
||||
- **Intermediate Files** (created during processing):
|
||||
- `.work/jira-backlog/{project-key}/batch-*.json` - Raw JIRA API responses (one per 1000 tickets)
|
||||
- `.work/jira-backlog/{project-key}/process_batches.py` - Python script for filtering
|
||||
- `.work/jira-backlog/{project-key}/filtered.json` - All filtered tickets grouped by priority
|
||||
- `.work/jira-backlog/{project-key}/stats.json` - Priority distribution statistics
|
||||
- **Optional Final Report**: `.work/jira-backlog/{project-key}-{timestamp}.md` containing the full report
|
||||
- **Summary Statistics**: Count of available tickets per priority level
|
||||
|
||||
## Examples
|
||||
|
||||
**Note:** All examples require JIRA credentials to be configured in `~/.config/claude-code/mcp.json` (see Prerequisites section). The command uses curl to fetch data directly from JIRA's REST API, bypassing MCP commands to avoid 413 errors with large datasets.
|
||||
|
||||
1. **Find unassigned tickets in OCPBUGS project**:
|
||||
```bash
|
||||
/jira:backlog OCPBUGS
|
||||
```
|
||||
Output: Intelligently analyzes tickets and shows 2 recommended tickets from each priority level (Critical, High, Normal, Low)
|
||||
|
||||
Example performance (tested October 31, 2025):
|
||||
- Fetched 2,535 tickets in 3 batches
|
||||
- Found 817 available tickets (unassigned or bot-assigned)
|
||||
- No 413 errors or token limit issues
|
||||
|
||||
2. **Find stale tickets with custom inactivity threshold**:
|
||||
```bash
|
||||
/jira:backlog OCPBUGS --days-inactive 14
|
||||
```
|
||||
Output: Report showing tickets with no activity for 14+ days, 2 per priority level
|
||||
|
||||
3. **Find tickets assigned to a specific user that are stale**:
|
||||
```bash
|
||||
/jira:backlog OCPBUGS --assignee jsmith --days-inactive 30
|
||||
```
|
||||
Output: Report showing tickets assigned to jsmith with 30+ days of inactivity, 2 per priority level
|
||||
|
||||
4. **Find tickets in Hypershift project**:
|
||||
```bash
|
||||
/jira:backlog HYPE
|
||||
```
|
||||
Output: Analyzes backlog and shows best 2 tickets from each priority in HYPE project
|
||||
|
||||
5. **Find tickets in CNV project**:
|
||||
```bash
|
||||
/jira:backlog CNV
|
||||
```
|
||||
Output: Report showing available backlog tickets across all priorities in CNV project
|
||||
|
||||
**Performance Note:** The curl-based approach can handle large backlogs efficiently. In testing with OCPBUGS (2,535 tickets), the command successfully fetched and processed all tickets without hitting Claude's token limits or encountering 413 errors.
|
||||
|
||||
## Arguments
|
||||
|
||||
- **project-key** (required): JIRA project key to search (e.g., OCPBUGS, JIRA, HYPE, CNV)
|
||||
- Must be uppercase
|
||||
- May contain hyphens (e.g., "MY-PROJECT")
|
||||
- If not provided, will prompt user to specify
|
||||
- `--assignee` (optional): Filter by assignee username
|
||||
- Default: Search for unassigned tickets (assignee IS EMPTY)
|
||||
- If username provided: Find tickets assigned to that user with stale activity
|
||||
- Example: `--assignee jsmith` finds jsmith's stale tickets
|
||||
- `--days-inactive` (optional): Number of days of inactivity to consider a ticket stale
|
||||
- Default: 28 days
|
||||
- Lower values find more recently inactive tickets
|
||||
- Example: `--days-inactive 14` finds tickets with 14+ days of no activity
|
||||
564
commands/create-release-note.md
Normal file
564
commands/create-release-note.md
Normal file
@@ -0,0 +1,564 @@
|
||||
---
|
||||
description: Generate bug fix release notes from Jira tickets and linked GitHub PRs
|
||||
argument-hint: <issue-key>
|
||||
---
|
||||
|
||||
## Name
|
||||
jira:create-release-note
|
||||
|
||||
## Synopsis
|
||||
```
|
||||
/jira:create-release-note <issue-key>
|
||||
```
|
||||
|
||||
## Description
|
||||
|
||||
The `jira:create-release-note` command automatically generates bug fix release notes by analyzing Jira bug tickets and their linked GitHub pull requests, then updates the Jira ticket with the generated release note content.
|
||||
|
||||
This command is particularly useful for:
|
||||
- Creating consistent, well-formatted release notes across all bugs
|
||||
- Automatically extracting information from multiple sources (Jira + GitHub)
|
||||
- Saving time by analyzing PR code changes, commits, and descriptions
|
||||
- Ensuring complete release notes with Cause, Consequence, Fix, Result, and Workaround
|
||||
|
||||
The command follows the standard release note template format and populates both the Release Note Type and Release Note Text fields in Jira.
|
||||
|
||||
## Implementation
|
||||
|
||||
The `jira:create-release-note` command runs in multiple phases:
|
||||
|
||||
### 🎯 Phase 1: Fetch and Validate Jira Bug
|
||||
|
||||
1. **Fetch bug ticket** using `mcp__atlassian__jira_get_issue` MCP tool:
|
||||
- Request all fields to ensure we have complete data
|
||||
- Verify the issue is a Bug type
|
||||
- Extract issue description, links, and custom fields
|
||||
|
||||
2. **Validate issue type**:
|
||||
- If not a Bug, warn user and ask if they want to continue
|
||||
- Release notes are typically for bugs, but may apply to other types
|
||||
|
||||
3. **Parse bug description** to extract required sections:
|
||||
- **Cause**: The root cause of the problem
|
||||
- **Consequence**: The impact or effect of the problem
|
||||
|
||||
4. **Handle missing sections**:
|
||||
- If Cause or Consequence sections are missing, inform the user
|
||||
- Provide template format and ask user to update the bug description
|
||||
- Optionally, allow user to provide Cause/Consequence interactively
|
||||
|
||||
### 🔗 Phase 2: Extract Linked GitHub PRs
|
||||
|
||||
Extract all linked GitHub PR URLs from multiple sources:
|
||||
|
||||
1. **Remote links** (Primary source - web links in Jira):
|
||||
- Check the Jira issue response for web links/remote links
|
||||
- Common field names: `remotelinks`, `issuelinks` with `outwardIssue.fields.issuetype.name == "GitHub PR"`
|
||||
- Look for GitHub PR URLs in remote link objects
|
||||
- Pattern: `https://github.com/{org}/{repo}/pull/{number}`
|
||||
- Extract PR URLs and parse into `{org}/{repo}` and `{number}`
|
||||
|
||||
2. **Description text**: Scan bug description for GitHub PR URLs
|
||||
- Use regex pattern to find PR URLs: `https://github\.com/[\w-]+/[\w-]+/pull/\d+`
|
||||
- Extract and parse all matches
|
||||
- **IMPORTANT**: Do NOT use `gh issue view {JIRA-KEY}` - Jira keys are not GitHub issues
|
||||
|
||||
3. **Comments**: Scan bug comments for GitHub PR URLs
|
||||
- Iterate through comments
|
||||
- Extract PR URLs using same regex pattern
|
||||
- **IMPORTANT**: Only look for full GitHub PR URLs, not issue references
|
||||
|
||||
4. **Deduplicate**: Create unique set of PR URLs
|
||||
|
||||
5. **Search by bug number** (Fallback if no PR URLs found):
|
||||
- If no PRs found via links, search GitHub for PRs mentioning the bug
|
||||
- **For OCPBUGS**: Search common repos (openshift/hypershift, openshift/cluster-api-provider-*):
|
||||
```bash
|
||||
# Try common OpenShift repos
|
||||
for repo in "openshift/hypershift" "openshift/cluster-api-provider-aws" "openshift/origin"; do
|
||||
gh pr list --repo $repo --search "{issue-key} in:title,body" --state all --limit 10 --json number,url,title
|
||||
done
|
||||
```
|
||||
- Ask user to confirm which PRs are relevant
|
||||
- **IMPORTANT**: Never use `gh issue view {JIRA-KEY}` - this will fail because Jira keys are not GitHub issue numbers
|
||||
|
||||
6. **Validate**: Ensure at least one PR is found
|
||||
- If no PRs found after all attempts, show error: "No GitHub PRs found linked to {issue-key}. Please link at least one PR to generate release notes."
|
||||
- Provide instructions on how to link PRs in Jira
|
||||
|
||||
### 📊 Phase 3: Analyze Each GitHub PR
|
||||
|
||||
For each linked PR, analyze multiple sources to extract Fix, Result, and Workaround information:
|
||||
|
||||
1. **Extract repository and PR number** from URL:
|
||||
- Parse: `https://github.com/{org}/{repo}/pull/{number}`
|
||||
- Store: `{org}/{repo}` as `REPO`, `{number}` as `PR_NUMBER`
|
||||
|
||||
2. **Fetch PR details** using `gh` CLI:
|
||||
```bash
|
||||
gh pr view {PR_NUMBER} --json body,title,commits,url,state --repo {REPO}
|
||||
```
|
||||
- Extract: title, body/description, commits array, state
|
||||
- Handle errors: If PR is inaccessible, log warning and skip
|
||||
|
||||
3. **Fetch PR diff** using `gh` CLI:
|
||||
```bash
|
||||
gh pr diff {PR_NUMBER} --repo {REPO}
|
||||
```
|
||||
- Analyze code changes to understand what was fixed
|
||||
- Look for key changes in error handling, validation, etc.
|
||||
|
||||
4. **Fetch PR comments** using `gh` CLI:
|
||||
```bash
|
||||
gh pr view {PR_NUMBER} --json comments --repo {REPO}
|
||||
```
|
||||
- Extract reviewer comments and author responses
|
||||
- Look for clarifications about the fix or workarounds
|
||||
|
||||
5. **Analyze all sources**:
|
||||
- **PR Title**: Often summarizes the fix
|
||||
- **PR Body/Description**: Usually contains detailed explanation
|
||||
- **Commit Messages**: May provide step-by-step implementation details
|
||||
- **Code Changes**: Shows exactly what was modified
|
||||
- **PR Comments**: May contain clarifications or additional context
|
||||
|
||||
6. **Extract key information**:
|
||||
- **Fix**: What code/configuration changes were made to address the problem
|
||||
- **Result**: What behavior changed after the fix
|
||||
- **Workaround**: If mentioned, any temporary solutions before the fix
|
||||
|
||||
### 🤖 Phase 4: Synthesize Release Note Content
|
||||
|
||||
Combine information from all analyzed PRs into a cohesive release note:
|
||||
|
||||
1. **Combine Cause/Consequence** from Jira bug:
|
||||
- Use the extracted Cause and Consequence sections
|
||||
- Clean up formatting (remove Jira markup if needed)
|
||||
|
||||
2. **Synthesize Fix** from all PRs:
|
||||
- If single PR: Use the PR's fix description
|
||||
- If multiple PRs: Combine into coherent narrative
|
||||
- Focus on "what was changed" rather than "how it was coded"
|
||||
- Keep it concise but complete
|
||||
|
||||
3. **Synthesize Result** from all PRs:
|
||||
- Describe the outcome after the fix is applied
|
||||
- Focus on user-visible changes
|
||||
- Example: "The control plane operator no longer crashes when..."
|
||||
|
||||
4. **Extract Workaround** (if applicable):
|
||||
- Check if PRs mention temporary solutions
|
||||
- Only include if a workaround was documented
|
||||
- Omit this section if no workaround exists
|
||||
|
||||
5. **Format according to template**:
|
||||
```
|
||||
Cause: <extracted from bug description>
|
||||
Consequence: <extracted from bug description>
|
||||
Fix: <synthesized from PR analysis>
|
||||
Result: <synthesized from PR analysis>
|
||||
Workaround: <synthesized from PR analysis if applicable>
|
||||
```
|
||||
|
||||
### 🔒 Phase 5: Security Validation
|
||||
|
||||
Scan the generated release note text for sensitive data before submission:
|
||||
|
||||
1. **Prohibited content patterns**:
|
||||
- Credentials: Passwords, API tokens, access keys
|
||||
- Cloud keys: AWS access keys (AKIA...), GCP service accounts, Azure credentials
|
||||
- Kubeconfigs: Cluster credentials, service account tokens
|
||||
- SSH keys: Private keys, authorized_keys content
|
||||
- Certificates: PEM files, private key content
|
||||
- URLs with credentials: `https://user:pass@example.com`
|
||||
|
||||
2. **Scanning approach**:
|
||||
- Use regex patterns to detect common credential formats
|
||||
- Check for base64-encoded secrets
|
||||
- Look for common secret prefixes (sk_, ghp_, etc.)
|
||||
|
||||
3. **Action if detected**:
|
||||
- STOP release note creation immediately
|
||||
- Inform user what type of data was detected (without showing it)
|
||||
- Example: "Detected what appears to be an API token in the release note text."
|
||||
- Ask user to review PR content and redact sensitive information
|
||||
- Provide guidance on safe alternatives (use placeholders like `<redacted>`, `YOUR_API_KEY`, etc.)
|
||||
|
||||
### 📝 Phase 6: Select Release Note Type
|
||||
|
||||
Prompt user to select the appropriate Release Note Type:
|
||||
|
||||
1. **Available options** (from Jira dropdown):
|
||||
- Bug Fix (most common for OCPBUGS)
|
||||
- Release Note Not Required
|
||||
- Known Issue
|
||||
- Enhancement
|
||||
- Rebase
|
||||
- Technology Preview
|
||||
- Deprecated Functionality
|
||||
- CVE
|
||||
|
||||
2. **Auto-detection** (optional):
|
||||
- For OCPBUGS: Default to "Bug Fix"
|
||||
- Check PR titles/descriptions for keywords
|
||||
- Suggest type based on content analysis
|
||||
|
||||
3. **User confirmation**:
|
||||
- Show suggested type
|
||||
- Allow user to override
|
||||
- Use `AskUserQuestion` tool for interactive selection
|
||||
|
||||
### ✅ Phase 7: Update Jira Ticket
|
||||
|
||||
Update the Jira bug ticket with generated release note:
|
||||
|
||||
1. **Prepare fields** for update:
|
||||
```
|
||||
{
|
||||
"customfield_12320850": {"value": "<Release Note Type>"},
|
||||
"customfield_12317313": "<Release Note Text>"
|
||||
}
|
||||
```
|
||||
|
||||
2. **Update using MCP tool**:
|
||||
```
|
||||
mcp__atlassian__jira_update_issue(
|
||||
issue_key=<issue-key>,
|
||||
fields={
|
||||
"customfield_12320850": {"value": "Bug Fix"},
|
||||
"customfield_12317313": "<formatted release note text>"
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
3. **Handle update errors**:
|
||||
- Permission denied: User may not have rights to update these fields
|
||||
- Invalid field value: Release Note Type value not in allowed list
|
||||
- Field not found: Custom field IDs may be different in different Jira instances
|
||||
|
||||
### 📤 Phase 8: Display Results
|
||||
|
||||
Show the user what was created:
|
||||
|
||||
1. **Display generated release note**:
|
||||
```
|
||||
Release Note Created for {issue-key}
|
||||
|
||||
Type: Bug Fix
|
||||
|
||||
Text:
|
||||
---
|
||||
Cause: ...
|
||||
Consequence: ...
|
||||
Fix: ...
|
||||
Result: ...
|
||||
Workaround: ...
|
||||
---
|
||||
|
||||
Updated: https://issues.redhat.com/browse/{issue-key}
|
||||
```
|
||||
|
||||
2. **Provide next steps**:
|
||||
- Link to the updated Jira ticket
|
||||
- Suggest reviewing the release note in Jira
|
||||
- Mention that the release note can be edited manually if needed
|
||||
|
||||
## Arguments
|
||||
|
||||
- **$1 – issue-key** *(required)*
|
||||
Jira issue key for the bug (e.g., `OCPBUGS-12345`).
|
||||
Must be a valid bug ticket with linked GitHub PRs.
|
||||
|
||||
## Return Value
|
||||
|
||||
- **Issue Key**: The Jira issue that was updated
|
||||
- **Release Note Type**: The selected release note type
|
||||
- **Release Note Text**: The generated release note content
|
||||
- **Issue URL**: Direct link to the updated Jira ticket
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic Usage
|
||||
|
||||
Create release note for a bug with linked PRs:
|
||||
```
|
||||
/jira:create-release-note OCPBUGS-38358
|
||||
```
|
||||
|
||||
The command will:
|
||||
1. Fetch the bug from Jira
|
||||
2. Extract Cause and Consequence from the description
|
||||
3. Find and analyze all linked GitHub PRs
|
||||
4. Generate the release note
|
||||
5. Prompt for Release Note Type selection
|
||||
6. Update the Jira ticket
|
||||
7. Display the results
|
||||
|
||||
### Example Output
|
||||
|
||||
```
|
||||
Analyzing OCPBUGS-38358...
|
||||
|
||||
Found bug: "hostedcontrolplane controller crashes when hcp.Spec.Platform.AWS.CloudProviderConfig.Subnet.ID is undefined"
|
||||
|
||||
Extracted from bug description:
|
||||
Cause: hostedcontrolplane controller crashes when hcp.Spec.Platform.AWS.CloudProviderConfig.Subnet.ID is undefined
|
||||
Consequence: control-plane-operator enters a crash loop
|
||||
|
||||
Found 1 linked GitHub PR:
|
||||
- https://github.com/openshift/hypershift/pull/4567
|
||||
|
||||
Analyzing PR #4567...
|
||||
Title: "Fix panic when CloudProviderConfig.Subnet is not specified"
|
||||
Commits: 2
|
||||
Files changed: 3
|
||||
|
||||
Synthesizing release note...
|
||||
|
||||
Select Release Note Type:
|
||||
1. Bug Fix
|
||||
2. Release Note Not Required
|
||||
3. Known Issue
|
||||
4. Enhancement
|
||||
5. CVE
|
||||
|
||||
Selection: 1 (Bug Fix)
|
||||
|
||||
Updating Jira ticket...
|
||||
|
||||
✓ Release Note Created for OCPBUGS-38358
|
||||
|
||||
Type: Bug Fix
|
||||
|
||||
Text:
|
||||
---
|
||||
Cause: hostedcontrolplane controller crashes when hcp.Spec.Platform.AWS.CloudProviderConfig.Subnet.ID is undefined
|
||||
Consequence: control-plane-operator enters a crash loop
|
||||
Fix: Added nil check for CloudProviderConfig.Subnet before accessing Subnet.ID field
|
||||
Result: The control-plane-operator no longer crashes when CloudProviderConfig.Subnet is not specified
|
||||
---
|
||||
|
||||
Updated: https://issues.redhat.com/browse/OCPBUGS-38358
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
### No GitHub PRs Linked
|
||||
|
||||
**Scenario**: Bug ticket has no linked GitHub PRs.
|
||||
|
||||
**Error Message**:
|
||||
```
|
||||
No GitHub PRs found linked to OCPBUGS-12345.
|
||||
|
||||
To generate a release note, please link at least one GitHub PR to this bug.
|
||||
|
||||
How to link PRs:
|
||||
1. Edit the bug in Jira
|
||||
2. Add a web link to the GitHub PR URL
|
||||
3. Or mention the PR URL in a comment
|
||||
4. Then run this command again
|
||||
```
|
||||
|
||||
**Action**: Exit without updating the ticket.
|
||||
|
||||
### PR Not Accessible
|
||||
|
||||
**Scenario**: One or more linked PRs cannot be accessed.
|
||||
|
||||
**Warning Message**:
|
||||
```
|
||||
Warning: Unable to access PR https://github.com/org/repo/pull/123
|
||||
Verify the PR exists and you have permissions.
|
||||
|
||||
Continuing with remaining PRs...
|
||||
```
|
||||
|
||||
**Action**: Skip the inaccessible PR, continue with others. If all PRs are inaccessible, treat as "No PRs" error.
|
||||
|
||||
### Missing Cause or Consequence
|
||||
|
||||
**Scenario**: Bug description doesn't contain required Cause and/or Consequence sections.
|
||||
|
||||
**Error Message**:
|
||||
```
|
||||
Bug description is missing required sections:
|
||||
- Missing: Cause
|
||||
- Missing: Consequence
|
||||
|
||||
Please update the bug description to include these sections.
|
||||
|
||||
Template format:
|
||||
---
|
||||
Description of problem:
|
||||
<problem description>
|
||||
|
||||
Cause:
|
||||
<root cause of the problem>
|
||||
|
||||
Consequence:
|
||||
<impact or effect of the problem>
|
||||
|
||||
Steps to Reproduce:
|
||||
1. ...
|
||||
---
|
||||
|
||||
Would you like to provide Cause and Consequence interactively? (yes/no)
|
||||
```
|
||||
|
||||
**Action**:
|
||||
- If user says yes: Prompt for Cause and Consequence
|
||||
- If user says no: Exit and ask them to update the bug
|
||||
|
||||
### Security Validation Failure
|
||||
|
||||
**Scenario**: Generated release note contains potential credentials or secrets.
|
||||
|
||||
**Error Message**:
|
||||
```
|
||||
Security validation failed!
|
||||
|
||||
Detected what appears to be an API token in the release note text.
|
||||
|
||||
This may have come from:
|
||||
- PR description
|
||||
- Commit messages
|
||||
- Code changes
|
||||
- PR comments
|
||||
|
||||
Please review the source PRs and remove any credentials before proceeding.
|
||||
|
||||
Use placeholder values instead:
|
||||
- YOUR_API_KEY
|
||||
- <redacted>
|
||||
- ********
|
||||
|
||||
Aborting release note creation.
|
||||
```
|
||||
|
||||
**Action**: Stop immediately, do not update Jira ticket.
|
||||
|
||||
### Update Permission Denied
|
||||
|
||||
**Scenario**: User doesn't have permission to update Release Note fields.
|
||||
|
||||
**Error Message**:
|
||||
```
|
||||
Failed to update OCPBUGS-12345.
|
||||
|
||||
Error: You do not have permission to edit field 'Release Note Type'
|
||||
|
||||
This may require specific Jira permissions. Please contact your Jira administrator or use the Jira web UI to add the release note manually.
|
||||
|
||||
Generated release note (for manual entry):
|
||||
---
|
||||
Cause: ...
|
||||
Consequence: ...
|
||||
...
|
||||
---
|
||||
```
|
||||
|
||||
**Action**: Display the generated release note so user can manually copy it.
|
||||
|
||||
### Invalid Release Note Type
|
||||
|
||||
**Scenario**: Selected release note type is not valid for this Jira instance.
|
||||
|
||||
**Error Message**:
|
||||
```
|
||||
Failed to update Release Note Type field.
|
||||
|
||||
Error: Value "Bug Fix" is not valid for field customfield_12320850
|
||||
|
||||
This may indicate a Jira configuration issue. Please verify the allowed values for Release Note Type in your Jira instance.
|
||||
```
|
||||
|
||||
**Action**: Ask user to select a different type or manually update in Jira.
|
||||
|
||||
### Multiple PRs with Conflicting Information
|
||||
|
||||
**Scenario**: Multiple PRs describe different fixes or contradictory information.
|
||||
|
||||
**Warning Message**:
|
||||
```
|
||||
Found 3 linked PRs with different fix descriptions:
|
||||
- PR #123: Fix A
|
||||
- PR #456: Fix B
|
||||
- PR #789: Fix C
|
||||
|
||||
Combining all fixes into a single release note...
|
||||
```
|
||||
|
||||
**Action**: Use AI to synthesize a coherent narrative combining all fixes. If truly contradictory, ask user for clarification.
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Link PRs early**: Add GitHub PR links to bugs as soon as PRs are created
|
||||
2. **Use structured bug descriptions**: Always include Cause and Consequence sections
|
||||
3. **Review before submission**: Check the generated release note before confirming
|
||||
4. **Sanitize PR content**: Don't include credentials in PR descriptions or commits
|
||||
5. **One release note per bug**: Don't run this command multiple times for the same bug
|
||||
6. **Update if needed**: Release notes can be manually edited in Jira after creation
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Required Tools
|
||||
|
||||
1. **MCP Jira Server**: Must be configured and accessible
|
||||
- See [Jira Plugin README](../README.md) for setup instructions
|
||||
- Requires read/write permissions for bugs
|
||||
|
||||
2. **GitHub CLI (`gh`)**: Must be installed and authenticated
|
||||
- Install: `brew install gh` (macOS) or see [GitHub CLI docs](https://cli.github.com/)
|
||||
- Authenticate: `gh auth login`
|
||||
- Verify: `gh auth status`
|
||||
|
||||
3. **Access to GitHub Repositories**: Must have read access to repos where PRs are located
|
||||
- PRs in private repos require appropriate GitHub permissions
|
||||
- Public repos should work without additional configuration
|
||||
|
||||
### Required Permissions
|
||||
|
||||
1. **Jira Permissions**:
|
||||
- Read access to bug tickets
|
||||
- Write access to Release Note Type field (customfield_12320850)
|
||||
- Write access to Release Note Text field (customfield_12317313)
|
||||
|
||||
2. **GitHub Permissions**:
|
||||
- Read access to pull requests
|
||||
- Read access to repository diffs and commits
|
||||
|
||||
## See Also
|
||||
|
||||
- `jira:solve` - Analyze and solve Jira issues
|
||||
- `jira:create` - Create Jira issues with guided workflows
|
||||
- `jira:generate-test-plan` - Generate test plans for PRs
|
||||
- `jira:status-rollup` - Create status rollup reports
|
||||
|
||||
## Technical Notes
|
||||
|
||||
### Jira Custom Fields
|
||||
|
||||
The command uses these Jira custom field IDs:
|
||||
- `customfield_12320850`: Release Note Type (dropdown)
|
||||
- `customfield_12317313`: Release Note Text (text field)
|
||||
|
||||
These field IDs are specific to Red Hat's Jira instance. If using a different Jira instance, you may need to update the field IDs.
|
||||
|
||||
### GitHub CLI Rate Limits
|
||||
|
||||
The `gh` CLI is subject to GitHub API rate limits:
|
||||
- Authenticated: 5,000 requests per hour
|
||||
- This command typically uses 3-4 requests per PR (view, diff, comments)
|
||||
- For bugs with many linked PRs, be aware of rate limits
|
||||
|
||||
### Release Note Template
|
||||
|
||||
The release note follows this structure:
|
||||
- **Cause**: Root cause (from Jira)
|
||||
- **Consequence**: Impact (from Jira)
|
||||
- **Fix**: What was changed (from PRs)
|
||||
- **Result**: Outcome after fix (from PRs)
|
||||
- **Workaround**: Temporary solution (from PRs, optional)
|
||||
|
||||
This format is standard for Red Hat bug fix release notes.
|
||||
579
commands/create.md
Normal file
579
commands/create.md
Normal file
@@ -0,0 +1,579 @@
|
||||
---
|
||||
description: Create Jira issues (story, epic, feature, task, bug, feature-request) with proper formatting
|
||||
argument-hint: <type> [project-key] <summary> [--component <name>] [--version <version>] [--parent <key>]
|
||||
---
|
||||
|
||||
## Name
|
||||
jira:create
|
||||
|
||||
## Synopsis
|
||||
```
|
||||
/jira:create <type> [project-key] <summary> [options]
|
||||
```
|
||||
|
||||
## Description
|
||||
The `jira:create` command creates Jira issues following best practices and team-specific conventions. It supports creating stories, epics, features, tasks, bugs, and feature requests with intelligent defaults, interactive prompts, and validation.
|
||||
|
||||
This command is particularly useful for:
|
||||
- Creating well-formed user stories with acceptance criteria
|
||||
- Organizing epics and features with proper hierarchy
|
||||
- Submitting bugs with complete reproduction steps
|
||||
- Capturing customer-driven feature requests with business justification
|
||||
- Maintaining consistency across team Jira practices
|
||||
|
||||
## Key Features
|
||||
|
||||
- **Multi-Type Support** - Create stories, epics, features, tasks, bugs, or feature requests from a single command
|
||||
- **Smart Defaults** - Automatically applies project-specific conventions (e.g., CNTRLPLANE, OCPBUGS, RFE)
|
||||
- **Interactive Guidance** - Prompts for missing information with helpful templates
|
||||
- **Context Detection** - Analyzes summary text to suggest components (ARO, ROSA, HyperShift)
|
||||
- **Security Validation** - Scans for credentials and secrets before submission
|
||||
- **Template Support** - Provides user story templates, bug report templates, feature request workflows, acceptance criteria formats
|
||||
|
||||
## Implementation
|
||||
|
||||
The `jira:create` command runs in multiple phases:
|
||||
|
||||
### 🎯 Phase 1: Load Implementation Guidance
|
||||
|
||||
Invoke the appropriate skill based on issue type using the Skill tool:
|
||||
|
||||
- **Type: `story`** → Invoke `jira:create-story` skill
|
||||
- Loads user story template guidance
|
||||
- Provides acceptance criteria formats
|
||||
- Offers story quality validation
|
||||
|
||||
- **Type: `epic`** → Invoke `jira:create-epic` skill
|
||||
- Loads epic structure guidance
|
||||
- Provides epic name field handling
|
||||
- Offers parent feature linking workflow
|
||||
|
||||
- **Type: `feature`** → Invoke `jira:create-feature` skill
|
||||
- Loads strategic planning guidance
|
||||
- Provides market problem framework
|
||||
- Offers success criteria templates
|
||||
|
||||
- **Type: `task`** → Invoke `jira:create-task` skill
|
||||
- Loads technical task guidance
|
||||
- Provides task vs story differentiation
|
||||
- Offers acceptance criteria for technical work
|
||||
|
||||
- **Type: `bug`** → Invoke `jira:create-bug` skill
|
||||
- Loads bug report template
|
||||
- Provides structured reproduction steps
|
||||
- Offers severity and reproducibility guidance
|
||||
|
||||
- **Type: `feature-request`** → Invoke `jira:create-feature-request` skill
|
||||
- Loads customer-driven feature request guidance
|
||||
- Provides 4-question workflow (title, description, business requirements, components)
|
||||
- Offers component mapping from teams/operators
|
||||
- Targets RFE project
|
||||
|
||||
### 🏢 Phase 2: Apply Project-Specific Conventions
|
||||
|
||||
Invoke project-specific and team-specific skills using the Skill tool as needed:
|
||||
|
||||
**Project-specific skills:**
|
||||
- **CNTRLPLANE:** Invoke `cntrlplane` skill for CNTRLPLANE stories/epics/features/tasks
|
||||
- **OCPBUGS:** Invoke `ocpbugs` skill for OCPBUGS bugs
|
||||
- **Other projects:** Use only type-specific skills for best practices
|
||||
|
||||
**Team-specific skills:**
|
||||
- Detected based on keywords in summary/description or component
|
||||
- Apply team-specific conventions (component selection, custom fields, workflows)
|
||||
- Layer on top of project-specific conventions
|
||||
- Example: HyperShift team → invoke `hypershift` skill
|
||||
|
||||
**General projects** use only the type-specific skills (create-story, create-bug, etc.) for best practices.
|
||||
|
||||
### 📝 Phase 3: Parse Arguments & Detect Context
|
||||
|
||||
Parse command arguments:
|
||||
- **Required:** `type`, `summary`
|
||||
- **Optional:** `project_key` (may have project-specific defaults)
|
||||
- **Optional flags:** `--component`, `--version`, `--parent`
|
||||
|
||||
Analyze summary text for context clues:
|
||||
- Extract keywords that may indicate team, component, or platform
|
||||
- Pass context to project-specific and team-specific skills for interpretation
|
||||
- Skills handle keyword detection and component/field suggestions
|
||||
|
||||
### ⚙️ Phase 4: Apply Smart Defaults
|
||||
|
||||
**Universal requirements (MUST be applied to ALL tickets):**
|
||||
- **Security level:** Red Hat Employee (required)
|
||||
- **Labels:** ai-generated-jira (required)
|
||||
|
||||
**Project defaults:**
|
||||
- May include default project for certain issue types
|
||||
- Version defaults (if applicable)
|
||||
- Additional labels (for tracking or automation)
|
||||
|
||||
**Team defaults:**
|
||||
- Component selection (based on keywords or prompts)
|
||||
- Custom field values
|
||||
- Workflow-specific requirements
|
||||
|
||||
**General projects:**
|
||||
- Use type-specific skills for issue structure
|
||||
- Prompt for required fields as needed
|
||||
|
||||
### 💬 Phase 5: Interactive Prompts (Hybrid Approach)
|
||||
|
||||
Prompt for missing required information based on issue type:
|
||||
|
||||
**For Stories:**
|
||||
- Offer user story template: "As a... I want... So that..."
|
||||
- Collect acceptance criteria (suggest formats)
|
||||
- Confirm auto-detected component
|
||||
|
||||
**For Epics:**
|
||||
- Collect epic objective and scope
|
||||
- Collect epic acceptance criteria
|
||||
- Collect timeline/target release
|
||||
- Set epic name field (same as summary)
|
||||
- Optional parent feature link (via `--parent` or prompt)
|
||||
|
||||
**For Features:**
|
||||
- Collect market problem description
|
||||
- Collect strategic value and business impact
|
||||
- Collect success criteria (adoption, usage, outcomes, business)
|
||||
- Identify component epics (3-8 major work streams)
|
||||
- Collect timeline and milestones
|
||||
|
||||
**For Tasks:**
|
||||
- Collect task description (what needs to be done)
|
||||
- Collect motivation/context (why it's needed)
|
||||
- Optionally collect acceptance criteria
|
||||
- Optionally collect technical details (files, approach)
|
||||
|
||||
**For Bugs:**
|
||||
- Use bug template (interactive fill-in):
|
||||
- Description of problem
|
||||
- Version-Release number
|
||||
- How reproducible (Always | Sometimes | Rarely)
|
||||
- Steps to Reproduce (numbered list)
|
||||
- Actual results (include error messages)
|
||||
- Expected results (correct behavior)
|
||||
- Additional info (logs, screenshots)
|
||||
|
||||
**For Feature Requests:**
|
||||
- Use 4-question workflow:
|
||||
1. Proposed title of feature request
|
||||
2. Nature and description (current limitations, desired behavior, use case)
|
||||
3. Business requirements (customer impact, regulatory drivers, justification)
|
||||
4. Affected packages and components (teams, operators, component mapping)
|
||||
|
||||
### ✅ Phase 5.5: Summary Validation
|
||||
|
||||
Before security validation, validate the summary format to catch common mistakes:
|
||||
|
||||
**Check for anti-patterns:**
|
||||
1. Summary starts with "As a" (user story format belongs in description)
|
||||
2. Summary contains "I want" or "so that" (belongs in description)
|
||||
3. Summary exceeds 100 characters (likely too long, may be full user story)
|
||||
|
||||
**Action if anti-pattern detected:**
|
||||
1. Detect that user put full user story in summary field
|
||||
2. Extract the key action/feature from the summary
|
||||
3. Generate a concise alternative (5-10 words)
|
||||
4. Prompt user for confirmation:
|
||||
```
|
||||
The summary looks like a full user story. Summaries should be concise titles.
|
||||
|
||||
Current: "As a cluster admin, I want to configure ImageTagMirrorSet in HostedCluster CRs so that I can enable tag-based image proxying"
|
||||
|
||||
Suggested: "Enable ImageTagMirrorSet configuration in HostedCluster CRs"
|
||||
|
||||
Use the suggested summary? (yes/no/edit)
|
||||
```
|
||||
|
||||
5. If user says yes, use suggested summary
|
||||
6. If user says edit, prompt for their preferred summary
|
||||
7. If user says no, use their original summary (but warn it may be truncated in Jira)
|
||||
|
||||
**Note:** This validation should happen BEFORE creating the issue, to avoid having to update the summary afterward.
|
||||
|
||||
### 🔒 Phase 6: Security Validation
|
||||
|
||||
Scan all content (summary, description, comments) for sensitive data:
|
||||
|
||||
**Prohibited content:**
|
||||
- Credentials (usernames/passwords, API tokens)
|
||||
- Cloud keys (AWS access keys, GCP service accounts, Azure credentials)
|
||||
- Kubeconfigs (cluster credentials, service account tokens)
|
||||
- SSH keys (private keys, authorized_keys)
|
||||
- Certificates (PEM files, private keys)
|
||||
- URLs with embedded credentials (e.g., `https://user:pass@example.com`)
|
||||
|
||||
**Action if detected:**
|
||||
- STOP issue creation immediately
|
||||
- Inform user what type of data was detected (without exposing it)
|
||||
- Ask user to redact sensitive information
|
||||
- Provide guidance on safe alternatives (placeholder values)
|
||||
|
||||
### ✅ Phase 7: Create Issue via MCP
|
||||
|
||||
Use the `mcp__atlassian__jira_create_issue` MCP tool with collected parameters.
|
||||
|
||||
**Build additional_fields:**
|
||||
|
||||
**Required fields (MUST be included):**
|
||||
- `security`: `{"name": "Red Hat Employee"}`
|
||||
- `labels`: `["ai-generated-jira"]` (may be combined with additional labels)
|
||||
|
||||
**Project-specific and team-specific fields:**
|
||||
- Custom field mappings
|
||||
- Version fields
|
||||
- Additional labels
|
||||
- Parent links
|
||||
- Component names
|
||||
- Any other project/team-specific requirements
|
||||
|
||||
The MCP tool parameters come from the combined guidance of type-specific, project-specific, and team-specific skills, with universal requirements always applied.
|
||||
|
||||
**Note:** Project-specific skills (e.g., CNTRLPLANE) may implement fallback strategies for handling creation failures (such as epic linking). Refer to the project-specific skill documentation for these strategies.
|
||||
|
||||
### 📤 Phase 8: Return Result
|
||||
|
||||
Display to user:
|
||||
- **Issue Key** (e.g., PROJECT-1234)
|
||||
- **Issue URL** (direct link to created issue)
|
||||
- **Summary of applied defaults** (any fields auto-populated by skills)
|
||||
|
||||
**Example output:**
|
||||
```
|
||||
Created: PROJECT-1234
|
||||
Title: <issue summary>
|
||||
URL: <issue URL>
|
||||
|
||||
Applied defaults:
|
||||
- <Field>: <Value>
|
||||
- <Field>: <Value>
|
||||
(varies by project/team)
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
|
||||
1. **Create a story with minimal info**:
|
||||
```
|
||||
/jira:create story MYPROJECT "Add user dashboard"
|
||||
```
|
||||
→ Prompts for user story format, acceptance criteria, and any required fields
|
||||
|
||||
2. **Create a story with options**:
|
||||
```
|
||||
/jira:create story MYPROJECT "Add search functionality" --component "Frontend" --version "2.5.0"
|
||||
```
|
||||
→ Uses provided component and version, prompts only for description and AC
|
||||
|
||||
3. **Create an epic with parent feature**:
|
||||
```
|
||||
/jira:create epic MYPROJECT "Mobile application redesign" --parent MYPROJECT-100
|
||||
```
|
||||
→ Links epic to parent feature, prompts for epic details
|
||||
|
||||
4. **Create a bug**:
|
||||
```
|
||||
/jira:create bug MYPROJECT "Login button doesn't work on mobile"
|
||||
```
|
||||
→ Prompts for bug template fields (description, steps, actual/expected results)
|
||||
|
||||
5. **Create a bug with component**:
|
||||
```
|
||||
/jira:create bug MYPROJECT "API returns 500 error" --component "Backend"
|
||||
```
|
||||
→ Uses specified component, prompts for bug details
|
||||
|
||||
6. **Create a task under a story**:
|
||||
```
|
||||
/jira:create task MYPROJECT "Update API documentation" --parent MYPROJECT-456
|
||||
```
|
||||
→ Links task to parent story, prompts for task description
|
||||
|
||||
7. **Create a feature**:
|
||||
```
|
||||
/jira:create feature MYPROJECT "Advanced search capabilities"
|
||||
```
|
||||
→ Prompts for market problem, strategic value, success criteria, epic breakdown
|
||||
|
||||
8. **Create a feature request**:
|
||||
```
|
||||
/jira:create feature-request RFE "Support custom SSL certificates for ROSA HCP"
|
||||
```
|
||||
→ Prompts for nature/description, business requirements, affected components (4-question workflow)
|
||||
|
||||
9. **Create with project-specific conventions** (examples vary by project):
|
||||
```
|
||||
/jira:create story SPECIALPROJECT "New capability"
|
||||
```
|
||||
→ Applies SPECIALPROJECT-specific skills and conventions automatically
|
||||
|
||||
## Arguments
|
||||
|
||||
- **$1 – type** *(required)*
|
||||
Issue type to create.
|
||||
**Options:** `story` | `epic` | `feature` | `task` | `bug` | `feature-request`
|
||||
|
||||
- **$2 – project-key** *(optional for bugs and feature-requests)*
|
||||
JIRA project key (e.g., `CNTRLPLANE`, `OCPBUGS`, `RFE`, `MYPROJECT`).
|
||||
**Default for bugs:** `OCPBUGS`
|
||||
**Default for feature-requests:** `RFE`
|
||||
**Required for:** stories, epics, features, tasks
|
||||
|
||||
- **$3 – summary** *(required)*
|
||||
Issue title/summary text.
|
||||
Use quotes for multi-word summaries: `"Enable automatic scaling"`
|
||||
|
||||
- **--component** *(optional)*
|
||||
Component name (e.g., `"HyperShift / ROSA"`, `"Networking"`, `"API"`).
|
||||
Auto-detected from summary context if not provided (for CNTRLPLANE/OCPBUGS).
|
||||
|
||||
- **--version** *(optional)*
|
||||
Target version (e.g., `"4.21"`, `"4.22"`, `"2.5.0"`).
|
||||
**Default varies by project:**
|
||||
- CNTRLPLANE/OCPBUGS: `openshift-4.21`
|
||||
- Other projects: Prompt or use project default
|
||||
|
||||
- **--parent** *(optional)*
|
||||
Parent issue key for linking (e.g., `CNTRLPLANE-123`).
|
||||
**Valid for:**
|
||||
- Epics: Link to parent Feature
|
||||
- Tasks: Link to parent Story or Epic
|
||||
- Stories: Link to parent Epic (less common)
|
||||
|
||||
## Return Value
|
||||
|
||||
- **Issue Key**: The created Jira issue identifier (e.g., `CNTRLPLANE-1234`)
|
||||
- **Issue URL**: Direct link to the created issue
|
||||
- **Summary**: Confirmation of applied defaults and field values
|
||||
|
||||
## Configuration
|
||||
|
||||
### Project-Specific Skills
|
||||
|
||||
The command automatically detects and applies project-specific conventions:
|
||||
|
||||
- **CNTRLPLANE:** Uses `cntrlplane` skill for CNTRLPLANE stories/epics/features/tasks
|
||||
- **OCPBUGS:** Uses `ocpbugs` skill for OCPBUGS bugs
|
||||
- **Other projects:** Uses general best practices from type-specific skills
|
||||
|
||||
To add conventions for your project, create a skill at:
|
||||
```
|
||||
plugins/jira/skills/your-project-name/SKILL.md
|
||||
```
|
||||
|
||||
Then update the command implementation to invoke your skill when the project is detected.
|
||||
|
||||
### Environment Variables
|
||||
|
||||
The command respects MCP Jira server configuration:
|
||||
- **JIRA_PROJECTS_FILTER:** Filter which projects are accessible
|
||||
- **JIRA_SERVER_URL:** Jira instance URL
|
||||
- **JIRA_AUTH:** Authentication credentials
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Invalid Issue Type
|
||||
|
||||
**Scenario:** User specifies invalid type.
|
||||
|
||||
**Action:**
|
||||
```
|
||||
Invalid issue type "stroy". Valid types: story, epic, feature, task, bug
|
||||
|
||||
Did you mean "story"?
|
||||
```
|
||||
|
||||
### Missing Project Key
|
||||
|
||||
**Scenario:** Project key required but not provided.
|
||||
|
||||
**Action:**
|
||||
```
|
||||
Project key is required for stories/tasks/epics/features.
|
||||
|
||||
Usage: /jira:create story PROJECT-KEY "summary"
|
||||
|
||||
Example: /jira:create story CNTRLPLANE "Enable autoscaling"
|
||||
```
|
||||
|
||||
### Component Required But Not Provided
|
||||
|
||||
**Scenario:** Project requires component, cannot auto-detect, user didn't specify.
|
||||
|
||||
**Action:**
|
||||
```
|
||||
Component is required for CNTRLPLANE issues. Which component?
|
||||
1. HyperShift / ARO - for ARO HCP (Azure) issues
|
||||
2. HyperShift / ROSA - for ROSA HCP (AWS) issues
|
||||
3. HyperShift - for platform-agnostic issues
|
||||
|
||||
Select a component (1-3):
|
||||
```
|
||||
|
||||
### Parent Issue Not Found
|
||||
|
||||
**Scenario:** User specifies `--parent` but issue doesn't exist.
|
||||
|
||||
**Action:**
|
||||
```
|
||||
Parent issue CNTRLPLANE-999 not found.
|
||||
|
||||
Options:
|
||||
1. Proceed without parent link
|
||||
2. Specify different parent
|
||||
3. Cancel creation
|
||||
|
||||
What would you like to do?
|
||||
```
|
||||
|
||||
### Security Validation Failure
|
||||
|
||||
**Scenario:** Credentials or secrets detected.
|
||||
|
||||
**Action:**
|
||||
```
|
||||
I detected what appears to be an API token in the description.
|
||||
|
||||
Please review and redact before proceeding. Use placeholder values like:
|
||||
- YOUR_API_KEY
|
||||
- <redacted>
|
||||
- ********
|
||||
|
||||
Would you like to edit the description?
|
||||
```
|
||||
|
||||
### MCP Tool Error
|
||||
|
||||
**Scenario:** MCP tool returns an error.
|
||||
|
||||
**Action:**
|
||||
1. Parse error message
|
||||
2. Translate to user-friendly explanation
|
||||
3. Suggest corrective action
|
||||
4. Offer to retry
|
||||
|
||||
**Common errors:**
|
||||
- **"Field 'component' is required"** → Prompt for component
|
||||
- **"Version not found"** → Fetch available versions, suggest closest match
|
||||
- **"Permission denied"** → User may lack permissions, suggest contacting admin
|
||||
- **"Issue type not available"** → Project may not support this issue type
|
||||
|
||||
### Epic Link Creation Failure
|
||||
|
||||
**Scenario:** Story/task creation fails when including epic link field.
|
||||
|
||||
**Action:**
|
||||
Refer to project-specific skills for epic linking fallback strategies:
|
||||
- **CNTRLPLANE:** See CNTRLPLANE skill "Epic Linking Implementation Strategy" section
|
||||
- **Other projects:** Consult project-specific skill documentation
|
||||
|
||||
**General pattern:**
|
||||
1. Detect error related to linking (error contains "epic", "parent", "link", or "customfield")
|
||||
2. Check project-specific skill for recommended fallback approach
|
||||
3. Typically: Create without link, then link via update
|
||||
4. Inform user of outcome
|
||||
5. **Last stand fallback:** If all strategies fail (including update-after-create), retry with absolute minimal fields:
|
||||
- Remove ALL custom fields (epic link, target version, etc.)
|
||||
- Keep only: project_key, summary, issue_type, description, assignee, components
|
||||
- Log to console what was stripped out
|
||||
- If this succeeds, inform user which fields need manual configuration in Jira
|
||||
|
||||
### Field Format Error
|
||||
|
||||
**Scenario:** Field provided in wrong format (e.g., Target Version as string instead of array).
|
||||
|
||||
**Common field format errors:**
|
||||
|
||||
1. **Target Version format**
|
||||
- ❌ Wrong: `"customfield_12319940": "openshift-4.21"`
|
||||
- ✅ Correct: `"customfield_12319940": [{"id": "12448830"}]`
|
||||
- **Action:** Fetch version ID using `mcp__atlassian__jira_get_project_versions`, convert to correct format
|
||||
|
||||
2. **Epic Link format**
|
||||
- ❌ Wrong: `"parent": {"key": "EPIC-123"}` (for stories)
|
||||
- ✅ Correct: `"customfield_12311140": "EPIC-123"` (string, not object)
|
||||
- **Action:** Convert to correct format and retry
|
||||
|
||||
3. **Component format**
|
||||
- ❌ Wrong: `"components": "ComponentName"`
|
||||
- ✅ Correct: `"components": ["ComponentName"]` (array) or just `"ComponentName"` (MCP accepts both)
|
||||
- **Action:** Ensure consistent format
|
||||
|
||||
**Detection:**
|
||||
- Parse error message for field names
|
||||
- Check skill documentation for correct format
|
||||
- Automatically convert and retry when possible
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Use descriptive summaries:** Include relevant keywords for context and auto-detection
|
||||
2. **Provide flags when known:** Use `--component` and `--version` to skip prompts
|
||||
3. **Link related work:** Use `--parent` to maintain hierarchy
|
||||
4. **Review before submit:** Check the formatted content before confirming creation
|
||||
5. **Follow templates:** Use the provided templates for consistency
|
||||
6. **Sanitize content:** Remove credentials before including logs or screenshots
|
||||
|
||||
## Anti-Patterns to Avoid
|
||||
|
||||
❌ **Wrong issue type**
|
||||
```
|
||||
/jira:create story MYPROJECT "Refactor database layer"
|
||||
```
|
||||
✅ This is technical work, use `task` instead
|
||||
|
||||
❌ **Vague summaries**
|
||||
```
|
||||
/jira:create bug "Something is broken"
|
||||
```
|
||||
✅ Be specific: "API server returns 500 error when creating namespaces"
|
||||
|
||||
❌ **Missing context**
|
||||
```
|
||||
/jira:create epic MYPROJECT "Improve things"
|
||||
```
|
||||
✅ Be descriptive: "Mobile application redesign"
|
||||
|
||||
❌ **Including credentials**
|
||||
```
|
||||
Steps to reproduce:
|
||||
1. Export API_KEY=sk_live_abc123xyz
|
||||
```
|
||||
✅ Use placeholders: "Export API_KEY=YOUR_API_KEY"
|
||||
|
||||
## See Also
|
||||
|
||||
- `jira:solve` - Analyze and solve Jira issues
|
||||
- `jira:grooming` - Generate grooming meeting agendas
|
||||
- `jira:status-rollup` - Create status rollup reports
|
||||
- `jira:generate-test-plan` - Generate test plans for PRs
|
||||
|
||||
## Skills Reference
|
||||
|
||||
The following skills are automatically invoked by this command:
|
||||
|
||||
**Type-specific skills:**
|
||||
- **create-story** - User story creation guidance
|
||||
- **create-epic** - Epic creation and structure
|
||||
- **create-feature** - Feature planning and strategy
|
||||
- **create-task** - Technical task creation
|
||||
- **create-bug** - Bug report templates
|
||||
- **create-feature-request** - Customer-driven feature request workflow for RFE project
|
||||
|
||||
**Project-specific skills:**
|
||||
- **cntrlplane** - CNTRLPLANE project conventions (stories, epics, features, tasks)
|
||||
- **ocpbugs** - OCPBUGS project conventions (bugs only)
|
||||
|
||||
**Team-specific skills:**
|
||||
- **hypershift** - HyperShift team conventions (component selection for ARO/ROSA/HyperShift)
|
||||
|
||||
To view skill details:
|
||||
```bash
|
||||
ls plugins/jira/skills/
|
||||
cat plugins/jira/skills/create-story/SKILL.md
|
||||
cat plugins/jira/skills/create-feature-request/SKILL.md
|
||||
cat plugins/jira/skills/cntrlplane/SKILL.md
|
||||
cat plugins/jira/skills/ocpbugs/SKILL.md
|
||||
cat plugins/jira/skills/hypershift/SKILL.md
|
||||
```
|
||||
186
commands/generate-test-plan.md
Normal file
186
commands/generate-test-plan.md
Normal file
@@ -0,0 +1,186 @@
|
||||
---
|
||||
description: Generate test steps for a JIRA issue
|
||||
argument-hint: [JIRA issue key] [GitHub PR URLs]
|
||||
---
|
||||
|
||||
## Name
|
||||
jira:generate-test-plan
|
||||
|
||||
## Synopsis
|
||||
/jira:generate-test-plan [JIRA issue key] [GitHub PR URLs]
|
||||
|
||||
## Description
|
||||
The 'jira:generate-test-plan' command takes a JIRA issue key and optionally a list of PR URLs. It fetches the JIRA issue details, retrieves all related PRs (or uses the provided PR list), analyzes the changes, and generates a comprehensive manual testing guide.
|
||||
|
||||
**JIRA Issue Test Guide Generator**
|
||||
|
||||
## Implementation
|
||||
|
||||
- The command uses curl to fetch JIRA data via REST API: https://issues.redhat.com/rest/api/2/issue/{$1}
|
||||
- Uses WebFetch to extract PR links from JIRA issue if no PRs provided
|
||||
- Uses `gh pr view` to fetch PR details for each PR
|
||||
- Analyzes changes across all PRs to understand implementation
|
||||
- Generates comprehensive manual test scenarios
|
||||
|
||||
## Process Flow:
|
||||
|
||||
1. **JIRA Analysis**: Fetch and parse JIRA issue details:
|
||||
- Use curl to fetch JIRA issue data: `curl -s "https://issues.redhat.com/rest/api/2/issue/{$1}"`
|
||||
- Parse JSON response to extract:
|
||||
- Issue summary and description
|
||||
- Context and acceptance criteria
|
||||
- Steps to reproduce (for bugs)
|
||||
- Expected vs actual behavior
|
||||
- Extract issue type (Story, Bug, Task, etc.)
|
||||
|
||||
2. **PR Discovery**: Get list of PRs to analyze:
|
||||
- **If no PRs provided in arguments** ($2, $3, etc. are empty):
|
||||
- Use WebFetch on https://issues.redhat.com/browse/{$1}
|
||||
- Extract all GitHub PR links from:
|
||||
- "Issue Links" section
|
||||
- "Development" section
|
||||
- PR links in comments
|
||||
- **If PRs provided in arguments**:
|
||||
- Use only the PRs provided in $2, $3, $4, etc.
|
||||
- Ignore any other PRs linked to the JIRA
|
||||
|
||||
3. **PR Analysis**: For each PR, fetch and analyze:
|
||||
- Use `gh pr view {PR_NUMBER} --repo <your repo> --json title,body,commits,files,labels`
|
||||
- Extract:
|
||||
- PR title and description
|
||||
- Changed files and their diffs
|
||||
- Commit messages
|
||||
- PR status (merged, open, closed)
|
||||
- Read changed files to understand implementation details
|
||||
- Use Grep and Glob tools to:
|
||||
- Find related test files
|
||||
- Locate configuration or documentation
|
||||
- Identify dependencies
|
||||
|
||||
4. **Change Analysis**: Understand what was changed across all PRs:
|
||||
- Identify the overall objective (bug fix, feature, refactor)
|
||||
- Determine affected components (API, CLI, operator, control-plane, etc.)
|
||||
- Find platform-specific changes (AWS, Azure, KubeVirt, etc.)
|
||||
- Map which PR addresses which aspect of the JIRA
|
||||
- Identify any dependencies between PRs
|
||||
|
||||
5. **Test Scenario Generation**: Create comprehensive test plan:
|
||||
- Map JIRA acceptance criteria to test scenarios
|
||||
- For bugs: Use reproduction steps as test cases
|
||||
- Generate test scenarios covering:
|
||||
- Happy path scenarios (based on acceptance criteria)
|
||||
- Edge cases and error handling
|
||||
- Platform-specific variations if applicable
|
||||
- Regression scenarios
|
||||
- For multiple PRs:
|
||||
- Create integrated test scenarios
|
||||
- Verify PRs work correctly together
|
||||
- Test each PR's contribution to the overall solution
|
||||
|
||||
6. **Test Guide Creation**: Generate detailed manual testing document:
|
||||
- **Filename**: Always use JIRA key format: `test-{JIRA_KEY}.md`
|
||||
- Convert JIRA key to lowercase
|
||||
- Examples: `test-cntrlplane-205.md`, `test-ocpbugs-12345.md`
|
||||
- **Structure**:
|
||||
- **JIRA Summary**: Include JIRA key, title, description, acceptance criteria
|
||||
- **PR Summary**: List all PRs with titles and how they relate to the JIRA
|
||||
- **Prerequisites**:
|
||||
- Required infrastructure and tools
|
||||
- Environment setup requirements
|
||||
- Access requirements
|
||||
- **Test Scenarios**:
|
||||
- Map each test to JIRA acceptance criteria
|
||||
- Numbered test cases with clear steps
|
||||
- Expected results with verification commands
|
||||
- Platform-specific test variations
|
||||
- **Regression Testing**:
|
||||
- Related features to verify
|
||||
- Areas that might be affected
|
||||
- **Success Criteria**:
|
||||
- Checklist mapping to JIRA acceptance criteria
|
||||
- **Troubleshooting**:
|
||||
- Common issues and debug steps
|
||||
- **Notes**:
|
||||
- Known limitations
|
||||
- Links to JIRA and all PRs
|
||||
- Critical test cases highlighted
|
||||
|
||||
7. **Exclusions**: Apply smart filtering:
|
||||
- **Skip PRs that don't require testing**:
|
||||
- PRs that only add documentation (.md files only)
|
||||
- PRs that only add CI/tooling (.github/, .claude/ directories)
|
||||
- PRs marked with labels like "skip-testing" or "docs-only"
|
||||
- **Note skipped PRs** in the test guide with reasoning
|
||||
- Focus test scenarios on PRs with actual code changes
|
||||
|
||||
8. **Output**: Display the testing guide:
|
||||
- Show the file path where the guide was saved
|
||||
- Provide a summary of:
|
||||
- JIRA issue being tested
|
||||
- Number of PRs included
|
||||
- Number of test scenarios generated
|
||||
- Critical test cases to focus on
|
||||
- Highlight any PRs that were skipped and why
|
||||
- Ask if the user would like any modifications to the test guide
|
||||
|
||||
## Examples:
|
||||
|
||||
1. **Generate test steps for JIRA with auto-discovered PRs**:
|
||||
`/jira:generate-test-plan CNTRLPLANE-205`
|
||||
|
||||
2. **Generate test steps for JIRA with specific PRs only**:
|
||||
`/jira:generate-test-plan CNTRLPLANE-205 https://github.com/openshift/hypershift/pull/6888`
|
||||
|
||||
3. **Generate test steps for multiple specific PRs**:
|
||||
`/jira:generate-test-plan CNTRLPLANE-205 https://github.com/openshift/hypershift/pull/6888 https://github.com/openshift/hypershift/pull/6889`
|
||||
|
||||
## Arguments:
|
||||
|
||||
- **$1**: JIRA issue key (required) - e.g., CNTRLPLANE-205, OCPBUGS-12345
|
||||
- **$2, $3, ..., $N**: Optional GitHub PR URLs
|
||||
- If provided: Only these PRs will be analyzed
|
||||
- If omitted: All PRs linked to the JIRA will be discovered and analyzed
|
||||
|
||||
## Smart Features:
|
||||
|
||||
1. **Automatic PR Discovery**:
|
||||
- Scans JIRA issue for all related PRs
|
||||
- Identifies PRs in "Issue Links", "Development" section, and comments
|
||||
|
||||
2. **Selective PR Testing**:
|
||||
- Allows manual override to test specific PRs only
|
||||
- Useful when JIRA has many PRs but only some need testing
|
||||
|
||||
3. **Context-Aware Test Generation**:
|
||||
- Bug fixes: Focus on reproduction steps and verification
|
||||
- Features: Focus on acceptance criteria and user workflows
|
||||
- Refactors: Focus on regression and functional equivalence
|
||||
|
||||
4. **Multi-PR Integration**:
|
||||
- Understands how multiple PRs work together
|
||||
- Creates integration test scenarios
|
||||
- Identifies dependencies and testing order
|
||||
|
||||
5. **Build/Deploy Section Exclusion**:
|
||||
- Does NOT include build or deployment steps
|
||||
- Assumes environment is already set up
|
||||
- Focuses purely on testing procedures
|
||||
|
||||
6. **Cleanup Section Exclusion**:
|
||||
- Does NOT include cleanup steps
|
||||
- Focuses on test execution and verification
|
||||
|
||||
## Example Workflow:
|
||||
|
||||
```bash
|
||||
# Auto-discover all PRs from JIRA
|
||||
/jira:generate-test-plan CNTRLPLANE-205
|
||||
|
||||
# Test only specific PRs
|
||||
/jira:generate-test-plan CNTRLPLANE-205 https://github.com/openshift/hypershift/pull/6888
|
||||
|
||||
# Test multiple specific PRs
|
||||
/jira:generate-test-plan OCPBUGS-12345 https://github.com/openshift/hypershift/pull/1234 https://github.com/openshift/hypershift/pull/1235
|
||||
```
|
||||
|
||||
The command will provide a comprehensive manual testing guide that QE or developers can use to thoroughly test the JIRA issue implementation.
|
||||
200
commands/grooming.md
Normal file
200
commands/grooming.md
Normal file
@@ -0,0 +1,200 @@
|
||||
---
|
||||
description: Analyze new bugs and cards added over a time period and generate grooming meeting agenda
|
||||
argument-hint: [project-filter] [time-period] [--component component-name] [--label label-name] [--type issue-type]
|
||||
---
|
||||
|
||||
## Name
|
||||
jira:grooming
|
||||
|
||||
## Synopsis
|
||||
```
|
||||
/jira:grooming [project-filter] [time-period] [--component component-name] [--label label-name] [--type issue-type]
|
||||
```
|
||||
|
||||
## Description
|
||||
The `jira:grooming` command helps teams prepare for backlog grooming meetings. It automatically collects bugs and user stories created within a specified time period OR assigned to a specific sprint, analyzes their priority, complexity, and dependencies, and generates structured grooming meeting agendas.
|
||||
|
||||
This command is particularly useful for:
|
||||
- Backlog organization before sprint planning
|
||||
- Sprint-specific grooming sessions
|
||||
- Regular requirement grooming meetings
|
||||
- Priority assessment of new bugs
|
||||
- Technical debt organization and planning
|
||||
|
||||
## Key Features
|
||||
|
||||
- **Automated Data Collection** – Collect and categorize issues within specified time periods or sprints by type (Bug, Story, Task, Epic), extract key information (priority, components, labels), and identify unassigned or incomplete issues.
|
||||
|
||||
- **Intelligent Analysis** – Evaluate issue complexity based on historical data, identify related or duplicate issues, analyze business value and technical impact, and detect potential dependencies.
|
||||
|
||||
- **Agenda Generation** – Build a structured, actionable meeting outline organized by priority and type, with discussion points, decision recommendations, estimation references, and risk alerts.
|
||||
|
||||
## Implementation
|
||||
|
||||
The `jira:grooming` command runs in three main phases:
|
||||
|
||||
### 🧩 Phase 1: Data Collection
|
||||
- Automatically queries JIRA for issues based on the provided time range or sprint name:
|
||||
- **Time range mode**: Filters issues by creation date within the specified period (e.g., `last-week`, `2024-01-01:2024-01-31`)
|
||||
- **Sprint mode**: Filters issues by JIRA Sprint without time constraints (e.g., `"OTA 277"`)
|
||||
- Sprint detection: If the time-period parameter doesn't match known time range formats, it's treated as a sprint name
|
||||
- Supports complex JQL filters, including multi-project, component-based, label-based, and issue-type queries.
|
||||
- Extracts key fields such as title, type, priority, component, reporter, and assignee.
|
||||
- Detects related or duplicate issues to provide better context.
|
||||
|
||||
### 🧠 Phase 2: Analysis & Processing
|
||||
- Groups collected issues by type and priority (e.g., Critical Bugs, High Priority Stories).
|
||||
- Identifies incomplete or unclear issues that need clarification.
|
||||
- Estimates complexity and effort based on similar historical data.
|
||||
- Highlights risks, dependencies, and recommended next actions.
|
||||
|
||||
### 📋 Phase 3: Report Generation
|
||||
- Automatically generates a **structured grooming meeting agenda** in Markdown format.
|
||||
- Includes discussion points, decision checklists, and action items.
|
||||
- Output can be copied directly into Confluence or shared with the team.
|
||||
|
||||
## Usage Examples
|
||||
|
||||
1. **Single project weekly review**:
|
||||
```
|
||||
/jira:grooming OCPSTRAT last-week
|
||||
```
|
||||
|
||||
2. **Multiple OpenShift projects**:
|
||||
```
|
||||
/jira:grooming "OCPSTRAT,OCPBUGS,HOSTEDCP" last-2-weeks
|
||||
```
|
||||
|
||||
3. **Filter by component**:
|
||||
```
|
||||
/jira:grooming OCPSTRAT last-week --component "Control Plane"
|
||||
```
|
||||
|
||||
4. **Custom date range**:
|
||||
```
|
||||
/jira:grooming OCPBUGS 2024-10-01:2024-10-15
|
||||
```
|
||||
|
||||
5. **Filter by label**:
|
||||
```
|
||||
/jira:grooming OCPSTRAT last-week --label "technical-debt"
|
||||
```
|
||||
|
||||
6. **Combine component and label filters**:
|
||||
```
|
||||
/jira:grooming OCPSTRAT last-week --component "Control Plane" --label "performance"
|
||||
```
|
||||
|
||||
7. **Query sprint issues with component filter**:
|
||||
```bash
|
||||
/jira:grooming OCPBUGS "OTA 277" --component "Cluster Version Operator"
|
||||
```
|
||||
|
||||
8. **Filter by issue type**:
|
||||
```
|
||||
/jira:grooming OCPSTRAT last-week --type Bug
|
||||
```
|
||||
|
||||
9. **Filter by multiple issue types**:
|
||||
```
|
||||
/jira:grooming OCPSTRAT last-week --type "Bug,Epic"
|
||||
```
|
||||
|
||||
10. **Combine all filters**:
|
||||
```
|
||||
/jira:grooming OCPSTRAT last-week --component "Control Plane" --label "performance" --type Story
|
||||
```
|
||||
|
||||
## Output Format
|
||||
|
||||
### Grooming Meeting Agenda
|
||||
|
||||
The command outputs a ready-to-use Markdown document that can be copied into Confluence or shared with your team.
|
||||
|
||||
```markdown
|
||||
# Backlog Grooming Agenda
|
||||
**Project**: [project-key] | **Period**: [time-period] | **New Issues**: [count]
|
||||
|
||||
## 🚨 Critical Issues ([count])
|
||||
- **[PROJ-1234]** System crashes on login - *Critical, needs immediate attention*
|
||||
- **[PROJ-1235]** Performance degradation - *High, assign to team lead*
|
||||
|
||||
## 📈 High Priority Stories ([count])
|
||||
- **[PROJ-1236]** User profile enhancement - *Ready for sprint*
|
||||
- **[PROJ-1237]** Payment integration - *Needs design review*
|
||||
|
||||
## 📝 Needs Clarification ([count])
|
||||
- **[PROJ-1238]** Missing acceptance criteria
|
||||
- **[PROJ-1239]** Unclear technical requirements
|
||||
|
||||
## 📋 Action Items
|
||||
- [ ] Assign PROJ-1234 to senior developer (immediate)
|
||||
- [ ] Schedule design review for PROJ-1237 (this week)
|
||||
- [ ] Clarify requirements for PROJ-1238,1239 (before next grooming)
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Default Query Configuration (.jira-grooming.json)
|
||||
```json
|
||||
{
|
||||
"defaultProjects": ["OCPSTRAT", "OCPBUGS"],
|
||||
"defaultLabels": [],
|
||||
"priorityMapping": {
|
||||
"Critical": "🚨 Critical",
|
||||
"High": "📈 High Priority"
|
||||
},
|
||||
"estimationReference": {
|
||||
"enableHistoricalComparison": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Arguments
|
||||
|
||||
- **$1 – project-filter**
|
||||
JIRA project selector. Supports single or multiple projects (comma-separated).
|
||||
Examples:
|
||||
- `OCPSTRAT`
|
||||
- `"OCPSTRAT,OCPBUGS,HOSTEDCP"`
|
||||
- `"OpenShift Virtualization,Red Hat OpenShift Control Planes"`
|
||||
Default: read from configuration file
|
||||
|
||||
- **$2 – time-period**
|
||||
Time range for issue collection OR sprint name.
|
||||
Options:
|
||||
- Time ranges: `last-week` | `last-2-weeks` | `last-month` | `YYYY-MM-DD:YYYY-MM-DD`
|
||||
- Sprint name: Any string that doesn't match time range formats (e.g., `"OTA 277"`)
|
||||
Default: `last-week`
|
||||
|
||||
**Behavior:**
|
||||
- If a time range is provided, filters issues by creation date within that range
|
||||
- If a sprint name is provided, filters issues by JIRA Sprint WITHOUT applying time range constraints
|
||||
|
||||
- **--component** *(optional)*
|
||||
Filter by JIRA component (single or comma-separated).
|
||||
Examples:
|
||||
- `--component "Networking"`
|
||||
- `--component "Control Plane,Storage"`
|
||||
|
||||
- **--label** *(optional)*
|
||||
Filter by JIRA labels (single or comma-separated).
|
||||
Examples:
|
||||
- `--label "technical-debt"`
|
||||
- `--label "performance,security"`
|
||||
|
||||
- **--type** *(optional)*
|
||||
Filter by JIRA issue type (single or comma-separated).
|
||||
Examples:
|
||||
- `--type Bug`
|
||||
- `--type "Epic,Story"`
|
||||
- `--type "Bug,Task,Feature"`
|
||||
|
||||
Common issue types: `Bug`, `Story`, `Task`, `Epic`, `Feature`, `Sub-task`
|
||||
|
||||
## Return Value
|
||||
- **Markdown Report**: Ready-to-use grooming agenda with categorized issues and action items
|
||||
|
||||
## See Also
|
||||
- `jira:status-rollup` - Status rollup reports
|
||||
- `jira:solve` - Issue solution generation
|
||||
133
commands/solve.md
Normal file
133
commands/solve.md
Normal file
@@ -0,0 +1,133 @@
|
||||
---
|
||||
description: Analyze a JIRA issue and create a pull request to solve it.
|
||||
---
|
||||
|
||||
## Name
|
||||
jira:solve
|
||||
|
||||
## Synopsis
|
||||
```
|
||||
/jira:solve <jira-issue-id> [remote]
|
||||
```
|
||||
|
||||
## Description
|
||||
|
||||
The `jira:solve` command analyzes a JIRA issue and creates a pull request to solve it.
|
||||
|
||||
This command takes a JIRA URL, fetches the issue description and requirements, analyzes the codebase to understand how to implement the solution, and creates a comprehensive pull request with the necessary changes.
|
||||
|
||||
**Usage Examples:**
|
||||
|
||||
1. **Solve a specific JIRA issue**:
|
||||
```
|
||||
/jira:solve OCPBUGS-12345 origin
|
||||
```
|
||||
|
||||
## Implementation
|
||||
|
||||
- The command uses curl to fetch JIRA data via REST API: https://issues.redhat.com/rest/api/2/issue/{$1}
|
||||
- Parses JSON response using jq or text processing
|
||||
- Extracts key fields: summary, description, components, labels
|
||||
- No authentication required for public Red Hat JIRA issues
|
||||
- Creates a PR with the solution
|
||||
|
||||
### Process Flow
|
||||
|
||||
1. **Issue Analysis**: Parse JIRA URL and fetch issue details:
|
||||
- Use curl to fetch JIRA issue data: curl -s "https://issues.redhat.com/rest/api/2/issue/{$1}"
|
||||
- Parse JSON response to extract:
|
||||
- Issue summary and description
|
||||
- From within the description expect the following sections
|
||||
- Required
|
||||
- Context
|
||||
- Acceptance criteria
|
||||
- Optional
|
||||
- Steps to reproduce (for bugs)
|
||||
- Expected vs actual behavior
|
||||
- Ask the user for further issue grooming if the requried sections are missing
|
||||
|
||||
2. **Codebase Analysis**: Search and analyze relevant code:
|
||||
- Find related files and functions
|
||||
- Understand current implementation
|
||||
- Identify areas that need changes
|
||||
- Use Grep and Glob tools to search for:
|
||||
- Related function names mentioned in JIRA
|
||||
- File patterns related to the component
|
||||
- Similar existing implementations
|
||||
- Test files that need updates
|
||||
|
||||
3. **Solution Implementation**:
|
||||
- Think hard and create a detailed, step-by-step plan to implement this feature. Save it to spec-$1.md within the .work/jira/solve folder, for example .work/jira/solve/spec-OCPBUGS-12345.md
|
||||
- Always ask the user to review the plan and give them the choice to modify it before start the implementation
|
||||
- Implement the plan:
|
||||
- Make necessary code changes using Edit/MultiEdit tools
|
||||
- Follow existing code patterns and conventions
|
||||
- Add or update tests as needed
|
||||
- Update documentation if needed within the docs/ folder
|
||||
- If the problem is too complex consider delegating to one of the SME agents.
|
||||
- Ensure godoc comments are generated for any newly created public functions
|
||||
- Use your best judgement if godoc comments are needed for private functions
|
||||
- For example, a comment should not be generated for a simple function like func add(int a, b) int { return a + b}
|
||||
- Create unit tests for any newly created functions
|
||||
- After making code changes, verify the implementation based on the repository's tooling:
|
||||
- **Check for Makefile**: Run `ls Makefile` to see if one exists
|
||||
- **If Makefile exists**: Check available targets with `make help` or `grep '^[^#]*:' Makefile | head -20`
|
||||
- **Run appropriate verification commands**:
|
||||
- If `make lint-fix` exists: Run it to ensure imports are properly sorted and linting issues are fixed
|
||||
- If `make verify`, `make build`, `make test` exist: Run these to ensure code builds and passes tests
|
||||
- If no Makefile or make targets: Look for alternative commands:
|
||||
- Go projects: `go fmt ./...`, `go vet ./...`, `go test ./...`, `go build ./...`
|
||||
- Node.js: `npm test`, `npm run build`, `npm run lint`
|
||||
- Python: `pytest`, `python -m unittest`, `pylint`, `black .`
|
||||
- Other: Follow repository conventions in CI config files (.github/workflows/, .gitlab-ci.yml, etc.)
|
||||
- **Never assume make targets exist** - always verify first
|
||||
- **You must ensure verification passes** before proceeding to "Commit Creation"
|
||||
|
||||
4. **Commit Creation**:
|
||||
- Create feature branch using the jira-key $1 as the branch name. For example: "git checkout -b fix-{jira-key}"
|
||||
- Break commits into logical components based on the nature of the changes
|
||||
- Each commit should honor https://www.conventionalcommits.org/en/v1.0.0/ and always include a commit message body articulating the "why"
|
||||
- Use your judgment to organize commits in a way that makes them easy to review and understand
|
||||
- Common logical groupings (use as guidance, not rigid rules):
|
||||
- API changes: Changes in `api/` directory (types, CRDs)
|
||||
- Example: `git commit -m"feat(api): Update HostedCluster API for X" -m"Add new fields to support Y functionality"`
|
||||
- Vendor changes: Dependency updates in `vendor/` directory
|
||||
- Example: `git commit -m"chore(vendor): Update dependencies for X" -m"Required to pick up bug fixes in upstream library Y"`
|
||||
- Generated code: Auto-generated clients, informers, listers, and CRDs
|
||||
- Example: `git commit -m"chore(generated): Regenerate clients and CRDs" -m"Regenerate after API changes to ensure client code is in sync"`
|
||||
- CLI changes: User-facing command changes in `cmd/` directory
|
||||
- Example: `git commit -m"feat(cli): Add support for X flag" -m"This allows users to configure Y behavior at cluster creation time"`
|
||||
- Operator changes: Controller logic in `operator/` or `controllers/`
|
||||
- Example: `git commit -m"feat(operator): Implement X controller logic" -m"Without this the controller won't reconcile when Y condition occurs"`
|
||||
- Support/utilities: Shared code in `support/` directory
|
||||
- Example: `git commit -m"refactor(support): Extract common X utility" -m"Consolidate duplicated logic from multiple controllers into shared helper"`
|
||||
- Tests: Test additions or modifications
|
||||
- Example: `git commit -m"test: Add tests for X functionality" -m"Ensure the new behavior is covered by unit tests to prevent regressions"`
|
||||
- Documentation: Changes in `docs/` directory
|
||||
- Example: `git commit -m"docs: Document X feature" -m"Help users understand how to configure and use the new capability"`
|
||||
|
||||
5. **PR Creation**:
|
||||
- Push the branch with all commits against the remote specified in argument $2
|
||||
- Create pull request with:
|
||||
- Clear title referencing JIRA issue as a prefix. For example: "OCPBUGS-12345: ..."
|
||||
- The PR description should satisfy the template within .github/PULL_REQUEST_TEMPLATE.md if the file exists
|
||||
- The "🤖 Generated with Claude Code" sentence should include a reference to the slash command that triggered the execution, for example "via `/jira-solve OCPBUGS-12345 enxebre`"
|
||||
- Always create as draft PR
|
||||
- Always create the PR against the remote origin
|
||||
- Use gh cli if you need to
|
||||
|
||||
6. **PR Description Review**:
|
||||
- After creating the PR, display the PR URL and description to the user
|
||||
- Ask the user: "Please review the PR description. Would you like me to update it? (yes/no)"
|
||||
- If the user says yes or requests changes:
|
||||
- Ask what changes they'd like to make
|
||||
- Update the PR description using `gh pr edit {PR_NUMBER} --body "{new_description}"`
|
||||
- Repeat this review step until the user is satisfied
|
||||
- If the user says no or is satisfied, acknowledge and provide next steps
|
||||
|
||||
|
||||
## Arguments:
|
||||
- $1: The JIRA issue to solve (required)
|
||||
- $2: The remote repository to push the branch. Defaults to "origin".
|
||||
|
||||
The command will provide progress updates and create a comprehensive solution addressing all requirements from the JIRA issue.
|
||||
203
commands/status-rollup.md
Normal file
203
commands/status-rollup.md
Normal file
@@ -0,0 +1,203 @@
|
||||
---
|
||||
description: Generate a status rollup comment for any JIRA issue based on all child issues and a given date range
|
||||
argument-hint: issue-id [--start-date YYYY-MM-DD] [--end-date YYYY-MM-DD]
|
||||
---
|
||||
|
||||
## Name
|
||||
jira:status-rollup
|
||||
|
||||
## Synopsis
|
||||
```
|
||||
/jira:status-rollup issue-id [--start-date YYYY-MM-DD] [--end-date YYYY-MM-DD]
|
||||
```
|
||||
|
||||
## Description
|
||||
The `jira:status-rollup` command generates a comprehensive status rollup for any JIRA issue (Feature, Epic, Story, etc.) by recursively analyzing all child issues and their activity within a specified date range. The command intelligently extracts insights from changelogs and comments to create a concise, well-formatted status summary that can be reviewed and refined before being posted to Jira.
|
||||
|
||||
This command is particularly useful for:
|
||||
- Weekly status updates on Features or Epics
|
||||
- Sprint retrospectives and planning
|
||||
- Executive summaries of complex work hierarchies
|
||||
- Identifying blockers and risks across multiple issues
|
||||
|
||||
Key capabilities:
|
||||
- Recursively traverses entire issue hierarchies (any depth)
|
||||
- Analyzes status transitions, assignee changes, and priority shifts
|
||||
- Extracts blockers, risks, and completion insights from comments
|
||||
- Generates properly formatted Jira wiki markup with nested bullets
|
||||
- Caches all data in a temp file for fast iterative refinement
|
||||
- Allows review and modification before posting to Jira
|
||||
|
||||
[Extended thinking: This command takes any JIRA issue ID (Feature, Epic, Story, etc.) and optional date range, recursively collects all descendant issues, analyzes their changes and comments within the date range, and generates a concise status summary rolled up to the parent issue level. The summary is presented to the user for review and refinement before being posted as a comment.]
|
||||
|
||||
## Implementation
|
||||
|
||||
The command executes the following workflow:
|
||||
|
||||
1. **Parse Arguments and Validate**
|
||||
- Extract issue ID from $1
|
||||
- Parse --start-date and --end-date if provided
|
||||
- Validate date format (YYYY-MM-DD)
|
||||
- Default to issue creation date if no start-date provided
|
||||
- Default to today if no end-date provided
|
||||
|
||||
2. **Issue Validation**
|
||||
- Use `mcp__atlassian__jira_get_issue` to fetch the issue
|
||||
- Verify the issue exists and is accessible
|
||||
- Extract issue key, summary, type, and basic info
|
||||
- Works with any issue type (Feature, Epic, Story, Task, etc.)
|
||||
|
||||
3. **Data Collection - Build Issue Hierarchy**
|
||||
- Find direct children using JQL: `parent = {issue-id}`
|
||||
- Recursively find all descendant issues (any depth)
|
||||
- Fetch detailed issue data for each issue (status, summary, assignee, etc.)
|
||||
- Use `mcp__atlassian__jira_batch_get_changelogs` for all issue keys
|
||||
- Filter changelog entries to date range (status transitions, assignee changes, etc.)
|
||||
- Fetch comments using `expand=renderedFields`, filter by date range
|
||||
- Save all data to temp file: `/tmp/jira-rollup-{issue-id}-{timestamp}.md`
|
||||
|
||||
4. **Data Analysis - Derive Status**
|
||||
- Calculate completion metrics (total, done, in-progress, blocked, percentage)
|
||||
- Identify issues completed/started/blocked within date range
|
||||
- Extract significant status transitions and key changes
|
||||
- Analyze comments for keywords:
|
||||
- **Blockers**: "blocked", "waiting on", "stuck", "dependency"
|
||||
- **Risks**: "risk", "concern", "problem", "at risk"
|
||||
- **Completion**: "completed", "done", "merged", "delivered"
|
||||
- **Progress**: "started", "working on", "implementing"
|
||||
- **Help needed**: "need", "require", "help", "support"
|
||||
- Extract entities: team mentions, dependencies, PR references, deadlines
|
||||
- Prioritize comments (high/medium/low based on keywords)
|
||||
- Cross-reference comments with status transitions
|
||||
- Assess overall health (on track, at risk, blocked, complete)
|
||||
- Append analysis results to temp file
|
||||
|
||||
5. **Generate Status Summary**
|
||||
- Read from temp file (NO re-fetching from Jira)
|
||||
- Create formatted summary in Jira wiki markup:
|
||||
```
|
||||
h2. Status Rollup From: {start-date} to {end-date}
|
||||
|
||||
*Overall Status:* [Clear statement about health and progress]
|
||||
|
||||
*This Week:*
|
||||
* Completed:
|
||||
*# [ISSUE-ID] - [Specific achievement from comments]
|
||||
*# [ISSUE-ID] - [Specific achievement from comments]
|
||||
* In Progress:
|
||||
*# [ISSUE-ID] - [Current state and specific details]
|
||||
* Blocked:
|
||||
*# [ISSUE-ID] - [Specific reason for blocker]
|
||||
|
||||
*Next Week:*
|
||||
* [Planned item based on analysis]
|
||||
|
||||
*Metrics:* X/Y issues complete (Z%)
|
||||
```
|
||||
- Use specific insights from comments (NOT vague phrases like "ongoing work")
|
||||
- Include PR references, ticket numbers, specific tasks mentioned
|
||||
- Add direct quotes when they provide critical context
|
||||
- Use `*#` syntax for nested bullets (Jira wiki markup)
|
||||
|
||||
6. **Present to User for Review**
|
||||
- Display temp file location for verification
|
||||
- Show generated summary
|
||||
- Ask if user wants changes
|
||||
|
||||
7. **Iterative Refinement**
|
||||
- If user requests changes, read from temp file (don't re-fetch)
|
||||
- Support refinement strategies:
|
||||
- Focus more on blockers/risks/completion
|
||||
- Add/remove technical details or quotes
|
||||
- Change grouping (by epic, type, status, assignee)
|
||||
- Adjust level of detail (high-level vs. detailed)
|
||||
- Regenerate only affected sections
|
||||
- Repeat until user satisfied
|
||||
|
||||
8. **Post Comment to Issue**
|
||||
- Use `mcp__atlassian__jira_add_comment` to post to parent issue
|
||||
- Append footer: "🤖 Generated with [Claude Code](https://claude.com/claude-code) via `/jira:status-rollup {issue-id} --start-date {date} --end-date {date}`"
|
||||
- Confirm with user and provide issue URL
|
||||
|
||||
9. **Temp File Cleanup**
|
||||
- Ask user if they want to keep `/tmp/jira-rollup-{issue-id}-{timestamp}.md`
|
||||
- Delete if user says no, otherwise keep for reference
|
||||
|
||||
**Error Handling:**
|
||||
- Invalid issue ID: Display error with verification instructions
|
||||
- No child issues: Offer to generate summary for single issue
|
||||
- No activity in date range: Generate summary based on current state
|
||||
- Invalid date format: Display error with correct format example
|
||||
- Large hierarchies (100+ issues): Show progress indicators
|
||||
|
||||
**Performance Considerations:**
|
||||
- Use batch API endpoints where available
|
||||
- Implement appropriate delays to respect rate limits
|
||||
- Cache all data in temp file for instant refinement
|
||||
|
||||
## Return Value
|
||||
- **Posted to Jira**: Formatted status comment on the parent issue
|
||||
- **Temp file**: `/tmp/jira-rollup-{issue-id}-{timestamp}.md` containing:
|
||||
- Parent issue details
|
||||
- Complete issue hierarchy with counts by type
|
||||
- Raw changelog data for all issues
|
||||
- All comments with metadata (author, date, issue key)
|
||||
- Comment analysis (keywords, priorities, cross-references)
|
||||
- Metrics summary
|
||||
|
||||
## Examples
|
||||
|
||||
1. **Generate status for a Feature for a specific week**:
|
||||
```
|
||||
/jira:status-rollup FEATURE-123 --start-date 2025-01-06 --end-date 2025-01-13
|
||||
```
|
||||
Output: Weekly status comment posted to FEATURE-123
|
||||
|
||||
2. **Generate status for an Epic**:
|
||||
```
|
||||
/jira:status-rollup EPIC-456 --start-date 2025-01-06 --end-date 2025-01-13
|
||||
```
|
||||
Output: Epic status summary with all child stories analyzed
|
||||
|
||||
3. **Generate status for a Story with subtasks**:
|
||||
```
|
||||
/jira:status-rollup STORY-789
|
||||
```
|
||||
Output: Status from story creation date to today
|
||||
|
||||
4. **Generate status from a start date to now**:
|
||||
```
|
||||
/jira:status-rollup CNTRLPLANE-1234 --start-date 2025-01-06
|
||||
```
|
||||
Output: Status from Jan 6 to today
|
||||
|
||||
**Example Output:**
|
||||
```
|
||||
h2. Weekly Status: 2025-01-06 to 2025-01-13
|
||||
|
||||
*Overall Status:* Feature is on track. Core authentication work completed this week with 2 PRs merged. UI integration starting with design approved.
|
||||
|
||||
*This Week:*
|
||||
* Completed:
|
||||
*# AUTH-101 - OAuth2 implementation (PR #456 merged, all review feedback addressed)
|
||||
*# AUTH-102 - OAuth2 token validation (unit tests added, edge cases handled)
|
||||
* In Progress:
|
||||
*# UI-201 - Login UI components (design review completed, implementing responsive layout for mobile)
|
||||
*# AUTH-103 - Session handling (refactoring cookie storage mechanism, PR in draft)
|
||||
* Blocked:
|
||||
*# AUTH-104 - Azure AD integration (blocked on subscription approval, escalated to infrastructure team). Per Jane Doe: "Need Azure subscription approved before proceeding - submitted ticket #12345"
|
||||
|
||||
*Next Week:*
|
||||
* Complete session handling refactor (AUTH-103) and submit for review
|
||||
* Finish login UI responsive implementation (UI-201) once design assets are finalized
|
||||
* Begin end-to-end testing (AUTH-107) if session handling is merged
|
||||
|
||||
*Metrics:* 8/15 issues complete (53%)
|
||||
|
||||
🤖 Generated with [Claude Code](https://claude.com/claude-code) via `/jira:status-rollup FEATURE-123 --start-date 2025-01-06 --end-date 2025-01-13`
|
||||
```
|
||||
|
||||
## Arguments
|
||||
- `issue-id` (required): The JIRA issue ID to analyze (e.g., FEATURE-123, EPIC-456, STORY-789, CNTRLPLANE-1234)
|
||||
- `--start-date` (optional): Start date in YYYY-MM-DD format. Defaults to issue creation date if not provided
|
||||
- `--end-date` (optional): End date in YYYY-MM-DD format. Defaults to today if not provided
|
||||
197
commands/validate-blockers.md
Normal file
197
commands/validate-blockers.md
Normal file
@@ -0,0 +1,197 @@
|
||||
---
|
||||
description: Validate proposed release blockers using Red Hat OpenShift release blocker criteria
|
||||
argument-hint: [target-version] [component-filter] [--bug issue-key]
|
||||
---
|
||||
|
||||
## Name
|
||||
jira:validate-blockers
|
||||
|
||||
## Synopsis
|
||||
```
|
||||
/jira:validate-blockers [target-version] [component-filter] [--bug issue-key]
|
||||
```
|
||||
|
||||
**Note**: `target-version` is required unless `--bug` is provided.
|
||||
|
||||
## Description
|
||||
The `jira:validate-blockers` command helps release managers make data-driven decisions on proposed release blockers. It analyzes bugs with "Release Blocker = Proposed" status using Red Hat OpenShift release blocker criteria and provides clear APPROVE/REJECT/DISCUSS recommendations with detailed justification.
|
||||
|
||||
This command is essential for:
|
||||
- Validating proposed release blockers
|
||||
- Making blocker approval/rejection decisions
|
||||
- Understanding why a bug should or shouldn't block a release
|
||||
- Reviewing blocker criteria compliance
|
||||
|
||||
## Key Features
|
||||
|
||||
- **Proposed Blocker Focus** – Automatically filters for bugs with Release Blocker = Proposed
|
||||
- **Red Hat OpenShift Release Blocker Criteria** – Analyzes against documented blocker criteria
|
||||
- **Clear Recommendations** – Provides APPROVE, REJECT, or DISCUSS recommendations
|
||||
- **Detailed Justification** – Shows which criteria matched and analysis rationale
|
||||
- **Component Filtering** – Scope validation to specific components
|
||||
|
||||
## Implementation
|
||||
|
||||
For detailed implementation guidance including JQL queries, scoring algorithms, and decision logic, see the [jira-validate-blockers skill](../skills/jira-validate-blockers/SKILL.md).
|
||||
|
||||
### High-Level Workflow
|
||||
|
||||
1. **Parse Arguments and Build Filters** – Extract arguments (target version, component filter, bug ID). Build JQL query for:
|
||||
- **Single bug mode** (if --bug provided): Query specific bug by issue key (version not required)
|
||||
- **Component + version mode** (if both provided): Query proposed blockers matching target version and component, excluding already-fixed bugs (status not in Closed, Release Pending, Verified, ON_QA)
|
||||
- **Version only mode** (if version provided): Query all proposed blockers for target version, excluding already-fixed bugs
|
||||
- **Error**: If neither --bug nor version provided, show error message
|
||||
|
||||
2. **Query Proposed Blockers** – Use MCP tools to fetch bugs based on mode:
|
||||
- Single bug: Fetch one specific bug with all fields
|
||||
- Component + version: Fetch proposed blockers matching version and component filter, excluding already-fixed statuses
|
||||
- Version only: Fetch all proposed blockers for target version, excluding already-fixed statuses
|
||||
|
||||
3. **Analyze Each Blocker** – Apply Red Hat OpenShift release blocker criteria:
|
||||
- Strong blockers: Component Readiness regression, Service Delivery blocker, data loss, install/upgrade failures, service unavailability, regressions
|
||||
- Never blockers: Severity below Important, new features without regression
|
||||
- Workaround assessment: Check if acceptable workaround exists (idempotent, safe at scale, timely)
|
||||
|
||||
4. **Generate Recommendations** – Create report with APPROVE/REJECT/DISCUSS verdicts and justifications.
|
||||
|
||||
### Technical Details
|
||||
|
||||
The skill file provides complete details on:
|
||||
- JQL query construction for proposed blockers
|
||||
- Blocker scoring criteria and point values
|
||||
- Workaround assessment logic
|
||||
- Decision thresholds
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Version-Based Validation
|
||||
|
||||
1. **Validate all proposed blockers for a target version**:
|
||||
```
|
||||
/jira:validate-blockers 4.21
|
||||
```
|
||||
|
||||
### Component-Based Validation
|
||||
|
||||
2. **Validate blockers for a specific component and version**:
|
||||
```
|
||||
/jira:validate-blockers 4.21 "Hypershift"
|
||||
```
|
||||
|
||||
### Single Bug Validation
|
||||
|
||||
3. **Validate a specific proposed blocker (version not required)**:
|
||||
```
|
||||
/jira:validate-blockers --bug OCPBUGS-36846
|
||||
```
|
||||
|
||||
## Output Format
|
||||
|
||||
The command outputs a blocker validation report:
|
||||
|
||||
```markdown
|
||||
# 🚫 Release Blocker Validation Report
|
||||
**Components**: All | **Project**: OCPBUGS | **Proposed Blockers**: 5 | **Generated**: 2025-11-23
|
||||
|
||||
## Summary
|
||||
- ✅ **Recommend APPROVE**: 2
|
||||
- ❌ **Recommend REJECT**: 1
|
||||
- ⚠️ **Needs DISCUSSION**: 2
|
||||
|
||||
---
|
||||
|
||||
## Blocker Analysis
|
||||
|
||||
### OCPBUGS-12345: Cluster install fails on AWS ✅ APPROVE
|
||||
|
||||
**Recommendation**: APPROVE - This bug meets blocker criteria
|
||||
|
||||
**Criteria Matched**:
|
||||
- ✅ Install/upgrade failure
|
||||
- ✅ Affects all users
|
||||
- ✅ No acceptable workaround
|
||||
|
||||
**Justification**:
|
||||
Install failures are strong blockers. This bug prevents cluster installation on AWS, affecting all users attempting AWS deployments. No workaround exists.
|
||||
|
||||
**Suggested Action**: Approve as release blocker
|
||||
|
||||
---
|
||||
|
||||
### OCPBUGS-12346: UI button misaligned ❌ REJECT
|
||||
|
||||
**Recommendation**: REJECT - This bug does not meet blocker criteria
|
||||
|
||||
**Criteria Matched**:
|
||||
- ❌ Cosmetic/UI-only issue (not data loss/corruption/unavailability)
|
||||
- ❌ Severity: Low (must be Important or higher)
|
||||
|
||||
**Justification**:
|
||||
Bugs with severity below Important are never blockers. This is a cosmetic issue with no functional impact.
|
||||
|
||||
**Suggested Action**: Reject as release blocker, triage to appropriate sprint
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
1. Review APPROVE recommendations - add to blocker list
|
||||
2. Review REJECT recommendations - remove blocker status
|
||||
3. Discuss unclear cases in triage meeting
|
||||
```
|
||||
|
||||
## Arguments
|
||||
|
||||
**IMPORTANT**: Either `target-version` OR `--bug` must be provided. If neither is provided, the command will error out.
|
||||
|
||||
### Core Arguments
|
||||
|
||||
- **$1 – target-version** *(required unless --bug is provided)*
|
||||
Target release version to validate blockers for. Format: `X.Y` (e.g., `4.21`, `4.22`)
|
||||
|
||||
The implementation automatically:
|
||||
- Expands version to search for both `X.Y` and `X.Y.0` in Target Version, Target Backport Versions, and Affected Version fields
|
||||
- Excludes already-fixed bugs with status: Closed, Release Pending, Verified, ON_QA
|
||||
|
||||
Examples:
|
||||
- `4.21` - Validates active proposed blockers for 4.21
|
||||
- `4.22` - Validates active proposed blockers for 4.22
|
||||
|
||||
**Note**: Not required when `--bug` is provided.
|
||||
|
||||
- **$2 – component-filter** *(optional)*
|
||||
Component name(s) to filter proposed blockers. Supports single or multiple (comma-separated) components.
|
||||
|
||||
Examples:
|
||||
- `"Hypershift"` - Single component
|
||||
- `"Hypershift,Cluster Version Operator"` - Multiple components
|
||||
|
||||
**Note**: Ignored if `--bug` is provided. Requires `target-version` to be specified.
|
||||
|
||||
Default: All components for the target version
|
||||
|
||||
- **--bug** *(optional)*
|
||||
Validate a single specific bug by its JIRA issue key.
|
||||
|
||||
When provided, analyzes only this bug and ignores both target-version and component-filter.
|
||||
|
||||
Examples:
|
||||
- `--bug OCPBUGS-36846`
|
||||
|
||||
**Note**: When `--bug` is provided, target-version and component-filter are ignored.
|
||||
|
||||
Default: Not specified
|
||||
|
||||
## Return Value
|
||||
|
||||
- **Markdown Report**: Blocker validation report with recommendations
|
||||
- **Exit Code**:
|
||||
- `0` - Success
|
||||
- `1` - Error querying JIRA or analyzing bugs
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Jira MCP server must be configured (see [plugin README](../README.md))
|
||||
- MCP tools provide read-only access to JIRA APIs
|
||||
- No JIRA credentials required for read operations (public Red Hat JIRA issues)
|
||||
- Access to JIRA projects (OCPBUGS)
|
||||
- Permission to search and view issues in target projects
|
||||
Reference in New Issue
Block a user