From f49dd8e25263b5ea356d5f40c3c003e701ed5192 Mon Sep 17 00:00:00 2001 From: Bryan Cox Date: Mon, 10 Aug 2026 10:58:06 -0400 Subject: [PATCH 1/4] review-agent: switch hypershift workflow from GitHub App to PAT auth The GitHub App token exchange in the trigger step was failing (exit code 6), causing the presubmit to report failure even though the periodic review agent job succeeded. Switch to PAT auth via jira-solve-bot, matching the pattern already used by the installer review-agent workflow. Co-Authored-By: Claude Opus 4.6 --- .../hypershift-review-agent-workflow.yaml | 8 +-- ...ypershift-review-agent-trigger-commands.sh | 68 ++++++------------- .../hypershift-review-agent-trigger-ref.yaml | 5 ++ 3 files changed, 29 insertions(+), 52 deletions(-) diff --git a/ci-operator/step-registry/hypershift/review-agent/hypershift-review-agent-workflow.yaml b/ci-operator/step-registry/hypershift/review-agent/hypershift-review-agent-workflow.yaml index a4cac607409b0..ae3d1ced04a80 100644 --- a/ci-operator/step-registry/hypershift/review-agent/hypershift-review-agent-workflow.yaml +++ b/ci-operator/step-registry/hypershift/review-agent/hypershift-review-agent-workflow.yaml @@ -2,20 +2,20 @@ workflow: as: hypershift-review-agent steps: pre: - - ref: jira-agent-github-app-auth - ref: review-agent-setup test: - ref: review-agent-process post: - ref: review-agent-report env: - REVIEW_AGENT_FORK_REPO: "https://github.com/hypershift-community/hypershift" - REVIEW_AGENT_AUTH_MODE: "app" + REVIEW_AGENT_AUTH_MODE: "pat" + REVIEW_AGENT_FORK_ORG: "jira-solve-bot" REVIEW_AGENT_UPSTREAM_REPO: "openshift/hypershift" documentation: |- HyperShift-specific wrapper for the generic review-agent workflow. Delegates to the generic review-agent steps with HyperShift-specific - configuration (fork repo, upstream repo). + configuration. Uses PAT auth via the jira-solve-bot account, which + auto-forks repos as needed. Credentials: Uses hypershift-team-claude-prow (configured in generic step refs). diff --git a/ci-operator/step-registry/hypershift/review-agent/trigger/hypershift-review-agent-trigger-commands.sh b/ci-operator/step-registry/hypershift/review-agent/trigger/hypershift-review-agent-trigger-commands.sh index 128b407a843d8..63614fd69af6d 100755 --- a/ci-operator/step-registry/hypershift/review-agent/trigger/hypershift-review-agent-trigger-commands.sh +++ b/ci-operator/step-registry/hypershift/review-agent/trigger/hypershift-review-agent-trigger-commands.sh @@ -16,39 +16,13 @@ echo "Triggering review agent for PR #$PR_NUMBER" CREDS_DIR="/var/run/claude-code-service-account" TOKEN_FILE="${CREDS_DIR}/gangway-token" -APP_ID_FILE="${CREDS_DIR}/app-id" -INSTALLATION_ID_UPSTREAM_FILE="${CREDS_DIR}/o-h-installation-id" -PRIVATE_KEY_FILE="${CREDS_DIR}/private-key" +PAT_FILE="${CREDS_DIR}/${REVIEW_AGENT_PAT_KEY:-gh-pat}" if [ ! -f "$TOKEN_FILE" ]; then echo "ERROR: Gangway token not found at ${TOKEN_FILE}" exit 1 fi -generate_github_token() { - local INSTALL_ID=$1 - local APP_ID - APP_ID=$(cat "$APP_ID_FILE") - local NOW - NOW=$(date +%s) - local IAT=$((NOW - 60)) - local EXP=$((NOW + 600)) - - local HEADER - HEADER=$(echo -n '{"alg":"RS256","typ":"JWT"}' | base64 | tr -d '=' | tr '/+' '_-' | tr -d '\n') - local PAYLOAD - PAYLOAD=$(echo -n "{\"iat\":${IAT},\"exp\":${EXP},\"iss\":\"${APP_ID}\"}" | base64 | tr -d '=' | tr '/+' '_-' | tr -d '\n') - local SIGNATURE - SIGNATURE=$(echo -n "${HEADER}.${PAYLOAD}" | openssl dgst -sha256 -sign "$PRIVATE_KEY_FILE" | base64 | tr -d '=' | tr '/+' '_-' | tr -d '\n') - local JWT="${HEADER}.${PAYLOAD}.${SIGNATURE}" - - curl -s -X POST \ - -H "Authorization: Bearer ${JWT}" \ - -H "Accept: application/vnd.github+json" \ - "https://api.github.com/app/installations/${INSTALL_ID}/access_tokens" \ - | jq -r '.token' -} - POST_DATA=$(jq -n --arg pr "$PR_NUMBER" \ '{job_execution_type: "1", pod_spec_options: {envs: {MULTISTAGE_PARAM_OVERRIDE_REVIEW_AGENT_TARGET_PR: $pr}}}') @@ -110,32 +84,30 @@ for ((i=1; i<=10; i++)); do done set -x -# Post a comment on the PR -if [ -f "$APP_ID_FILE" ] && [ -f "$INSTALLATION_ID_UPSTREAM_FILE" ] && [ -f "$PRIVATE_KEY_FILE" ]; then - echo "Generating GitHub token to post PR comment..." - INSTALLATION_ID_UPSTREAM=$(cat "$INSTALLATION_ID_UPSTREAM_FILE") - GITHUB_TOKEN=$(generate_github_token "$INSTALLATION_ID_UPSTREAM") +# Post a comment on the PR using the PAT +if [ -f "$PAT_FILE" ]; then + echo "Posting PR comment..." + [[ $- == *x* ]] && _was_tracing=true || _was_tracing=false + set +x - if [ -n "$GITHUB_TOKEN" ] && [ "$GITHUB_TOKEN" != "null" ]; then - if [ -n "$JOB_URL" ]; then - COMMENT_BODY="Review agent triggered. [View job](${JOB_URL})" - else - COMMENT_BODY="Review agent triggered (Gangway execution ID: \`${JOB_ID}\`). The Prow job has not started yet — check the [job history](https://prow.ci.openshift.org/job-history/gs/test-platform-results/logs/${PERIODIC_JOB_NAME}) for the run once it begins." - fi + GITHUB_TOKEN_PAT=$(cat "$PAT_FILE") - set +x - curl -s -X POST \ - -H "Authorization: token ${GITHUB_TOKEN}" \ - -H "Accept: application/vnd.github+json" \ - "https://api.github.com/repos/${REVIEW_AGENT_UPSTREAM_REPO}/issues/${PR_NUMBER}/comments" \ - -d "$(jq -n --arg body "$COMMENT_BODY" '{body: $body}')" > /dev/null - set -x - echo "Comment posted on PR #$PR_NUMBER" + if [ -n "$JOB_URL" ]; then + COMMENT_BODY="Review agent triggered. [View job](${JOB_URL})" else - echo "WARNING: Failed to generate GitHub token for PR comment" + COMMENT_BODY="Review agent triggered (Gangway execution ID: \`${JOB_ID}\`). The Prow job has not started yet — check the [job history](https://prow.ci.openshift.org/job-history/gs/test-platform-results/logs/${PERIODIC_JOB_NAME}) for the run once it begins." fi + + curl --fail --silent --show-error -X POST \ + -H "Authorization: token ${GITHUB_TOKEN_PAT}" \ + -H "Accept: application/vnd.github+json" \ + "https://api.github.com/repos/${REVIEW_AGENT_UPSTREAM_REPO}/issues/${PR_NUMBER}/comments" \ + -d "$(jq -n --arg body "$COMMENT_BODY" '{body: $body}')" > /dev/null + + $_was_tracing && set -x || true + echo "Comment posted on PR #$PR_NUMBER" else - echo "WARNING: GitHub App credentials not available, skipping PR comment" + echo "WARNING: PAT not found at ${PAT_FILE}, skipping PR comment" fi echo "=== Trigger Complete ===" diff --git a/ci-operator/step-registry/hypershift/review-agent/trigger/hypershift-review-agent-trigger-ref.yaml b/ci-operator/step-registry/hypershift/review-agent/trigger/hypershift-review-agent-trigger-ref.yaml index 1774c12edc5a0..516be2cfaa1fb 100644 --- a/ci-operator/step-registry/hypershift/review-agent/trigger/hypershift-review-agent-trigger-ref.yaml +++ b/ci-operator/step-registry/hypershift/review-agent/trigger/hypershift-review-agent-trigger-ref.yaml @@ -15,6 +15,11 @@ ref: default: "openshift/hypershift" documentation: |- Upstream owner/repo for posting PR comments (e.g. openshift/hypershift). + - name: REVIEW_AGENT_PAT_KEY + default: "gh-pat" + documentation: |- + Key name in the credential secret for the GitHub PAT used to post + PR comments. resources: requests: cpu: 100m From 040e06a24c6170fd53ef2d853a080366c047fef3 Mon Sep 17 00:00:00 2001 From: Bryan Cox Date: Mon, 10 Aug 2026 10:59:52 -0400 Subject: [PATCH 2/4] TEMP: hardcode PR #9102 for rehearsal testing Remove before merge. Co-Authored-By: Claude Opus 4.6 --- .../hypershift-review-agent-trigger-commands.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ci-operator/step-registry/hypershift/review-agent/trigger/hypershift-review-agent-trigger-commands.sh b/ci-operator/step-registry/hypershift/review-agent/trigger/hypershift-review-agent-trigger-commands.sh index 63614fd69af6d..0347cd049f64e 100755 --- a/ci-operator/step-registry/hypershift/review-agent/trigger/hypershift-review-agent-trigger-commands.sh +++ b/ci-operator/step-registry/hypershift/review-agent/trigger/hypershift-review-agent-trigger-commands.sh @@ -3,11 +3,13 @@ set -euo pipefail echo "=== HyperShift Review Agent Trigger ===" -PR_NUMBER="${PULL_NUMBER:-}" -if [ -z "$PR_NUMBER" ]; then - echo "ERROR: PULL_NUMBER not set. This step must run as a presubmit." - exit 1 -fi +# TODO: remove hardcoded PR before merge +PR_NUMBER="9102" +# PR_NUMBER="${PULL_NUMBER:-}" +# if [ -z "$PR_NUMBER" ]; then +# echo "ERROR: PULL_NUMBER not set. This step must run as a presubmit." +# exit 1 +# fi if [ -z "${REVIEW_AGENT_UPSTREAM_REPO:-}" ]; then echo "ERROR: REVIEW_AGENT_UPSTREAM_REPO is required (e.g. openshift/hypershift)" exit 1 From e870b891eee04106110b0a74b69ae6ce87ac7a0f Mon Sep 17 00:00:00 2001 From: Bryan Cox Date: Mon, 10 Aug 2026 11:09:51 -0400 Subject: [PATCH 3/4] review-agent: guard against empty PAT file in trigger step Co-Authored-By: Claude Opus 4.6 --- .../hypershift-review-agent-workflow.yaml | 1 + ...ypershift-review-agent-trigger-commands.sh | 29 +++++++++++-------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/ci-operator/step-registry/hypershift/review-agent/hypershift-review-agent-workflow.yaml b/ci-operator/step-registry/hypershift/review-agent/hypershift-review-agent-workflow.yaml index ae3d1ced04a80..d8851566f6a05 100644 --- a/ci-operator/step-registry/hypershift/review-agent/hypershift-review-agent-workflow.yaml +++ b/ci-operator/step-registry/hypershift/review-agent/hypershift-review-agent-workflow.yaml @@ -11,6 +11,7 @@ workflow: REVIEW_AGENT_AUTH_MODE: "pat" REVIEW_AGENT_FORK_ORG: "jira-solve-bot" REVIEW_AGENT_UPSTREAM_REPO: "openshift/hypershift" + REVIEW_AGENT_TARGET_PR: "9102" documentation: |- HyperShift-specific wrapper for the generic review-agent workflow. diff --git a/ci-operator/step-registry/hypershift/review-agent/trigger/hypershift-review-agent-trigger-commands.sh b/ci-operator/step-registry/hypershift/review-agent/trigger/hypershift-review-agent-trigger-commands.sh index 0347cd049f64e..a7049d7f5732a 100755 --- a/ci-operator/step-registry/hypershift/review-agent/trigger/hypershift-review-agent-trigger-commands.sh +++ b/ci-operator/step-registry/hypershift/review-agent/trigger/hypershift-review-agent-trigger-commands.sh @@ -94,20 +94,25 @@ if [ -f "$PAT_FILE" ]; then GITHUB_TOKEN_PAT=$(cat "$PAT_FILE") - if [ -n "$JOB_URL" ]; then - COMMENT_BODY="Review agent triggered. [View job](${JOB_URL})" - else - COMMENT_BODY="Review agent triggered (Gangway execution ID: \`${JOB_ID}\`). The Prow job has not started yet — check the [job history](https://prow.ci.openshift.org/job-history/gs/test-platform-results/logs/${PERIODIC_JOB_NAME}) for the run once it begins." - fi + if [ -n "$GITHUB_TOKEN_PAT" ]; then + if [ -n "$JOB_URL" ]; then + COMMENT_BODY="Review agent triggered. [View job](${JOB_URL})" + else + COMMENT_BODY="Review agent triggered (Gangway execution ID: \`${JOB_ID}\`). The Prow job has not started yet — check the [job history](https://prow.ci.openshift.org/job-history/gs/test-platform-results/logs/${PERIODIC_JOB_NAME}) for the run once it begins." + fi - curl --fail --silent --show-error -X POST \ - -H "Authorization: token ${GITHUB_TOKEN_PAT}" \ - -H "Accept: application/vnd.github+json" \ - "https://api.github.com/repos/${REVIEW_AGENT_UPSTREAM_REPO}/issues/${PR_NUMBER}/comments" \ - -d "$(jq -n --arg body "$COMMENT_BODY" '{body: $body}')" > /dev/null + curl --fail --silent --show-error -X POST \ + -H "Authorization: token ${GITHUB_TOKEN_PAT}" \ + -H "Accept: application/vnd.github+json" \ + "https://api.github.com/repos/${REVIEW_AGENT_UPSTREAM_REPO}/issues/${PR_NUMBER}/comments" \ + -d "$(jq -n --arg body "$COMMENT_BODY" '{body: $body}')" > /dev/null - $_was_tracing && set -x || true - echo "Comment posted on PR #$PR_NUMBER" + $_was_tracing && set -x || true + echo "Comment posted on PR #$PR_NUMBER" + else + $_was_tracing && set -x || true + echo "WARNING: PAT file is empty, skipping PR comment" + fi else echo "WARNING: PAT not found at ${PAT_FILE}, skipping PR comment" fi From 48a1fd5a20ff3bdd67955ab69b285ada9344acac Mon Sep 17 00:00:00 2001 From: Bryan Cox Date: Mon, 10 Aug 2026 12:35:23 -0400 Subject: [PATCH 4/4] review-agent: drop hardcoded test PR Co-Authored-By: Claude Opus 4.6 --- .../hypershift-review-agent-workflow.yaml | 1 - .../hypershift-review-agent-trigger-commands.sh | 12 +++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/ci-operator/step-registry/hypershift/review-agent/hypershift-review-agent-workflow.yaml b/ci-operator/step-registry/hypershift/review-agent/hypershift-review-agent-workflow.yaml index d8851566f6a05..ae3d1ced04a80 100644 --- a/ci-operator/step-registry/hypershift/review-agent/hypershift-review-agent-workflow.yaml +++ b/ci-operator/step-registry/hypershift/review-agent/hypershift-review-agent-workflow.yaml @@ -11,7 +11,6 @@ workflow: REVIEW_AGENT_AUTH_MODE: "pat" REVIEW_AGENT_FORK_ORG: "jira-solve-bot" REVIEW_AGENT_UPSTREAM_REPO: "openshift/hypershift" - REVIEW_AGENT_TARGET_PR: "9102" documentation: |- HyperShift-specific wrapper for the generic review-agent workflow. diff --git a/ci-operator/step-registry/hypershift/review-agent/trigger/hypershift-review-agent-trigger-commands.sh b/ci-operator/step-registry/hypershift/review-agent/trigger/hypershift-review-agent-trigger-commands.sh index a7049d7f5732a..7d3926c583915 100755 --- a/ci-operator/step-registry/hypershift/review-agent/trigger/hypershift-review-agent-trigger-commands.sh +++ b/ci-operator/step-registry/hypershift/review-agent/trigger/hypershift-review-agent-trigger-commands.sh @@ -3,13 +3,11 @@ set -euo pipefail echo "=== HyperShift Review Agent Trigger ===" -# TODO: remove hardcoded PR before merge -PR_NUMBER="9102" -# PR_NUMBER="${PULL_NUMBER:-}" -# if [ -z "$PR_NUMBER" ]; then -# echo "ERROR: PULL_NUMBER not set. This step must run as a presubmit." -# exit 1 -# fi +PR_NUMBER="${PULL_NUMBER:-}" +if [ -z "$PR_NUMBER" ]; then + echo "ERROR: PULL_NUMBER not set. This step must run as a presubmit." + exit 1 +fi if [ -z "${REVIEW_AGENT_UPSTREAM_REPO:-}" ]; then echo "ERROR: REVIEW_AGENT_UPSTREAM_REPO is required (e.g. openshift/hypershift)" exit 1