From microshift-ci
Create JIRA bugs from analyze-ci failure reports (dry-run by default). Supports both release and PR job files.
How this skill is triggered — by the user, by Claude, or both
Slash command
/microshift-ci:create-bugsThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
```bash
/microshift-ci:create-bugs <source> [--create]
Reads individual job analysis reports produced by microshift-ci:doctor and creates JIRA bugs in USHIFT for CI test failures. Operates in dry-run mode by default - it shows what bugs would be created without actually creating them. Use --create to perform actual issue creation.
This command does NOT re-analyze CI jobs. It consumes existing job analysis files from <WORKDIR>.
<ARGUMENTS> (required): Source identifier, optionally followed by --create
<source> (required): One of the following:
4.22, main): Looks for files matching analyze-ci-release-<release>-job-*.txtpr-6396 or pr6396): Looks for files matching analyze-ci-prs-job-*-pr<number>-*.txtrebase-release-4.22): Resolves to the corresponding rebase PR by scanning existing analyze-ci-prs-job-* files for the matching release version in their content--create (optional): Actually create JIRA issues. Without this flag, only a dry-run report is produced.<WORKDIR>:
analyze-ci-release-<release>-job-*.txt (produced by /microshift-ci:doctor)analyze-ci-prs-job-*-pr<number>-*.txt (produced by /microshift-ci:doctor)--- STRUCTURED SUMMARY --- block (see below)Each job analysis file produced by /microshift-ci:prow-job must end with a machine-readable block:
--- STRUCTURED SUMMARY ---
SEVERITY: <1-5>
STACK_LAYER: <AWS Infra|External Infrastructure|build phase|deploy phase|test setup phase|Test Configuration|test|teardown>
STEP_NAME: <the CI step where the error occurred>
ERROR_SIGNATURE: <concise, unique description of the root cause error>
RAW_ERROR: <verbatim primary error message from logs — used for deterministic grouping>
INFRASTRUCTURE_FAILURE: <true|false>
JOB_URL: <full prow job URL>
JOB_NAME: <full periodic job name>
RELEASE: <X.YY>
FINISHED: <job finish date in YYYY-MM-DD format>
--- END STRUCTURED SUMMARY ---
If a job file lacks this block, it is skipped with a warning.
Compute once at the start by running date +%y%m%d and substituting into the path below. In all commands, replace <WORKDIR> with the computed path — do not use shell variables.
/tmp/microshift-ci-claude-workdir.<YYMMDD>
Actions:
Parse <ARGUMENTS> to extract <source> and detect --create flag
Determine mode: if --create is present, set MODE=create; otherwise MODE=dry-run
Determine today's WORKDIR path by running date +%y%m%d and substituting into /tmp/microshift-ci-claude-workdir.YYMMDD. Run mkdir -p on it.
Run the preparation script to parse job files, group by signature, and extract search keywords:
python3 plugins/microshift-ci/scripts/search-bugs.py <source> --workdir <WORKDIR>
The script writes <WORKDIR>/analyze-ci-bug-candidates-<source>.json containing:
keywords (2-4 distinctive search terms per candidate)test_ids (numeric IDs like 55394 for test case searches)analysis_text for bug descriptionsRead the candidates JSON file for use in Step 2
Error Handling:
For each bug candidate in the candidates JSON, run ALL of the following searches. The keywords and test_ids fields are pre-computed by the script — use them directly.
Search A — Keyword search (multiple focused queries):
Use the pre-computed keywords array from the candidate (already filtered for stop words and ranked by specificity)
Run 2-3 separate searches in parallel, each using 1-2 keywords from the array. Do NOT put all keywords into a single text ~ query — Jira requires all terms to match, so queries with 3+ keywords are fragile and miss issues that use slightly different wording.
# Example: candidate.keywords = ["invalidclienttokenid", "cloudformation", "createstack", "aws-2"]
# Search A1: most distinctive keyword
mcp__jira__jira_search(jql='... AND issuetype = Bug AND text ~ "invalidclienttokenid" ...', limit=5)
# Search A2: second keyword
mcp__jira__jira_search(jql='... AND issuetype = Bug AND text ~ "cloudformation" ...', limit=5)
Merge and deduplicate results from all A-series queries before proceeding
Search B — Test case ID search (MANDATORY when test_ids is non-empty):
Use the pre-computed test_ids array from the candidate. For EACH ID, run TWO separate searches:
# Search B1: bare number
jql: ... AND issuetype = Bug AND text ~ "68256" AND status not in (Closed, Verified) ...
# Search B2: OCP-prefixed form (OpenShift Polarion convention)
jql: ... AND issuetype = Bug AND text ~ "OCP-68256" AND status not in (Closed, Verified) ...
Why both forms are required: Jira's text indexer treats OCP-68256 as a single token, so text ~ "68256" will NOT match issues containing OCP-68256, and vice versa. Skipping either form WILL cause missed duplicates.
After all searches:
mcp__jira__jira_get_issue to show summary and statusSearch C — Regression check (closed/verified issues): After completing searches A and B, run an additional keyword search against closed/verified issues to detect potential regressions:
mcp__jira__jira_search(
jql='((project = OCPBUGS AND component = MicroShift) OR project = USHIFT) AND issuetype = Bug AND text ~ "<keywords>" AND status in (Closed, Verified) ORDER BY updated DESC',
limit=5
)
If results are found, fetch their details with mcp__jira__jira_get_issue and flag them as "Potential regression of closed bug" — distinct from open duplicates. These should be shown to the user but do NOT block creation; they serve as a warning that a previously fixed issue may have resurfaced.
Note: Run searches in parallel where possible.
Actions:
Display a numbered list of all bug candidates with:
[DRY-RUN] or [WILL CREATE]In dry-run mode (--create NOT specified):
Display all candidates with [DRY-RUN] prefix
After listing all candidates, show a summary:
DRY-RUN SUMMARY
Source: <SOURCE_LABEL>
Total job files parsed: N
Unique bug candidates: N
Candidates with potential duplicates: N
Candidates ready to file: N
To create these bugs, run:
/microshift-ci:create-bugs <source> --create
Do NOT prompt for any actions. Do NOT create any issues. Do NOT proceed to Steps 4/4a (create/reopen). Continue to Step 5 and Step 6.
In create mode (--create specified):
For each candidate, prompt the user:
Bug Candidate N/M:
Summary: "<derived summary>"
Severity: X (affects Y jobs)
Step: <step_name>
Jobs:
- <job_url_1>
- <job_url_2>
Potential Duplicates (open):
- USHIFT-XXXXX: "<summary>" [Status] (or OCPBUGS-YYYYY)
(or "None found")
Potential Regressions (closed):
- USHIFT-YYYYY (or OCPBUGS-YYYYY): "<summary>" [Status] potential regression
(or "None found")
# ACTION_PROMPT_WITH_REOPEN (use when closed regressions exist):
Action? [c]reate / [s]kip / [l]ink-to-existing <JIRA-KEY> / [r]eopen <JIRA-KEY>:
# ACTION_PROMPT_NO_REOPEN (use when no closed regressions exist):
Action? [c]reate / [s]kip / [l]ink-to-existing <JIRA-KEY>:
Select the prompt template based on whether closed regressions were found for the candidate: use ACTION_PROMPT_WITH_REOPEN when the candidate has closed regressions from Search C, and ACTION_PROMPT_NO_REOPEN otherwise.
create: Proceed to Step 4
skip: Skip this candidate, move to next
link-to-existing: Validate the key by calling mcp__jira__jira_get_issue(issue_key=<JIRA-KEY>). If the issue exists, record the key and move to next. If the call fails or returns not-found, show an error (e.g., "JIRA key <JIRA-KEY> not found — check for typos") and re-prompt with the same Action? choices.
reopen: Validate the provided JIRA key before proceeding. Call mcp__jira__jira_get_issue(issue_key=<JIRA-KEY>) to confirm the issue exists, then verify that the key matches one of the candidate's closed regressions found in Search C, that the issue status is Closed or Verified, and that the issue type is Bug. If validation fails (key not found, not in the candidate's closed regression list, not in Closed/Verified state, or not a Bug), show an error (e.g., "JIRA key <JIRA-KEY> not eligible for reopen — must be a Bug closed regression") and re-prompt with the same Action? choices. If validation passes, proceed to Step 4a.
Actions: For each candidate where user chose "create":
Construct the bug summary:
"MicroShift CI: <error_signature>" (truncate to 100 chars if needed)Construct the bug description using Markdown format (the MCP Jira tool accepts Markdown and automatically converts it to Jira wiki markup — do NOT write Jira wiki markup directly):
## Description of problem
CI job failures detected for MicroShift <SOURCE_LABEL>.
<concise description derived from the error signature and analysis text>
## Version-Release number of selected component (if applicable)
<release from STRUCTURED SUMMARY>
## How reproducible
Always (fails consistently in CI)
## Steps to Reproduce
1. Run the CI job(s) listed below
2. Observe failure in step: <step_name>
## Actual results
````
<error details extracted from the analysis text — the specific error message and relevant log context>
````
## Expected results
CI job should pass successfully.
## Additional info
**Stack Layer:** <stack_layer>
**CI Step:** <step_name>
**Error Severity:** <severity>/5
**Number of affected jobs:** <count>
**Last observed:** <finished date from STRUCTURED SUMMARY, YYYY-MM-DD>
**Affected Jobs:**
<for each job in the group>
- [<job_name>](<job_url>)
</for each>
**Source:** Auto-generated by /microshift-ci:create-bugs from CI analysis output.
Create the issue:
mcp__jira__jira_create_issue(
project_key="USHIFT",
summary="MicroShift CI: <error_signature>",
issue_type="Bug",
description="<constructed description>",
components="MicroShift",
additional_fields={
"labels": ["microshift-ci-ai-generated"],
"security": {"name": "Red Hat Employee"}
}
)
Record the result: Store the created issue key for the final report.
Error Handling:
Precondition: The JIRA issue must be a Bug in Closed or Verified state (validated in Step 3). If the issue type is not Bug, do not proceed — show an error and re-prompt.
Actions: For each candidate where user chose "reopen":
Get available transitions for the closed issue:
mcp__jira__jira_get_transitions(issue_key="<JIRA-KEY>")
Find the reopen transition: Look for a transition whose name is exactly "To Do", "New", or "Backlog" (case-insensitive). If no suitable transition is found, report the error and ask the user whether to create a new bug instead or skip.
Construct a regression comment describing the new occurrences:
## Regression: issue has resurfaced
This issue was previously closed but the same failure has been detected again in CI.
**Error Signature:** <error_signature>
**Error Severity:** <severity>/5
**Number of affected jobs:** <count>
**Last observed:** <finished date>
**Affected Jobs:**
- [<job_name>](<job_url>)
...
Reopened automatically by /microshift-ci:create-bugs.
Transition the issue to reopen it:
mcp__jira__jira_transition_issue(
issue_key="<JIRA-KEY>",
transition_id="<reopen_transition_id>",
comment="<regression comment>"
)
If the transition call does not support inline comments, add the comment separately:
mcp__jira__jira_add_comment(
issue_key="<JIRA-KEY>",
body="<regression comment>"
)
Record the result: Store the reopened issue key for the final report.
Error Handling:
Actions:
After processing all bug candidates (Steps 2-4a) and regardless of mode (dry-run or create), write a machine-readable bug mapping file that create-report.py can consume to display JIRA bug links in the HTML report. The file content is based on the Jira search results from Step 2 — it is not affected by whether bugs were created or reopened in Steps 4/4a.
<WORKDIR>/analyze-ci-bugs-<source>.json (overwrite if exists){
"source": "<source>",
"date": "YYYY-MM-DD",
"candidates": [
{
"error_signature": "<error_signature>",
"severity": <N>,
"step_name": "<step_name>",
"affected_jobs": <count>,
"duplicates": [
{"key": "<JIRA-KEY>", "summary": "<summary>", "status": "<status>"}
],
"regressions": [
{"key": "<JIRA-KEY>", "summary": "<summary>", "status": "<status>"}
]
}
]
}
create-report.py to show linked bugs per issue in the HTML report.[] for duplicates and regressions when none are found.jq or python3 -c to ensure valid JSON, or use the Write tool.Actions:
<WORKDIR>/analyze-ci-create-bugs-<source>.<timestamp>.txtDry-run report format:
═══════════════════════════════════════════════════════════════
ANALYZE-CI CREATE BUGS - DRY-RUN REPORT
Source: <SOURCE_LABEL>
Date: YYYY-MM-DD
═══════════════════════════════════════════════════════════════
PARSING
Job files found: N
Successfully parsed: N
Skipped (no structured summary): N
FILTERING
None (all failures included)
DEDUPLICATION
Unique bug candidates: N
CANDIDATES
1. MicroShift CI: <error_signature>
Severity: X | Jobs: Y | Step: <step_name>
Potential Duplicates: USHIFT-XXXXX, OCPBUGS-YYYYY (or "None")
Potential Regressions: USHIFT-YYYYY (or OCPBUGS-YYYYY) [Closed] (or "None")
2. MicroShift CI: <error_signature>
...
To create these bugs, run:
/microshift-ci:create-bugs <source> --create
Report saved: <WORKDIR>/analyze-ci-create-bugs-<source>.<timestamp>.txt
═══════════════════════════════════════════════════════════════
Create mode report format:
═══════════════════════════════════════════════════════════════
ANALYZE-CI CREATE BUGS - CREATION REPORT
Source: <SOURCE_LABEL>
Date: YYYY-MM-DD
═══════════════════════════════════════════════════════════════
RESULTS
1. USHIFT-12345 (CREATED)
MicroShift CI: <error_signature>
URL: https://redhat.atlassian.net/browse/USHIFT-12345
2. SKIPPED
MicroShift CI: <error_signature>
Reason: User skipped
3. USHIFT-99999 (LINKED TO EXISTING)
MicroShift CI: <error_signature>
Reason: Duplicate of existing issue
4. USHIFT-88888 (REOPENED)
MicroShift CI: <error_signature>
URL: https://redhat.atlassian.net/browse/USHIFT-88888
Reason: Regression of previously closed bug
SUMMARY
Created: N
Skipped: N
Linked to existing: N
Reopened: N
Failed: N
Report saved: <WORKDIR>/analyze-ci-create-bugs-<source>.<timestamp>.txt
═══════════════════════════════════════════════════════════════
/microshift-ci:create-bugs 4.22
Shows what bugs would be created from release 4.22 analysis without creating anything.
/microshift-ci:create-bugs 4.22 --create
Interactively creates bugs from release 4.22 analysis.
/microshift-ci:create-bugs pr-6396
Shows what bugs would be created from PR #6396 analysis.
/microshift-ci:create-bugs rebase-release-4.22 --create
Resolves the rebase PR for release 4.22, then interactively creates bugs.
/microshift-ci:create-bugs 4.19
Error: No job analysis files found at <WORKDIR>/analyze-ci-release-4.19-job-*.txt
Run the analysis first:
/microshift-ci:doctor 4.19
/microshift-ci:create-bugs pr-9999
Error: No job analysis files found at <WORKDIR>/analyze-ci-prs-job-*-pr9999-*.txt
Run the analysis first:
/microshift-ci:doctor <release>
<WORKDIR>analyze-ci-release-<release>-job-*.txt (from /microshift-ci:doctor)analyze-ci-prs-job-*-pr<number>-*.txt (from /microshift-ci:doctor)--create flag triggers interactive mode where each candidate requires user confirmationmicroshift-ci-ai-generated for tracking/microshift-ci:prow-jobanalyze-ci-bugs-<source>.json) is written in both dry-run and create modes — this file is consumed by create-report.py to show JIRA bug links in the HTML reportGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub openshift-eng/edge-tooling --plugin microshift-ci