plugins/ci/skills/fetch-new-prs-in-payload/SKILL.md
Fetch pull requests that are new in a given OpenShift payload compared to the previous payload
npx skillsauth add openshift-eng/ai-helpers fetch-new-prs-in-payloadInstall 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 fetches the list of pull requests that are new in a given OpenShift payload tag compared to the previous payload. It tries the Sippy payload diff API first, and falls back to the release controller API when Sippy has not yet ingested the payload (e.g., in-progress or very recent payloads).
Use this skill when you need to:
The payload tag can be obtained from the fetch-prowjob-json skill (release.openshift.io/tag annotation) or from release controller pages.
Network Access: Must be able to reach the Sippy API and/or the release controller
curl -s https://sippy.dptools.openshift.org/api/healthcurl -s https://amd64.ocp.releases.ci.openshift.org/api/v1/releasestream/4-stable/latestPython 3: Python 3.6 or later
python3 --versionThe skill uses a Python script to fetch and format the payload diff data:
# Locate the Python script
FETCH_NEW_PRS="${CLAUDE_PLUGIN_ROOT}/skills/fetch-new-prs-in-payload/fetch_new_prs_in_payload.py"
if [ ! -f "$FETCH_NEW_PRS" ]; then
FETCH_NEW_PRS=$(find ~/.claude/plugins -type f -path "*/ci/skills/fetch-new-prs-in-payload/fetch_new_prs_in_payload.py" 2>/dev/null | sort | head -1)
fi
if [ -z "$FETCH_NEW_PRS" ] || [ ! -f "$FETCH_NEW_PRS" ]; then echo "ERROR: fetch_new_prs_in_payload.py not found" >&2; exit 2; fi
# Fetch new PRs in JSON format
python3 "$FETCH_NEW_PRS" <payload_tag> --format json
# Or fetch as human-readable summary grouped by component
python3 "$FETCH_NEW_PRS" <payload_tag> --format summary
The script outputs structured JSON data that can be further processed:
# Store JSON output in a variable for processing
pr_data=$(python3 "$script_path" 4.22.0-0.ci-2026-02-06-195709 --format json)
# Extract specific fields using jq if needed
total=$(echo "$pr_data" | jq '.total_prs')
pr_urls=$(echo "$pr_data" | jq -r '.pull_requests[].url')
components=$(echo "$pr_data" | jq -r '[.pull_requests[].component] | unique[]')
# Find PRs for a specific component
echo "$pr_data" | jq '.pull_requests[] | select(.component == "hypershift")'
# Find PRs with associated bugs
echo "$pr_data" | jq '.pull_requests[] | select(.bug_url != "")'
The structured data includes all PR details from the payload diff:
{
"payload_tag": "4.22.0-0.nightly-2026-01-15-114134",
"total_prs": 17,
"pull_requests": [
{
"url": "https://github.com/openshift/assisted-service/pull/8594",
"pull_request_id": "8594",
"component": "agent-installer-api-server",
"description": "Create Enhancement Document for 3rd Party CNI / No CNI Support in Assisted Installer",
"bug_url": "https://redhat.atlassian.net/browse/MGMT-22584"
},
{
"url": "https://github.com/openshift/hypershift/pull/7470",
"pull_request_id": "7470",
"component": "hypershift",
"description": "use InfraStatus.APIPort for custom DNS kubeconfig",
"bug_url": "https://redhat.atlassian.net/browse/OCPBUGS-72258"
}
]
}
The Python script handles common error cases automatically:
python3 fetch_new_prs_in_payload.py 4.22.0-0.ci-9999-99-99-000000
# Error: Payload '4.22.0-0.ci-9999-99-99-000000' not found.
# Verify the payload tag exists (e.g., 4.22.0-0.ci-2026-02-06-195709).
python3 fetch_new_prs_in_payload.py 4.22.0-0.ci-2026-02-06-195709
# Error: Failed to connect to Sippy API: [Errno -2] Name or service not known
# Check network connectivity.
python3 fetch_new_prs_in_payload.py
# usage: fetch_new_prs_in_payload.py [-h] [--format {json,summary}] payload_tag
# fetch_new_prs_in_payload.py: error: the following arguments are required: payload_tag
Exit Codes:
0: Success1: Error (invalid input, API error, network error, etc.)The script tries two APIs in order:
The output format is identical regardless of which source is used. The fallback is automatic and transparent.
GET https://sippy.dptools.openshift.org/api/payloads/diff?toPayload={payload_tag}
toPayload (required): The payload tag to diff against its predecessor (e.g., 4.22.0-0.ci-2026-02-06-195709)The API returns a JSON array of PR objects:
[
{
"id": 0,
"created_at": "0001-01-01T00:00:00Z",
"updated_at": "0001-01-01T00:00:00Z",
"deleted_at": null,
"url": "https://github.com/openshift/hypershift/pull/7470",
"pull_request_id": "7470",
"name": "hypershift",
"description": "use InfraStatus.APIPort for custom DNS kubeconfig",
"bug_url": "https://redhat.atlassian.net/browse/OCPBUGS-72258"
}
]
Raw API Fields:
id, created_at, updated_at, deleted_at: Database metadata (not useful for consumers)url: Full GitHub pull request URLpull_request_id: PR number as a stringname: Component name(s) affected by this PR (may contain comma-separated values for multi-component PRs, e.g., "olm-catalogd, olm-operator-controller")description: PR title/descriptionbug_url: Associated Jira bug URL (empty string if none)The Python script remaps name to component in its output for clarity.
python3 "$FETCH_NEW_PRS" 4.22.0-0.nightly-2026-01-15-114134 --format json
Expected Output:
{
"payload_tag": "4.22.0-0.nightly-2026-01-15-114134",
"total_prs": 17,
"pull_requests": [
{
"url": "https://github.com/openshift/assisted-service/pull/8594",
"pull_request_id": "8594",
"component": "agent-installer-api-server",
"description": "Create Enhancement Document for 3rd Party CNI / No CNI Support in Assisted Installer",
"bug_url": "https://redhat.atlassian.net/browse/MGMT-22584"
},
{
"url": "https://github.com/openshift/machine-config-operator/pull/5509",
"pull_request_id": "5509",
"component": "machine-config-operator",
"description": "Set `NodeDegraded` MCN condition when node state annotation is set to `Degraded`",
"bug_url": "https://redhat.atlassian.net/browse/OCPBUGS-67229"
}
]
}
python3 "$FETCH_NEW_PRS" 4.22.0-0.nightly-2026-01-15-114134 --format summary
Expected Output:
New PRs in payload 4.22.0-0.nightly-2026-01-15-114134
============================================================
Total: 17 new pull requests
agent-installer-api-server (1 PRs):
- Create Enhancement Document for 3rd Party CNI / No CNI Support in Assisted Installer [https://redhat.atlassian.net/browse/MGMT-22584]
https://github.com/openshift/assisted-service/pull/8594
hypershift (4 PRs):
- [kubevirt] Make L3 migration labeling conditional [https://redhat.atlassian.net/browse/OCPBUGS-66205]
https://github.com/openshift/hypershift/pull/7308
- feat(api): add support for graceful service account signing key rotation [https://redhat.atlassian.net/browse/CNTRLPLANE-1768]
https://github.com/openshift/hypershift/pull/7324
- Scaffold OpenShiftManager controller [https://redhat.atlassian.net/browse/API-1835]
https://github.com/openshift/hypershift/pull/7445
- use InfraStatus.APIPort for custom DNS kubeconfig [https://redhat.atlassian.net/browse/OCPBUGS-72258]
https://github.com/openshift/hypershift/pull/7470
machine-config-operator (2 PRs):
- Set `NodeDegraded` MCN condition when node state annotation is set to `Degraded` [https://redhat.atlassian.net/browse/OCPBUGS-67229]
https://github.com/openshift/machine-config-operator/pull/5509
- Prevent unnecessary systemd unit disable [https://redhat.atlassian.net/browse/OCPBUGS-58023]
https://github.com/openshift/machine-config-operator/pull/5527
Combine with the fetch-prowjob-json skill to get the payload tag from a Prow job, then find what PRs were new in that payload:
# 1. Get payload tag from prowjob.json (via fetch-prowjob-json skill)
# payload_tag = metadata.annotations["release.openshift.io/tag"]
# e.g., "4.22.0-0.ci-2026-02-06-195709"
# 2. Fetch new PRs in that payload
python3 "$FETCH_NEW_PRS" "$payload_tag" --format json
{version}-0.{stream}-{date}-{time} (e.g., 4.22.0-0.ci-2026-02-06-195709 or 4.22.0-0.nightly-2026-01-15-114134)component field (called name in the raw API) may contain multiple comma-separated component names for PRs that affect multiple componentsbug_urlfetch-prowjob-json (provides payload tag from Prow job metadata)fetch-regression-details (for correlating regressions with payload changes)/ci:analyze-regression (analyzes regressions that may be caused by new PRs)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