-
Notifications
You must be signed in to change notification settings - Fork 53
Add Claude Code command for automated bug labeling through MCP JIRA server #168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: ricky-rav The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
WalkthroughAdds documentation for an automated JIRA bug-labeling workflow and MCP JIRA server configuration, and extends Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🧹 Recent nitpick comments
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro Cache: Disabled due to data retention organization setting Knowledge base: Disabled due to 📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (1)**⚙️ CodeRabbit configuration file
Files:
🔇 Additional comments (4)
✏️ Tip: You can disable this entire section by setting Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (5)
jira-scripts/README.md (2)
42-111: Clarify PAT handling and encourage env‑based configurationThe MCP JIRA section is clear and accurate, and the explicit warning about not committing
.claude/settings.jsonis good. To further reduce risk of accidental token leaks, consider either:
- Showing an example that reads
JIRA_PERSONAL_TOKENfrom the user's shell environment (leaving the value empty or as a placeholder in JSON), or- Calling out that the value should be injected via environment (e.g.,
claude mcp addflow) rather than hard‑coding the real token into the JSON checked into a repo.This keeps the workflow the same while nudging users toward safer defaults.
17-27: Address markdownlint warnings for fenced code blocks and bare URLsmarkdownlint is flagging this file for:
- Fenced code blocks without a language, and
- Bare URLs (e.g.,
https://issues.redhat.com, GitHub links).If markdownlint runs in CI, consider:
- Adding a language such as
bash,json, ortextto all new fenced code blocks, and- Wrapping bare URLs in angle brackets (
<https://…>) or link syntax ([link text](https://…)).This should clear the MD034/MD040 warnings noted in the static analysis.
Also applies to: 42-111
jira-scripts/network_bugs_overview (2)
1189-1203: CLI wiring for--query/--label-*looks sound; note mutually exclusive behaviorThe new arguments (
--query,--label-bug,--label) are correctly parsed and threaded throughparams. Inmain(), the subsequent short‑circuiting means:
- If
--queryis provided, onlyrun_custom_queryruns and all other flags are effectively ignored.- If either
--label-bugor--labelis provided, onlyapply_label_to_bugruns (with a runtime check enforcing both are present).This is a reasonable design for ad‑hoc utilities, but it does mean combinations like
--query --jira-bugswon’t behave additively. If that could surprise users, consider documenting this “one special action per run” behavior in the script’s help or README.Also applies to: 1229-1242
1246-1305:run_custom_queryimplementation aligns with docs; consider note on large result sets
run_custom_query:
- Reuses the existing retrying
run_jira_queryhelper.- Prints per‑bug ID, URL, summary, components, labels, issue links, description (truncated to 500 chars), and up to 5 comments.
- Gracefully handles empty results and any failures when reading issue links or comments (they’re best‑effort).
This matches what the
/label-bugsAPI‑mode documentation promises fornetwork_bugs_overview --query. For large JQL result sets, per‑issuejira_client.comments(bug)may be chatty, but that’s acceptable for an on‑demand debugging/AI integration tool. If you start querying hundreds of bugs at once, you might later consider an option to skip comments for performance.jira-scripts/.claude/commands/label-bugs.md (1)
42-51: Tidy fenced code blocks and bare URLs to satisfy markdownlintStatic analysis flags several spots here for:
- Fenced code blocks without a language (
```alone around JQL and output examples).- Bare URLs in example text (e.g.,
https://issues.redhat.com/browse/OCPBUGS-XXXXX).To keep the docs lint‑clean and more readable, consider:
- Adding an explicit language to each fence, e.g.
```bashfor commands,```textor```nonefor plain output/JQL.- Wrapping URLs in angle brackets (
<https://…>) or markdown links.These are purely documentation polish changes and won’t affect the behavior of
/label-bugs, but they’ll clear the MD034/MD040 warnings mentioned in static analysis.Also applies to: 77-90, 93-107, 133-156, 168-171
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting
⛔ Files ignored due to path filters (1)
jira-scripts/area_labels.csvis excluded by!**/*.csv
📒 Files selected for processing (3)
jira-scripts/.claude/commands/label-bugs.md(1 hunks)jira-scripts/README.md(2 hunks)jira-scripts/network_bugs_overview(3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**
⚙️ CodeRabbit configuration file
-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.
Files:
jira-scripts/README.mdjira-scripts/network_bugs_overview
🪛 markdownlint-cli2 (0.18.1)
jira-scripts/README.md
42-42: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
68-68: Bare URL used
(MD034, no-bare-urls)
69-69: Bare URL used
(MD034, no-bare-urls)
77-77: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
86-86: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
94-94: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
jira-scripts/.claude/commands/label-bugs.md
42-42: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
68-68: Bare URL used
(MD034, no-bare-urls)
69-69: Bare URL used
(MD034, no-bare-urls)
77-77: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
86-86: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
94-94: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
133-133: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
168-168: Bare URL used
(MD034, no-bare-urls)
🔇 Additional comments (3)
jira-scripts/network_bugs_overview (2)
1307-1337:apply_label_to_bugis safe and idempotent for repeated labelingThe labeling helper:
- Validates that both
bug_idandlabelare provided and prints a clear error otherwise.- Fetches the issue, checks for the label’s presence, and exits early with a friendly message if it already exists.
- Updates the
labelsfield with the new label appended, then prints URL, summary, and the full label list.- Catches and reports any exceptions from the JIRA client.
This fits the
/label-bugsAPI‑mode contract of “apply this one label and report back” and is safe to call repeatedly for the same(bug_id, label)pair. No changes needed here.
1445-1452: Short‑circuit order inmain()is correct for /label-bugs integrationThe execution order in
main():
--print-bug--query--label-bug/--label- recent/old bot utilities
- normal Jira/GitHub processing
ensures
/label-bugs’s API‑mode uses (--query,--label-bug/--label) don’t accidentally trigger the legacy reporting logic. That matches the PR’s goal of exposing ad‑hoc query/label operations without interfering with existing workflows.If you later add more “utility” flags, keeping them in this early‑return block will preserve the same mental model: one special action per invocation.
jira-scripts/.claude/commands/label-bugs.md (1)
7-176: Spec for/label-bugsis consistent with the Python helpers and MCP flowThe document clearly ties together:
- MCP mode using
mcp__jira-atlassian__jira_search/jira_update_issuewith the provided JQL and fields.- API mode using
./network_bugs_overview --query …and--label-bug/--label, which matches the newrun_custom_queryandapply_label_to_bughelpers.- Confidence thresholds, dry‑run behavior (no AskUserQuestion,
[DRY RUN]prefixes), and the requirement to skip bugs that already carry SDN area labels.From an implementation perspective this gives a precise contract for the command and aligns with the script changes in this PR, so it should be straightforward to keep the behavior consistent.
This commit adds an AI-powered bug labeling system for the networking team: /label-bugs command: - Automatically analyzes and labels JIRA bugs using area_labels.csv mapping - Uses MCP JIRA server by default for efficient data retrieval - Supports --dry-run flag to preview labels without applying them - Supports --api flag to use Python API through network_bugs_overview script as fallback - Implements confidence-based labeling: high (>80%), medium (40-80%), low (<40%) - Auto-applies high-confidence labels, prompts user for medium/low confidence - Detects backports via issue dependencies and applies SDN:Backport label - Skips bugs that already have SDN area labels Additional changes: - Add comprehensive MCP JIRA server configuration instructions to README.md - Document /label-bugs usage and examples in README.md Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Riccardo Ravaioli <rravaiol@redhat.com>
c46bca8 to
d618fd4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@jira-scripts/network_bugs_overview`:
- Around line 1243-1244: The default enabling of Claude labeling is currently
set via the variable label_bugs_with_claude = True which forces Claude Code runs
with no args; change this to opt-in by setting label_bugs_with_claude = False
(or remove the default True) and/or add a runtime availability check where the
script branches on label_bugs_with_claude and validates Claude is installed (log
a clear warning and skip labeling if not available) — look for the variable name
label_bugs_with_claude and the code path that invokes Claude Code and update the
default and add the safety check/warning there.
- Around line 1411-1426: The subprocess invocation in
run_label_bugs_with_claude() is using the claude CLI incorrectly:
subprocess.run(["claude", "-p", "/label-bugs --api"]) treats the /label-bugs
string as a prompt, but /label-bugs is an IDE/MCP command and not valid for
headless -p usage; update run_label_bugs_with_claude to either call the Claude
API directly (preferred) to trigger the label-bugs functionality or, if a CLI
call is required, construct a valid prompt string for -p (e.g., pass a real
prompt that performs labeling) or use the correct CLI subcommand syntax
supported by the installed claude binary; replace the existing subprocess.run
call with the appropriate API client call or corrected CLI invocation and adjust
error handling around subprocess.run / API request accordingly.
🧹 Nitpick comments (3)
jira-scripts/network_bugs_overview (1)
1296-1308: Bareexceptclauses silently swallow errors.These bare
exceptblocks make debugging difficult when things go wrong. Consider catching specific exceptions or at minimum logging the error.♻️ Suggested improvement
try: if hasattr(bug.fields, 'issuelinks') and bug.fields.issuelinks: for link in bug.fields.issuelinks: link_type = link.type.name if hasattr(link, 'type') else "Unknown" if hasattr(link, 'outwardIssue'): issue_links.append(f"{link_type} -> {link.outwardIssue.key}") elif hasattr(link, 'inwardIssue'): issue_links.append(f"{link.inwardIssue.key} -> {link_type}") - except: - pass + except Exception as ex: + # Issue links are optional - continue if unavailable + pass # Get comments comments = [] try: comment_objs = jira_client.comments(bug) for comment in comment_objs[:5]: # Limit to first 5 comments author = comment.author.displayName if hasattr(comment.author, 'displayName') else "Unknown" body = comment.body[:200] + "..." if len(comment.body) > 200 else comment.body comments.append(f"{author}: {body}") - except: - pass + except Exception as ex: + # Comments are optional - continue if unavailable + passjira-scripts/.claude/commands/label-bugs.md (1)
37-50: Consider referencing the JQL query from a single source.The JQL query is hardcoded here and may also exist in other parts of the codebase. If the filtering criteria change, multiple locations would need updating.
jira-scripts/README.md (1)
111-111: Consider recommending environment variables for token management.The warning about not committing the token is good, but you could strengthen security guidance by suggesting users reference an environment variable instead of hardcoding the token in
settings.json.Example addition:
**Tip**: Instead of hardcoding the token, you can use an environment variable: ```json "JIRA_PERSONAL_TOKEN": "${JIRA_TOKEN}"Then set
export JIRA_TOKEN=your_tokenin your shell profile.</blockquote></details> </blockquote></details> <details> <summary>📜 Review details</summary> **Configuration used**: Organization UI **Review profile**: CHILL **Plan**: Pro **Cache: Disabled due to data retention organization setting** **Knowledge base: Disabled due to `Reviews -> Disable Knowledge Base` setting** <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between c46bca8e17af58e3682f48480e67a51d277e2243 and d618fd4a1534b1a94ef2aceb6926160324cc26c6. </details> <details> <summary>⛔ Files ignored due to path filters (1)</summary> * `jira-scripts/area_labels.csv` is excluded by `!**/*.csv` </details> <details> <summary>📒 Files selected for processing (3)</summary> * `jira-scripts/.claude/commands/label-bugs.md` * `jira-scripts/README.md` * `jira-scripts/network_bugs_overview` </details> <details> <summary>🧰 Additional context used</summary> <details> <summary>📓 Path-based instructions (1)</summary> <details> <summary>**</summary> **⚙️ CodeRabbit configuration file** > -Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity. Files: - `jira-scripts/network_bugs_overview` - `jira-scripts/README.md` </details> </details><details> <summary>🪛 LanguageTool</summary> <details> <summary>jira-scripts/.claude/commands/label-bugs.md</summary> [grammar] ~62-~62: Use a hyphen to join words. Context: ...view and choose 4. **For medium and low confidence bugs** (SKIP THIS STEP ENTIRE... (QB_NEW_EN_HYPHEN) --- [grammar] ~85-~85: Use a hyphen to join words. Context: ...BUGS-12345 ``` For medium and low confidence bugs, also show: ``` - ... (QB_NEW_EN_HYPHEN) </details> </details> <details> <summary>🪛 markdownlint-cli2 (0.18.1)</summary> <details> <summary>jira-scripts/README.md</summary> 42-42: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 68-68: Bare URL used (MD034, no-bare-urls) --- 69-69: Bare URL used (MD034, no-bare-urls) --- 77-77: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 86-86: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 94-94: Fenced code blocks should have a language specified (MD040, fenced-code-language) </details> </details> </details> <details> <summary>🔇 Additional comments (8)</summary><blockquote> <details> <summary>jira-scripts/network_bugs_overview (3)</summary><blockquote> `1196-1216`: **LGTM!** The new CLI arguments are well-structured with clear help text. The mutual dependency between `--label-bug` and `--label` is appropriately validated in the `apply_label_to_bug` function. --- `1325-1354`: **LGTM!** The function has proper input validation, checks for duplicate labels before applying, and provides clear feedback on success or failure. --- `1481-1506`: **LGTM!** The integration in `main()` properly handles the new query and labeling flows with appropriate early returns. The `label_only` logic correctly isolates standalone Claude labeling from combined operations. </blockquote></details> <details> <summary>jira-scripts/.claude/commands/label-bugs.md (3)</summary><blockquote> `1-18`: **LGTM!** The usage section is clear with practical examples covering all command variations. --- `52-74`: **LGTM!** The confidence-based workflow is well-designed. Requiring "Skip/Defer" as the first option is a good UX pattern for quick triage. --- `158-177`: **LGTM!** The rules section provides clear, actionable guidelines that should help maintain consistent labeling behavior. </blockquote></details> <details> <summary>jira-scripts/README.md (2)</summary><blockquote> `42-92`: **LGTM!** The setup instructions are clear and comprehensive. The use of podman with environment variables for secrets is a reasonable approach. --- `94-109`: **LGTM!** The usage examples clearly demonstrate how to interact with Claude Code using the MCP JIRA integration. </blockquote></details> </blockquote></details> <sub>✏️ Tip: You can disable this entire section by setting `review_details` to `false` in your review settings.</sub> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
| # Also run AI-powered bug labeling by default | ||
| label_bugs_with_claude = True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Defaulting Claude labeling to run with no args may be disruptive.
When no arguments are specified, label_bugs_with_claude is set to True, meaning the script will attempt to invoke Claude Code by default. This changes existing behavior and could fail for users who don't have Claude Code installed.
Consider making this opt-in only (remove from default case) or add a clear warning/skip when Claude is not available.
🐛 Suggested fix - make Claude labeling opt-in only
else:
# Default values when no args are specified
jira_bugs = True
jira_escalations = False
new_bugs = True
process_github_issues = True
- # Also run AI-powered bug labeling by default
- label_bugs_with_claude = True
+ # AI-powered bug labeling is opt-in via -l/--label-bugs-with-claude📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # Also run AI-powered bug labeling by default | |
| label_bugs_with_claude = True | |
| # Default values when no args are specified | |
| jira_bugs = True | |
| jira_escalations = False | |
| new_bugs = True | |
| process_github_issues = True | |
| # AI-powered bug labeling is opt-in via -l/--label-bugs-with-claude | |
| label_bugs_with_claude = False |
🤖 Prompt for AI Agents
In `@jira-scripts/network_bugs_overview` around lines 1243 - 1244, The default
enabling of Claude labeling is currently set via the variable
label_bugs_with_claude = True which forces Claude Code runs with no args; change
this to opt-in by setting label_bugs_with_claude = False (or remove the default
True) and/or add a runtime availability check where the script branches on
label_bugs_with_claude and validates Claude is installed (log a clear warning
and skip labeling if not available) — look for the variable name
label_bugs_with_claude and the code path that invokes Claude Code and update the
default and add the safety check/warning there.
| parser.add_argument( | ||
| "--label-bug", | ||
| type=str, | ||
| help="Bug ID to apply a label to (e.g., OCPBUGS-123). Use with --label", | ||
| ) | ||
| parser.add_argument( | ||
| "--label", | ||
| type=str, | ||
| help="Label to apply to the bug specified with --label-bug", | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so --label-bug and --label options must be used together ? can't this be done with single option ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It definitely can!
| ## Usage | ||
|
|
||
| - `/label-bugs` - Analyze and apply labels to unlabeled bugs (uses MCP JIRA server) | ||
| - `/label-bugs --dry-run` - Analyze bugs and show what labels would be applied WITHOUT actually applying them |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can dry-run option run from network_bugs_overview script ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, but I can add it if you think you'll need it.
- Add -l/--label-bugs-with-claude flag to invoke Claude Code for AI-powered bug labeling - When run without arguments, the script now also runs the /label-bugs --api command - When -l is the only flag, it runs only the labeling and exits - Uses subprocess to call: claude -p "/label-bugs --api" Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> Signed-off-by: Riccardo Ravaioli <rravaiol@redhat.com>
d618fd4 to
1d4b7f8
Compare
|
@ricky-rav: all tests passed! Full PR test history. Your PR dashboard. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
This commit adds an AI-powered bug labeling system for the networking team:
/label-bugs command:
Additional changes:
When retrieving bugs through the MCP JIRA server, it needs ~1000 tokens per bug, even if we ask for only a limited set of fields, because - it seems - the answer will contain all jira fields anyway (empty if not requested, filled out if requested).
So I provided also a way to do the same operation via the standard jira API with the existing python script.
Usage:
I also added a new
-loption tonetwork_bugs_overview, in order to launch the claude-code slash command from the python script. I also added the execution of the slash command to the end ofnetwork_bugs_overview, so that the person running bug dispatch only has to run the script once to (1) get the bug ranking, (2) retrieve the new bugs, (3) label new bugs.