|
| 1 | +# Reference config for the oape-review-handler Prow presubmit job. |
| 2 | +# |
| 3 | +# This file is NOT consumed by CI directly. It documents the changes |
| 4 | +# needed in a NEW openshift/release PR to enable: |
| 5 | +# |
| 6 | +# /test oape-review-handler |
| 7 | +# |
| 8 | +# This is SEPARATE from the oape-ci-monitor PR (#80727). |
| 9 | +# |
| 10 | +# Apply these changes to: |
| 11 | +# ci-operator/config/openshift/must-gather-operator/openshift-must-gather-operator-master.yaml |
| 12 | +# |
| 13 | +# After editing the ci-operator config, run: |
| 14 | +# make jobs |
| 15 | +# to regenerate the presubmits YAML, then open a PR to openshift/release. |
| 16 | + |
| 17 | +# ============================================================================ |
| 18 | +# STEP 1: Add review-handler-agent image to the "images.items" array |
| 19 | +# ============================================================================ |
| 20 | +# This is a SEPARATE image from ci-monitor-agent. It clones from |
| 21 | +# neha037/oape-ai-e2e branch oape-review-handler and includes Node.js + Claude CLI. |
| 22 | + |
| 23 | +image_reference: |
| 24 | +- dockerfile_literal: |- |
| 25 | + FROM registry.access.redhat.com/ubi9/go-toolset |
| 26 | + USER 0 |
| 27 | + RUN dnf install -y git make jq && \ |
| 28 | + dnf install -y 'dnf-command(config-manager)' && \ |
| 29 | + dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo && \ |
| 30 | + dnf install -y gh && \ |
| 31 | + dnf clean all |
| 32 | + RUN dnf module reset -y nodejs && \ |
| 33 | + dnf module enable -y nodejs:20 && \ |
| 34 | + dnf install -y nodejs npm && \ |
| 35 | + npm install -g @anthropic-ai/claude-code && \ |
| 36 | + dnf clean all |
| 37 | + WORKDIR /app |
| 38 | + RUN git clone --depth 1 -b oape-review-handler https://github.com/neha037/oape-ai-e2e.git /tmp/oape && \ |
| 39 | + cp -r /tmp/oape/scripts /app/scripts && \ |
| 40 | + cp -r /tmp/oape/plugins /plugins && \ |
| 41 | + mkdir -p /config && cp -r /tmp/oape/deploy/config/* /config/ && \ |
| 42 | + rm -rf /tmp/oape |
| 43 | + RUN go install golang.org/x/tools/cmd/goimports@v0.33.0 && \ |
| 44 | + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/v2.1.6/install.sh | sh -s -- -b /usr/local/bin v2.1.6 |
| 45 | + RUN git config --global user.name "openshift-app-platform-shift-bot" && \ |
| 46 | + git config --global user.email "267347085+openshift-app-platform-shift-bot@users.noreply.github.com" |
| 47 | + RUN chmod -R g=u /opt/app-root/src |
| 48 | + USER 1001 |
| 49 | + to: review-handler-agent |
| 50 | + |
| 51 | +# Also add to promotion.to[0].excluded_images: |
| 52 | +# - review-handler-agent |
| 53 | + |
| 54 | +# ============================================================================ |
| 55 | +# STEP 2: Add the oape-review-handler test step to the "tests:" array |
| 56 | +# ============================================================================ |
| 57 | + |
| 58 | +test_step_reference: |
| 59 | +- always_run: false |
| 60 | + as: oape-review-handler |
| 61 | + optional: true |
| 62 | + steps: |
| 63 | + test: |
| 64 | + - as: review |
| 65 | + commands: | |
| 66 | + set -euo pipefail |
| 67 | +
|
| 68 | + echo "[setup] Starting oape-review-handler for ${REPO_OWNER}/${REPO_NAME} PR#${PULL_NUMBER}" |
| 69 | +
|
| 70 | + # --- Rehearsal detection --- |
| 71 | + if [[ "${REPO_NAME}" == "release" && "${REPO_OWNER}" == "openshift" ]]; then |
| 72 | + echo "[setup] Detected openshift/release context — switching to test target" |
| 73 | + export REPO_OWNER="openshift" |
| 74 | + export REPO_NAME="must-gather-operator" |
| 75 | + TEST_PR=$(curl -s "https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/pulls?state=open&per_page=1" \ |
| 76 | + | python3 -c "import sys,json; data=json.load(sys.stdin); print(data[0]['number'] if data else '')" 2>/dev/null || echo "") |
| 77 | + if [[ -z "$TEST_PR" ]]; then |
| 78 | + echo "[setup] No open PRs found — skipping" |
| 79 | + exit 0 |
| 80 | + fi |
| 81 | + export PULL_NUMBER="$TEST_PR" |
| 82 | + echo "[setup] Testing against ${REPO_OWNER}/${REPO_NAME}#${PULL_NUMBER}" |
| 83 | + fi |
| 84 | +
|
| 85 | + # --- GitHub auth: App token with GITHUB_TOKEN fallback --- |
| 86 | + USE_APP_TOKEN="false" |
| 87 | + if [[ -f /var/run/github-app/app-id && -f /var/run/github-app/private-key.pem ]]; then |
| 88 | + echo "[auth] Attempting GitHub App token..." |
| 89 | + APP_ID=$(cat /var/run/github-app/app-id) |
| 90 | + PEM_PATH="/var/run/github-app/private-key.pem" |
| 91 | + HEADER=$(printf '{"alg":"RS256","typ":"JWT"}' | openssl base64 -e -A | tr '+/' '-_' | tr -d '=') |
| 92 | + NOW=$(date +%s); EXP=$((NOW + 300)) |
| 93 | + PAYLOAD=$(printf '{"iat":%d,"exp":%d,"iss":"%s"}' "$NOW" "$EXP" "$APP_ID" | openssl base64 -e -A | tr '+/' '-_' | tr -d '=') |
| 94 | + SIGNATURE=$(printf '%s' "${HEADER}.${PAYLOAD}" | openssl dgst -sha256 -sign "$PEM_PATH" -binary | openssl base64 -e -A | tr '+/' '-_' | tr -d '=') |
| 95 | + JWT="${HEADER}.${PAYLOAD}.${SIGNATURE}" |
| 96 | + INSTALL_RESPONSE=$(curl -s -w "\n%{http_code}" -H "Authorization: Bearer ${JWT}" -H "Accept: application/vnd.github+json" \ |
| 97 | + "https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/installation") |
| 98 | + HTTP_CODE=$(echo "$INSTALL_RESPONSE" | tail -1) |
| 99 | + INSTALL_BODY=$(echo "$INSTALL_RESPONSE" | sed '$d') |
| 100 | + if [[ "$HTTP_CODE" -eq 200 ]]; then |
| 101 | + INST_ID=$(echo "$INSTALL_BODY" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])") |
| 102 | + TOKEN_RESPONSE=$(curl -s -w "\n%{http_code}" -X POST -H "Authorization: Bearer ${JWT}" -H "Accept: application/vnd.github+json" \ |
| 103 | + "https://api.github.com/app/installations/${INST_ID}/access_tokens") |
| 104 | + T_CODE=$(echo "$TOKEN_RESPONSE" | tail -1) |
| 105 | + T_BODY=$(echo "$TOKEN_RESPONSE" | sed '$d') |
| 106 | + if [[ "$T_CODE" -eq 201 ]]; then |
| 107 | + export GH_TOKEN=$(echo "$T_BODY" | python3 -c "import sys,json; print(json.load(sys.stdin)['token'])") |
| 108 | + USE_APP_TOKEN="true" |
| 109 | + echo "[auth] GitHub App token generated successfully" |
| 110 | + else |
| 111 | + echo "[auth] WARN: App token creation failed (HTTP ${T_CODE}), falling back to GITHUB_TOKEN" |
| 112 | + fi |
| 113 | + else |
| 114 | + echo "[auth] WARN: App not installed on ${REPO_OWNER}/${REPO_NAME} (HTTP ${HTTP_CODE}), falling back to GITHUB_TOKEN" |
| 115 | + fi |
| 116 | + else |
| 117 | + echo "[auth] GitHub App credentials not mounted, using GITHUB_TOKEN" |
| 118 | + fi |
| 119 | + if [[ "$USE_APP_TOKEN" != "true" ]]; then |
| 120 | + if [[ -z "${GH_TOKEN:-}" && -z "${GITHUB_TOKEN:-}" ]]; then |
| 121 | + echo "[auth] ERROR: No GitHub token available" >&2 |
| 122 | + exit 1 |
| 123 | + fi |
| 124 | + export GH_TOKEN="${GH_TOKEN:-${GITHUB_TOKEN}}" |
| 125 | + fi |
| 126 | +
|
| 127 | + # --- GCP auth for Claude (Vertex AI) --- |
| 128 | + export GOOGLE_APPLICATION_CREDENTIALS="/var/run/gcloud-adc/application_default_credentials.json" |
| 129 | + export CLAUDE_CODE_USE_VERTEX="1" |
| 130 | + export CLOUD_ML_REGION="global" |
| 131 | + export ANTHROPIC_VERTEX_PROJECT_ID="itpc-gcp-hcm-pe-eng-claude" |
| 132 | +
|
| 133 | + # --- Run review handler --- |
| 134 | + export PR_URL="https://github.com/${REPO_OWNER}/${REPO_NAME}/pull/${PULL_NUMBER}" |
| 135 | + export PLUGINS_DIR="/plugins/oape/skills" |
| 136 | +
|
| 137 | + gh auth setup-git |
| 138 | + /app/scripts/pr-agent/review-handler.sh --pr-url "$PR_URL" |
| 139 | + credentials: |
| 140 | + - mount_path: /var/run/gcloud-adc |
| 141 | + name: oap-lts-claude-gcp-vertex-sa |
| 142 | + namespace: test-credentials |
| 143 | + - mount_path: /var/run/github-app |
| 144 | + name: openshift-app-platform-shift-github-bot |
| 145 | + namespace: test-credentials |
| 146 | + from: review-handler-agent |
| 147 | + resources: |
| 148 | + requests: |
| 149 | + cpu: "1" |
| 150 | + memory: 500Mi |
| 151 | + timeout: 1h0m0s |
| 152 | + |
| 153 | +# ============================================================================ |
| 154 | +# STEP 3: Trigger the job |
| 155 | +# ============================================================================ |
| 156 | +# On any PR in openshift/must-gather-operator, comment: |
| 157 | +# |
| 158 | +# /test oape-review-handler |
| 159 | +# |
| 160 | +# For rehearsal (from openshift/release PR): |
| 161 | +# |
| 162 | +# /pj-rehearse oape-review-handler |
| 163 | +# |
| 164 | +# ============================================================================ |
| 165 | +# PREREQUISITE: The oape-review-handler branch on neha037/oape-ai-e2e |
| 166 | +# must contain the review handler scripts, since the dockerfile_literal |
| 167 | +# clones from that branch. |
| 168 | +# ============================================================================ |
0 commit comments