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
168 changes: 168 additions & 0 deletions docs/prow-review-handler-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
# Reference config for the oape-review-handler Prow presubmit job.
#
# This file is NOT consumed by CI directly. It documents the changes
# needed in a NEW openshift/release PR to enable:
#
# /test oape-review-handler
#
# This is SEPARATE from the oape-ci-monitor PR (#80727).
#
# Apply these changes to:
# ci-operator/config/openshift/must-gather-operator/openshift-must-gather-operator-master.yaml
#
# After editing the ci-operator config, run:
# make jobs
# to regenerate the presubmits YAML, then open a PR to openshift/release.

# ============================================================================
# STEP 1: Add review-handler-agent image to the "images.items" array
# ============================================================================
# This is a SEPARATE image from ci-monitor-agent. It clones from
# neha037/oape-ai-e2e branch oape-review-handler and includes Node.js + Claude CLI.

image_reference:
- dockerfile_literal: |-
FROM registry.access.redhat.com/ubi9/go-toolset
USER 0
RUN dnf install -y git make jq && \
dnf install -y 'dnf-command(config-manager)' && \
dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo && \
dnf install -y gh && \
dnf clean all
RUN dnf module reset -y nodejs && \
dnf module enable -y nodejs:20 && \
dnf install -y nodejs npm && \
npm install -g @anthropic-ai/claude-code && \
dnf clean all
WORKDIR /app
RUN git clone --depth 1 -b oape-review-handler https://github.com/neha037/oape-ai-e2e.git /tmp/oape && \
cp -r /tmp/oape/scripts /app/scripts && \
cp -r /tmp/oape/plugins /plugins && \
mkdir -p /config && cp -r /tmp/oape/deploy/config/* /config/ && \
rm -rf /tmp/oape
RUN go install golang.org/x/tools/cmd/goimports@v0.33.0 && \
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/v2.1.6/install.sh | sh -s -- -b /usr/local/bin v2.1.6
RUN git config --global user.name "openshift-app-platform-shift-bot" && \
git config --global user.email "267347085+openshift-app-platform-shift-bot@users.noreply.github.com"
RUN chmod -R g=u /opt/app-root/src
USER 1001
to: review-handler-agent

# Also add to promotion.to[0].excluded_images:
# - review-handler-agent

# ============================================================================
# STEP 2: Add the oape-review-handler test step to the "tests:" array
# ============================================================================

test_step_reference:
- always_run: false
as: oape-review-handler
optional: true
steps:
test:
- as: review
commands: |
set -euo pipefail

echo "[setup] Starting oape-review-handler for ${REPO_OWNER}/${REPO_NAME} PR#${PULL_NUMBER}"

# --- Rehearsal detection ---
if [[ "${REPO_NAME}" == "release" && "${REPO_OWNER}" == "openshift" ]]; then
echo "[setup] Detected openshift/release context — switching to test target"
export REPO_OWNER="openshift"
export REPO_NAME="must-gather-operator"
TEST_PR=$(curl -s "https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/pulls?state=open&per_page=1" \
| python3 -c "import sys,json; data=json.load(sys.stdin); print(data[0]['number'] if data else '')" 2>/dev/null || echo "")
if [[ -z "$TEST_PR" ]]; then
echo "[setup] No open PRs found — skipping"
exit 0
fi
export PULL_NUMBER="$TEST_PR"
echo "[setup] Testing against ${REPO_OWNER}/${REPO_NAME}#${PULL_NUMBER}"
fi

# --- GitHub auth: App token with GITHUB_TOKEN fallback ---
USE_APP_TOKEN="false"
if [[ -f /var/run/github-app/app-id && -f /var/run/github-app/private-key.pem ]]; then
echo "[auth] Attempting GitHub App token..."
APP_ID=$(cat /var/run/github-app/app-id)
PEM_PATH="/var/run/github-app/private-key.pem"
HEADER=$(printf '{"alg":"RS256","typ":"JWT"}' | openssl base64 -e -A | tr '+/' '-_' | tr -d '=')
NOW=$(date +%s); EXP=$((NOW + 300))
PAYLOAD=$(printf '{"iat":%d,"exp":%d,"iss":"%s"}' "$NOW" "$EXP" "$APP_ID" | openssl base64 -e -A | tr '+/' '-_' | tr -d '=')
SIGNATURE=$(printf '%s' "${HEADER}.${PAYLOAD}" | openssl dgst -sha256 -sign "$PEM_PATH" -binary | openssl base64 -e -A | tr '+/' '-_' | tr -d '=')
JWT="${HEADER}.${PAYLOAD}.${SIGNATURE}"
INSTALL_RESPONSE=$(curl -s -w "\n%{http_code}" -H "Authorization: Bearer ${JWT}" -H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/installation")
HTTP_CODE=$(echo "$INSTALL_RESPONSE" | tail -1)
INSTALL_BODY=$(echo "$INSTALL_RESPONSE" | sed '$d')
if [[ "$HTTP_CODE" -eq 200 ]]; then
INST_ID=$(echo "$INSTALL_BODY" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
TOKEN_RESPONSE=$(curl -s -w "\n%{http_code}" -X POST -H "Authorization: Bearer ${JWT}" -H "Accept: application/vnd.github+json" \
"https://api.github.com/app/installations/${INST_ID}/access_tokens")
T_CODE=$(echo "$TOKEN_RESPONSE" | tail -1)
T_BODY=$(echo "$TOKEN_RESPONSE" | sed '$d')
if [[ "$T_CODE" -eq 201 ]]; then
export GH_TOKEN=$(echo "$T_BODY" | python3 -c "import sys,json; print(json.load(sys.stdin)['token'])")
USE_APP_TOKEN="true"
echo "[auth] GitHub App token generated successfully"
else
echo "[auth] WARN: App token creation failed (HTTP ${T_CODE}), falling back to GITHUB_TOKEN"
fi
else
echo "[auth] WARN: App not installed on ${REPO_OWNER}/${REPO_NAME} (HTTP ${HTTP_CODE}), falling back to GITHUB_TOKEN"
fi
else
echo "[auth] GitHub App credentials not mounted, using GITHUB_TOKEN"
fi
if [[ "$USE_APP_TOKEN" != "true" ]]; then
if [[ -z "${GH_TOKEN:-}" && -z "${GITHUB_TOKEN:-}" ]]; then
echo "[auth] ERROR: No GitHub token available" >&2
exit 1
fi
export GH_TOKEN="${GH_TOKEN:-${GITHUB_TOKEN}}"
fi

# --- GCP auth for Claude (Vertex AI) ---
export GOOGLE_APPLICATION_CREDENTIALS="/var/run/gcloud-adc/application_default_credentials.json"
export CLAUDE_CODE_USE_VERTEX="1"
export CLOUD_ML_REGION="global"
export ANTHROPIC_VERTEX_PROJECT_ID="itpc-gcp-hcm-pe-eng-claude"

# --- Run review handler ---
export PR_URL="https://github.com/${REPO_OWNER}/${REPO_NAME}/pull/${PULL_NUMBER}"
export PLUGINS_DIR="/plugins/oape/skills"

gh auth setup-git
/app/scripts/pr-agent/review-handler.sh --pr-url "$PR_URL"
credentials:
- mount_path: /var/run/gcloud-adc
name: oap-lts-claude-gcp-vertex-sa
namespace: test-credentials
- mount_path: /var/run/github-app
name: openshift-app-platform-shift-github-bot
namespace: test-credentials
from: review-handler-agent
resources:
requests:
cpu: "1"
memory: 500Mi
timeout: 1h0m0s

# ============================================================================
# STEP 3: Trigger the job
# ============================================================================
# On any PR in openshift/must-gather-operator, comment:
#
# /test oape-review-handler
#
# For rehearsal (from openshift/release PR):
#
# /pj-rehearse oape-review-handler
#
# ============================================================================
# PREREQUISITE: The oape-review-handler branch on neha037/oape-ai-e2e
# must contain the review handler scripts, since the dockerfile_literal
# clones from that branch.
# ============================================================================
Loading