plugins/ci/skills/prow-job-artifact-search/SKILL.md
Search, list, and fetch artifacts from Prow CI job runs stored in GCS using the gcloud CLI
npx skillsauth add openshift-eng/ai-helpers prow-job-artifact-searchInstall 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 provides a reusable Python script for browsing, searching, and fetching artifacts from Prow CI job runs stored in the test-platform-results GCS bucket. It wraps gcloud storage commands so callers do not need to construct GCS URIs or manage the CLI directly.
Use this skill when you need to:
This skill is a building block used by other analysis workflows. Use it when you need ad-hoc artifact access that is not covered by a dedicated analysis skill.
gcloud CLI Installation
which gcloudgcloud Authentication (Optional)
test-platform-results bucket is publicly accessiblePython 3 (3.6 or later)
which python3plugins/ci/skills/prow-job-artifact-search/prow_job_artifact_search.py
List files and subdirectories at a given path within the job's artifact tree.
python3 plugins/ci/skills/prow-job-artifact-search/prow_job_artifact_search.py \
<prow-url> list [subpath]
Arguments:
prow-url (required): The Prow job URLsubpath (optional): Subdirectory path relative to the job root. If omitted, lists the job root.Examples:
# List the job root
python3 .../prow_job_artifact_search.py "https://prow.ci.openshift.org/view/gs/test-platform-results/logs/periodic-ci-.../1234567890" list
# List e2e test artifacts
python3 .../prow_job_artifact_search.py <url> list artifacts/e2e-test/openshift-e2e-test
# List gather-extra oc_cmds
python3 .../prow_job_artifact_search.py <url> list artifacts/e2e-test/gather-extra/artifacts/oc_cmds
Output:
{
"success": true,
"path": "gs://test-platform-results/logs/<job>/<id>/",
"count": 5,
"entries": [
{
"name": "artifacts/",
"path": "artifacts",
"type": "directory",
"gcs_uri": "gs://test-platform-results/logs/<job>/<id>/artifacts/"
},
{
"name": "build-log.txt",
"path": "build-log.txt",
"type": "file",
"gcs_uri": "gs://test-platform-results/logs/<job>/<id>/build-log.txt"
}
]
}
Recursively search for files matching a glob pattern under a given path.
python3 plugins/ci/skills/prow-job-artifact-search/prow_job_artifact_search.py \
<prow-url> search <pattern> [subpath]
Arguments:
prow-url (required): The Prow job URLpattern (required): Glob pattern to match. Supports ** for recursive matching and * for wildcards.subpath (optional): Subdirectory to search within. If omitted, searches from the job root.Examples:
# Find all interval JSON files
python3 .../prow_job_artifact_search.py <url> search "**/*intervals*.json"
# Find all e2e timeline files
python3 .../prow_job_artifact_search.py <url> search "**/e2e-timelines_spyglass_*.json"
# Find node-related oc_cmds output
python3 .../prow_job_artifact_search.py <url> search "**/nodes" artifacts
# Find journal logs for a specific node
python3 .../prow_job_artifact_search.py <url> search "**/*worker-c-7t6ng*" artifacts
# Find all junit files
python3 .../prow_job_artifact_search.py <url> search "**/junit*.xml"
# Find must-gather archives
python3 .../prow_job_artifact_search.py <url> search "**/must-gather*"
Output:
{
"success": true,
"pattern": "gs://test-platform-results/logs/<job>/<id>/**/*intervals*.json",
"count": 3,
"matches": [
{
"name": "e2e-timelines_spyglass_20260209-043512.json",
"path": "artifacts/e2e-test/openshift-e2e-test/e2e-timelines_spyglass_20260209-043512.json",
"type": "file",
"gcs_uri": "gs://test-platform-results/logs/<job>/<id>/artifacts/..."
}
]
}
Download and return the contents of a specific file from the job's artifacts.
python3 plugins/ci/skills/prow-job-artifact-search/prow_job_artifact_search.py \
<prow-url> fetch <filepath> [--max-bytes N]
Arguments:
prow-url (required): The Prow job URLfilepath (required): Path to the file relative to the job root--max-bytes (optional): Maximum bytes to read (default: 524288 = 512KB). Files larger than this are truncated.Examples:
# Fetch the build log
python3 .../prow_job_artifact_search.py <url> fetch build-log.txt
# Fetch a specific oc_cmds output
python3 .../prow_job_artifact_search.py <url> fetch artifacts/e2e-test/gather-extra/artifacts/oc_cmds/nodes
# Fetch a large file with higher limit
python3 .../prow_job_artifact_search.py <url> fetch artifacts/e2e-test/openshift-e2e-test/build-log.txt --max-bytes 2097152
Output:
{
"success": true,
"path": "gs://test-platform-results/logs/<job>/<id>/build-log.txt",
"size_bytes": 45230,
"truncated": false,
"max_bytes": 524288,
"content": "... file contents ..."
}
These are common artifact paths within a Prow job. The {target} is the CI workflow step name (e.g., e2e-gcp-ovn-rt-rhcos10-techpreview).
| Path | Description |
|------|-------------|
| build-log.txt | Top-level build log |
| artifacts/{target}/ | All artifacts for the test step |
| artifacts/{target}/openshift-e2e-test/ | E2E test output (build-log, junit, timelines) |
| artifacts/{target}/openshift-e2e-test/build-log.txt | E2E test console log |
| artifacts/{target}/openshift-e2e-test/artifacts/e2e-timelines_spyglass_*.json | Interval/timeline data |
| artifacts/{target}/gather-extra/artifacts/oc_cmds/ | Cluster state snapshots (nodes, pods, events, etc.) |
| artifacts/{target}/gather-extra/artifacts/pods/ | Pod logs from all namespaces |
| artifacts/{target}/gather-extra/artifacts/audit_logs/ | API server audit logs |
| artifacts/{target}/gather-extra/artifacts/journal_logs/ | Node journal logs (systemd) |
| artifacts/{target}/gather-must-gather/artifacts/ | Must-gather archives |
| prowjob.json | Job metadata (payload tag, timing, etc.) |
The script accepts both Prow UI URLs and gcsweb URLs:
https://prow.ci.openshift.org/view/gs/test-platform-results/logs/<job>/<build_id>https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/test-platform-results/logs/<job>/<build_id>When a search returns no results, the script returns success with an empty matches array:
{
"success": true,
"pattern": "...",
"count": 0,
"matches": []
}
{
"success": false,
"error": "gcloud CLI is not installed. Install from: https://cloud.google.com/sdk/docs/install"
}
{
"success": false,
"error": "gcloud storage ls failed: ...",
"path": "gs://..."
}
test-platform-results bucket is publicly accessible. No authentication is required.--no-user-output-enabled flag is used on gcloud storage cp to suppress progress bars.--max-bytes to limit download size. The default is 512KB.search command uses gcloud storage ls with glob patterns, which supports ** for recursive matching."success": false.prow-job-analyze-test-failure — Analyzes test failures using build logs and timelinesprow-job-analyze-install-failure — Analyzes install failures using installer logsprow-job-analyze-resource — Analyzes resource lifecycles using audit logsprow-job-extract-must-gather — Extracts must-gather archivesfetch-prowjob-json — Fetches prowjob.json metadatatesting
Snapshot OpenShift payload data (release controller, PR diffs, comments, CI jobs, JUnit results, regression tracking) to a local directory for offline analysis
research
Shared engine for analyzing Jira issue activity and generating status summaries
tools
This skill should be used before any Snowflake command to verify MCP connectivity, guide users through access provisioning, and set the session context. Invoke this skill proactively whenever a command needs Snowflake data access.
development
Analyze a payload snapshot to identify root causes of blocking job failures, score candidate PRs, and produce an HTML report with revert recommendations