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 metadatatools
Analyze a JIRA issue and create a pull request to solve it. Use when the user wants to implement a fix or feature described in a Jira issue, push a branch, and open a draft PR.
development
Use when a deeper level of code review is requested. Multi-agent panel code review with specialist reviewers and forced runtime reproducers for all BLOCKING bug findings. Optionally posts to GitHub/GitLab as a PENDING review.
development
Review agentic documentation — verify claims locally against source code first, then use chai-bot for cross-repo and cross-functional verification
development
Use this skill when debugging a failed Prow CI job.