Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion ci-operator/step-registry/sippy-e2e/OWNERS
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
reviewers:
approvers:
- deads2k
- deepsm007
- dgoodwin
- neisw
- petr-muller
- stbenjam
- DennisPeriquet
- xueqzhan
- sosiouxme
- smg247
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
reviewers:
approvers:
- deads2k
- deepsm007
- dgoodwin
- neisw
- petr-muller
- stbenjam
- xueqzhan
- sosiouxme
- smg247
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#!/bin/bash

set -o nounset
set -o errexit
set -o pipefail

# Only run on presubmit jobs (PRs)
if [[ "${JOB_TYPE:-}" != "presubmit" ]]; then
echo "Not a presubmit job. Skipping."
exit 0
fi

# Load GitHub token
set +x
if [[ -f "${GITHUB_TOKEN_PATH}" ]]; then
export GITHUB_TOKEN
GITHUB_TOKEN=$(cat "${GITHUB_TOKEN_PATH}")
echo "GitHub token loaded."
else
echo "No GitHub token found at ${GITHUB_TOKEN_PATH}. Cannot comment on PR."
exit 0
fi

GCS_BUCKET="test-platform-results"
GCS_PATH="gs://${GCS_BUCKET}/pr-logs/pull/${REPO_OWNER}_${REPO_NAME}/${PULL_NUMBER}/${JOB_NAME}/${BUILD_ID}/artifacts"
PROW_URL="https://prow.ci.openshift.org/view/gs/${GCS_BUCKET}/pr-logs/pull/${REPO_OWNER}_${REPO_NAME}/${PULL_NUMBER}/${JOB_NAME}/${BUILD_ID}"

# Check finished.json for each step to find failures
echo "Checking for failed steps..."
FAILED_STEPS=()

while IFS= read -r finished; do
result=$(gsutil cat "${finished}" 2>/dev/null | jq -r '.result')
step_name=$(basename "$(dirname "${finished}")")
if [[ "${result}" == "FAILURE" ]]; then
echo "FAILED: ${step_name}"
FAILED_STEPS+=("${step_name}")
else
echo "PASSED: ${step_name}"
fi
done < <(gsutil ls "${GCS_PATH}/**/finished.json" 2>/dev/null)

