plugins/ci/skills/triage-regression/SKILL.md
Create or update a Component Readiness triage record linking regressions to a JIRA bug
npx skillsauth add openshift-eng/ai-helpers triage-regressionInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill creates or updates triage records via the Sippy API, linking one or more Component Readiness regressions to a JIRA bug.
Use this skill when you need to:
OpenShift CLI Authentication: Required for authenticating to the sippy-auth API
oc loginhttps://api.cr.j7t7.p1.openshiftapps.com:6443oc-auth skill to obtain the Bearer tokenPython 3: Python 3.6 or later
python3 --versionInput Data: Requires regression IDs, a JIRA bug URL, and a triage type
fetch-regression-details skillhttps://redhat.atlassian.net/browse/OCPBUGS-12345)product, test, ci-infra, or product-infraUse the oc-auth skill to obtain a Bearer token from the DPCR cluster:
# Get token from the DPCR cluster context
# The oc-auth skill's curl_with_token.sh uses this cluster for sippy-auth
DPCR_CLUSTER="https://api.cr.j7t7.p1.openshiftapps.com:6443"
# Find the oc context for the DPCR cluster and get the token
CONTEXT=$(oc config get-contexts -o name 2>/dev/null | while read -r ctx; do
server=$(oc config view -o jsonpath="{.clusters[?(@.name=='$(oc config view -o jsonpath="{.contexts[?(@.name=='$ctx')].context.cluster}" 2>/dev/null)')].cluster.server}" 2>/dev/null || echo "")
server_clean=$(echo "$server" | sed -E 's|^https?://||')
if [ "$server_clean" = "api.cr.j7t7.p1.openshiftapps.com:6443" ]; then
echo "$ctx"
break
fi
done)
if [ -z "$CONTEXT" ]; then
echo "Error: Not logged into DPCR cluster. Please run: oc login $DPCR_CLUSTER"
exit 1
fi
TOKEN=$(oc whoami -t --context="$CONTEXT" 2>/dev/null)
if [ -z "$TOKEN" ]; then
echo "Error: Failed to get token. Please re-authenticate to DPCR cluster."
exit 1
fi
script_path="plugins/ci/skills/triage-regression/triage_regression.py"
# Create a new triage for one regression
python3 "$script_path" 33639 \
--token "$TOKEN" \
--url "https://redhat.atlassian.net/browse/OCPBUGS-12345" \
--type product \
--format json
# Create a new triage for multiple regressions
python3 "$script_path" 33639,33640,33641 \
--token "$TOKEN" \
--url "https://redhat.atlassian.net/browse/OCPBUGS-12345" \
--type product \
--description "API discovery regression across metal variants" \
--format json
# Update an existing triage to add more regressions (url and type inherited from existing triage)
python3 "$script_path" 33639,33640,33641,33642 \
--token "$TOKEN" \
--triage-id 456 \
--format json
Arguments:
regression_ids: Required comma-separated list of regression IDs (integers)Required Options:
--token <token>: OAuth Bearer token for sippy-auth (obtained from oc-auth skill)--url <jira_url>: JIRA bug URL (required for create, optional for update - uses existing value)--type <triage_type>: Triage type: product, test, ci-infra, product-infra (required for create, optional for update - uses existing value)Options:
--triage-id <id>: Existing triage ID to update (omit to create new)--description <text>: Description for the triage--format json|summary: Output format (default: json)output=$(python3 "$script_path" 33639 \
--token "$TOKEN" \
--url "https://redhat.atlassian.net/browse/OCPBUGS-12345" \
--type product \
--format json)
success=$(echo "$output" | jq -r '.success')
if [ "$success" = "true" ]; then
triage_id=$(echo "$output" | jq -r '.triage.id')
echo "Triage created with ID: $triage_id"
else
error=$(echo "$output" | jq -r '.error')
echo "Error: $error"
fi
| Type | Description |
|------|-------------|
| product | Actual product regressions (default for most bugs) |
| test | Test framework issues (flaky tests, test bugs) |
| ci-infra | CI infrastructure problems that did not impact customers |
| product-infra | Infrastructure problems that impacted CI and customers |
Base URL: https://sippy-auth.dptools.openshift.org
Authentication: Bearer token from the DPCR cluster (api.cr.j7t7.p1.openshiftapps.com:6443)
Create Triage:
POST/api/component_readiness/triagesAuthorization: Bearer <token>, Content-Type: application/json{
"url": "https://redhat.atlassian.net/browse/OCPBUGS-12345",
"type": "product",
"description": "Optional description",
"regressions": [{"id": 33639}, {"id": 33640}]
}
Update Triage:
PUT/api/component_readiness/triages/{id}Authorization: Bearer <token>, Content-Type: application/json"id" matching the URL pathSuccess Response:
{
"success": true,
"operation": "create",
"regression_ids": [33639],
"triage": {
"id": 456,
"url": "https://redhat.atlassian.net/browse/OCPBUGS-12345",
"type": "product",
"description": "API discovery regression",
"regressions": [
{"id": 33639}
],
"links": {
"self": "/api/component_readiness/triages/456"
}
}
}
Error Response:
{
"success": false,
"error": "HTTP error 400: Bad Request",
"detail": "regression ID 99999 not found",
"operation": "create",
"regression_ids": [99999]
}
Triage Create - SUCCESS
============================================================
Triage ID: 456
URL: https://redhat.atlassian.net/browse/OCPBUGS-12345
Type: product
Description: API discovery regression
Linked Regressions: 1
- Regression 33639
{
"success": false,
"error": "HTTP error 401: Unauthorized",
"detail": "",
"operation": "create",
"regression_ids": [33639]
}
Re-authenticate to the DPCR cluster and obtain a fresh token.
{
"success": false,
"error": "HTTP error 400: Bad Request",
"detail": "regression ID 99999 not found",
"operation": "create",
"regression_ids": [99999]
}
The script validates triage type locally before making the API call:
Error: Invalid type 'invalid'. Must be one of: product, test, ci-infra, product-infra
Exit Codes:
0: Success1: Error (invalid input, API error, network error, etc.)python3 plugins/ci/skills/triage-regression/triage_regression.py \
33639 \
--token "$TOKEN" \
--url "https://redhat.atlassian.net/browse/OCPBUGS-12345" \
--type product \
--format json
python3 plugins/ci/skills/triage-regression/triage_regression.py \
33639,33640,33641 \
--token "$TOKEN" \
--url "https://redhat.atlassian.net/browse/OCPBUGS-12345" \
--type product \
--description "Same root cause: API discovery failure across metal variants" \
--format json
# First, get the existing triage ID from regression data
existing_triage_id=$(echo "$regression_data" | jq -r '.triages[0].id')
# Update it with additional regression IDs (url and type inherited from existing triage)
python3 plugins/ci/skills/triage-regression/triage_regression.py \
33639,33640,33641,33642 \
--token "$TOKEN" \
--triage-id "$existing_triage_id" \
--format json
python3 plugins/ci/skills/triage-regression/triage_regression.py \
33639 \
--token "$TOKEN" \
--url "https://redhat.atlassian.net/browse/OCPBUGS-67890" \
--type test \
--description "Flaky test: intermittent timeout in discovery suite" \
--format json
https://sippy-auth.dptools.openshift.org using a Bearer token from the DPCR clusteroc-auth skill to obtain the token (requires oc login to DPCR cluster)--triage-id; when updating, --triage-id is requiredoc-auth (provides authentication tokens for sippy-auth)fetch-regression-details (provides regression IDs and existing triage info)/ci:analyze-regression (analyzes regressions and suggests triage)research
Shared engine for analyzing Jira issue activity and generating status summaries
testing
Snapshot OpenShift payload data (release controller, PR diffs, comments, CI jobs, JUnit results, regression tracking) to a local directory for offline analysis
development
Analyze a payload snapshot to identify root causes of blocking job failures, score candidate PRs, and produce an HTML report with revert recommendations
tools
Create TRT JIRA bugs, open revert PRs, and trigger payload jobs for high-confidence revert candidates