if [[ ${#FAILED_STEPS[@]} -eq 0 ]]; then
echo "No failed steps found. Skipping analysis."
exit 0
fi

echo "Found ${#FAILED_STEPS[@]} failed step(s): ${FAILED_STEPS[*]}"

WORKDIR=$(mktemp -d /tmp/claude-analysis-XXXXXX)
cd "${WORKDIR}"

copy_reports() {
cp "${WORKDIR}"/*.md "${ARTIFACT_DIR}/" 2>/dev/null || true
cp "${WORKDIR}"/*.html "${ARTIFACT_DIR}/" 2>/dev/null || true

# Archive Claude session for continue-session support
CLAUDE_HOME="/home/claude/.claude"
if [[ -d "${CLAUDE_HOME}/projects" ]]; then
echo "Archiving Claude session logs..."
if tar -czf "${ARTIFACT_DIR}/claude-sessions-$(date +%Y%m%d-%H%M%S).tar.gz" -C "${CLAUDE_HOME}" projects/ 2>/dev/null; then
touch "${SHARED_DIR}/claude-session-available"
fi
fi
}
trap copy_reports EXIT TERM INT

ALLOWED_TOOLS="Bash Read Grep Glob WebFetch"

PROMPT="You are analyzing a failed CI e2e test for the ${REPO_OWNER}/${REPO_NAME} project.

## Job Information
- PR: https://github.com/${REPO_OWNER}/${REPO_NAME}/pull/${PULL_NUMBER}
- Prow Job: ${PROW_URL}
- Failed steps: ${FAILED_STEPS[*]}

## Artifacts
The GCS artifacts for this job are at:
${GCS_PATH}/

Use gsutil to browse and read artifacts (build logs, test artifacts, etc.) from the failed steps.

## Instructions
1. Browse the artifacts from the failed steps to understand what went wrong.
2. Fetch the PR diff with: gh pr diff ${PULL_NUMBER} --repo ${REPO_OWNER}/${REPO_NAME}
3. Determine whether the PR's changes are likely responsible for the failure, or if this looks like a pre-existing/flaky issue.
4. Leave a comment on the PR using: gh pr comment ${PULL_NUMBER} --repo ${REPO_OWNER}/${REPO_NAME} --body \"\$(cat <<'COMMENT'
<your analysis>
COMMENT
)\"

Your PR comment should be concise and helpful:
- Start with a one-line summary (e.g. 'The e2e failure appears to be caused by ...' or 'This failure looks unrelated to this PR')
- Include the specific test(s) that failed and why
- If the PR is responsible, point to the specific change that likely caused it
- If the PR is NOT responsible, briefly explain what the actual issue appears to be
- Link to the Prow job: ${PROW_URL}
- Keep it short - engineers are busy

Important: Do NOT make any code changes. Only analyze and comment."

echo "Invoking Claude for failure analysis..."
timeout 600 claude \
--model "${CLAUDE_MODEL}" \
--allowedTools "${ALLOWED_TOOLS}" \
--output-format stream-json \
--max-turns 50 \
-p "${PROMPT}" \
--verbose 2>&1 | tee "${ARTIFACT_DIR}/claude-analysis.log" || true

echo "Analysis complete."
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"path": "sippy-e2e/sippy-e2e-claude-post-analysis/sippy-e2e-sippy-e2e-claude-post-analysis-ref.yaml",
"owners": {
"approvers": [
"deads2k",
"deepsm007",
"dgoodwin",
"neisw",
"petr-muller",
"stbenjam",
"xueqzhan",
"sosiouxme",
"smg247"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
ref:
as: sippy-e2e-sippy-e2e-claude-post-analysis
from_image:
namespace: ci
name: claude-ai-helpers
tag: latest
best_effort: true
commands: sippy-e2e-sippy-e2e-claude-post-analysis-commands.sh
credentials:
- namespace: test-credentials
name: hypershift-team-claude-prow
mount_path: /var/run/claude-code-service-account
- namespace: test-credentials
name: claude-payload-agent-github-token
mount_path: /var/run/github-token
env:
- name: CLAUDE_CODE_USE_VERTEX
default: "1"
- name: CLOUD_ML_REGION
default: "us-east5"
- name: ANTHROPIC_VERTEX_PROJECT_ID
default: "itpc-gcp-hybrid-pe-eng-claude"
- name: GOOGLE_APPLICATION_CREDENTIALS
default: "/var/run/claude-code-service-account/claude-prow"
- name: CLAUDE_MODEL
default: "claude-sonnet-4-6"
- name: GITHUB_TOKEN_PATH
default: "/var/run/github-token/token"
resources:
requests:
cpu: 500m
memory: 512Mi
timeout: 15m0s
grace_period: 1m0s
documentation: |-
Best-effort post step that uses Claude AI to analyze e2e test failures
in presubmit jobs and leaves a comment on the PR explaining the failure
and whether the PR's changes are likely responsible.
9 changes: 8 additions & 1 deletion ci-operator/step-registry/sippy-e2e/sippy-e2e-setup/OWNERS
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
reviewers:
approvers:
- deads2k
- deepsm007
- dgoodwin
- neisw
- petr-muller
- stbenjam
- DennisPeriquet
- xueqzhan
- sosiouxme
- smg247
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
"path": "sippy-e2e/sippy-e2e-setup/sippy-e2e-sippy-e2e-setup-ref.yaml",
"owners": {
"approvers": [
"deads2k",
"deepsm007",
"dgoodwin",
"neisw",
"petr-muller",
"stbenjam",
"DennisPeriquet"
"xueqzhan",
"sosiouxme",
"smg247"
]
}
}
9 changes: 8 additions & 1 deletion ci-operator/step-registry/sippy-e2e/sippy-e2e-test/OWNERS
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
reviewers:
approvers:
- deads2k
- deepsm007
- dgoodwin
- neisw
- petr-muller
- stbenjam
- DennisPeriquet
- xueqzhan
- sosiouxme
- smg247
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
"path": "sippy-e2e/sippy-e2e-test/sippy-e2e-sippy-e2e-test-ref.yaml",
"owners": {
"approvers": [
"deads2k",
"deepsm007",
"dgoodwin",
"neisw",
"petr-muller",
"stbenjam",
"DennisPeriquet"
"xueqzhan",
"sosiouxme",
"smg247"
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
"path": "sippy-e2e/sippy-e2e-workflow.yaml",
"owners": {
"approvers": [
"deads2k",
"deepsm007",
"dgoodwin",
"neisw",
"petr-muller",
"stbenjam",
"DennisPeriquet"
"xueqzhan",
"sosiouxme",
"smg247"
]
}
}
3 changes: 3 additions & 0 deletions ci-operator/step-registry/sippy-e2e/sippy-e2e-workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@ workflow:
- ref: sippy-e2e-sippy-e2e-setup
test:
- ref: sippy-e2e-sippy-e2e-test
post:
- ref: sippy-e2e-sippy-e2e-claude-post-analysis
- ref: openshift-claude-post
documentation: |-
Workflow to run the sippy e2e tests.