#!/usr/bin/env bash # Regression harness for durable Gitea PR review comments (#812). set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" WORK_DIR="${MOSAIC_TEST_WORK_DIR:-$PWD/.mosaic-test-work/pr-review-gitea-comment}" REPO_DIR="$WORK_DIR/repo" BIN_DIR="$WORK_DIR/bin" TEA_LOG="$WORK_DIR/tea.log" CURL_LOG="$WORK_DIR/curl.log" OUTPUT_FILE="$WORK_DIR/output.log" CREDENTIALS_FILE="$WORK_DIR/credentials.json" cleanup() { rm -rf "$WORK_DIR" } trap cleanup EXIT mkdir -p "$REPO_DIR" "$BIN_DIR" git -C "$REPO_DIR" init -q git -C "$REPO_DIR" remote add origin https://git.mosaicstack.dev/mosaicstack/stack.git write_credentials() { local configured_url="$1" CONFIGURED_GITEA_URL="$configured_url" python3 - "$CREDENTIALS_FILE" <<'PY' import json import os import sys with open(sys.argv[1], "w", encoding="utf-8") as credentials: json.dump({ "gitea": { "mosaicstack": { "url": os.environ["CONFIGURED_GITEA_URL"], "token": "test-only-placeholder", } } }, credentials) PY } cat > "$BIN_DIR/tea" <<'SH' #!/usr/bin/env bash set -euo pipefail printf '%s\n' "$*" >> "$PR_REVIEW_TEA_LOG" if [[ "$*" == "login list --output json" ]]; then printf '%s\n' '[{"name":"mosaicstack","url":"https://git.mosaicstack.dev"}]' exit 0 fi case "${PR_REVIEW_TEST_MODE:-}" in approve) [[ "$*" == "pr approve 123 --repo mosaicstack/stack --login mosaicstack" ]] || exit 90 ;; request-changes) [[ "$*" == "pr reject 123 --repo mosaicstack/stack --login mosaicstack --comment changes-required" ]] || exit 91 ;; legacy-fallback|comment-success|http-success|prefix-success|subpath-success|port-success|scp-ssh-success|url-ssh-success|write-transport-failure|write-http-failure|readback-failure) if [[ "$*" == pr\ comment* ]]; then # tea v0.11.1 treats the nonexistent subcommand as `tea pr list` and exits 0. printf '%s\n' 'INDEX TITLE STATE' exit 0 fi echo "Unexpected tea command: $*" >&2 exit 92 ;; *) exit 95 ;; esac SH chmod +x "$BIN_DIR/tea" cat > "$BIN_DIR/curl" <<'SH' #!/usr/bin/env bash set -euo pipefail output_file="" method="GET" payload="" url="" while [[ $# -gt 0 ]]; do case "$1" in -o) output_file="$2" shift 2 ;; -w|-H) shift 2 ;; -X) method="$2" shift 2 ;; -d|--data) payload="$2" shift 2 ;; -s|-S|-sS) shift ;; http://*|https://*) url="$1" shift ;; *) shift ;; esac done printf '%s %s\n' "$method" "$url" >> "$PR_REVIEW_CURL_LOG" write_response() { local status="$1" body="$2" [[ -n "$output_file" ]] || exit 96 printf '%s' "$body" > "$output_file" printf '%s' "$status" } case "${PR_REVIEW_TEST_MODE:-}" in legacy-fallback|write-transport-failure) echo "simulated transport failure" >&2 exit 7 ;; write-http-failure) write_response 500 '{"message":"simulated rejection"}' ;; comment-success|http-success|prefix-success|subpath-success|port-success|scp-ssh-success|url-ssh-success|readback-failure) if [[ "$method" == "POST" && "$url" == "$PR_REVIEW_EXPECTED_API_BASE/issues/123/comments" ]]; then PR_REVIEW_PAYLOAD="$payload" python3 - <<'PY' import json import os assert json.loads(os.environ["PR_REVIEW_PAYLOAD"]) == {"body": os.environ["PR_REVIEW_EXPECTED_BODY"]} PY response=$(python3 - <<'PY' import json import os print(json.dumps({"id": 456, "body": os.environ["PR_REVIEW_EXPECTED_BODY"]})) PY ) write_response 201 "$response" elif [[ "$method" == "GET" && "$url" == "$PR_REVIEW_EXPECTED_API_BASE/issues/comments/456" ]]; then if [[ "$PR_REVIEW_TEST_MODE" == "readback-failure" ]]; then body="different-body" else body="$PR_REVIEW_EXPECTED_BODY" fi response=$(PR_REVIEW_BODY="$body" python3 - <<'PY' import json import os print(json.dumps({ "id": 456, "body": os.environ["PR_REVIEW_BODY"], "issue_url": os.environ["PR_REVIEW_EXPECTED_API_BASE"] + "/issues/123", })) PY ) write_response 200 "$response" else echo "Unexpected curl request: $method $url" >&2 exit 97 fi ;; *) exit 98 ;; esac SH chmod +x "$BIN_DIR/curl" run_review() { local mode="$1" action="$2" comment="${3:-}" local configured_url="${4:-https://git.mosaicstack.dev}" local remote_url="${5:-https://git.mosaicstack.dev/mosaicstack/stack.git}" local expected_repo="${6:-mosaicstack/stack}" local expected_api_base="${configured_url%/}/api/v1/repos/$expected_repo" git -C "$REPO_DIR" remote set-url origin "$remote_url" write_credentials "$configured_url" : > "$TEA_LOG" : > "$CURL_LOG" : > "$OUTPUT_FILE" ( cd "$REPO_DIR" PATH="$BIN_DIR:$PATH" \ MOSAIC_CREDENTIALS_FILE="$CREDENTIALS_FILE" \ PR_REVIEW_TEA_LOG="$TEA_LOG" \ PR_REVIEW_CURL_LOG="$CURL_LOG" \ PR_REVIEW_TEST_MODE="$mode" \ PR_REVIEW_EXPECTED_BODY="$comment" \ PR_REVIEW_EXPECTED_API_BASE="$expected_api_base" \ "$SCRIPT_DIR/pr-review.sh" -n 123 -a "$action" ${comment:+-c "$comment"} ) > "$OUTPUT_FILE" 2>&1 } run_review approve approve grep -q '^pr approve 123 --repo mosaicstack/stack --login mosaicstack$' "$TEA_LOG" grep -q 'Approved Gitea PR #123' "$OUTPUT_FILE" run_review request-changes request-changes changes-required grep -q '^pr reject 123 --repo mosaicstack/stack --login mosaicstack --comment changes-required$' "$TEA_LOG" grep -q 'Requested changes on Gitea PR #123' "$OUTPUT_FILE" if run_review legacy-fallback comment durable-body; then echo "The old nonexistent tea pr comment fallback returned success" >&2 cat "$OUTPUT_FILE" >&2 exit 1 fi if grep -q '^pr comment ' "$TEA_LOG"; then echo "Wrapper invoked unsupported tea pr comment" >&2 exit 1 fi if grep -q 'Added comment to Gitea PR' "$OUTPUT_FILE"; then echo "Wrapper reported success without durable persistence" >&2 exit 1 fi complex_body=$'durable "body"\n-- marker' run_review comment-success comment "$complex_body" grep -q '^POST https://git.mosaicstack.dev/api/v1/repos/mosaicstack/stack/issues/123/comments$' "$CURL_LOG" grep -q '^GET https://git.mosaicstack.dev/api/v1/repos/mosaicstack/stack/issues/comments/456$' "$CURL_LOG" grep -q 'Added and verified comment on Gitea PR #123' "$OUTPUT_FILE" if [[ -s "$TEA_LOG" ]]; then echo "REST comment path unexpectedly invoked tea" >&2 cat "$TEA_LOG" >&2 exit 1 fi run_review http-success comment durable-body http://git.mosaicstack.dev grep -q '^POST http://git.mosaicstack.dev/api/v1/repos/mosaicstack/stack/issues/123/comments$' "$CURL_LOG" grep -q '^GET http://git.mosaicstack.dev/api/v1/repos/mosaicstack/stack/issues/comments/456$' "$CURL_LOG" run_review prefix-success comment durable-body https://git.mosaicstack.dev/gitea/ grep -q '^POST https://git.mosaicstack.dev/gitea/api/v1/repos/mosaicstack/stack/issues/123/comments$' "$CURL_LOG" grep -q '^GET https://git.mosaicstack.dev/gitea/api/v1/repos/mosaicstack/stack/issues/comments/456$' "$CURL_LOG" run_review subpath-success comment durable-body https://git.example/gitea https://git.example/gitea/owner/repo.git owner/repo grep -q '^POST https://git.example/gitea/api/v1/repos/owner/repo/issues/123/comments$' "$CURL_LOG" grep -q '^GET https://git.example/gitea/api/v1/repos/owner/repo/issues/comments/456$' "$CURL_LOG" if grep -q '/repos/gitea/owner/repo/' "$CURL_LOG"; then echo "Configured Gitea path prefix leaked into the repository slug" >&2 exit 1 fi run_review port-success comment durable-body http://git.example:3000 http://git.example:3000/owner/repo.git owner/repo grep -q '^POST http://git.example:3000/api/v1/repos/owner/repo/issues/123/comments$' "$CURL_LOG" grep -q '^GET http://git.example:3000/api/v1/repos/owner/repo/issues/comments/456$' "$CURL_LOG" run_review scp-ssh-success comment durable-body https://git.example git@git.example:owner/repo.git owner/repo grep -q '^POST https://git.example/api/v1/repos/owner/repo/issues/123/comments$' "$CURL_LOG" run_review url-ssh-success comment durable-body https://git.example ssh://git@git.example/owner/repo.git owner/repo grep -q '^POST https://git.example/api/v1/repos/owner/repo/issues/123/comments$' "$CURL_LOG" if run_review write-transport-failure comment durable-body; then echo "Expected provider transport failure to return nonzero" >&2 exit 1 fi if run_review write-http-failure comment durable-body; then echo "Expected non-201 provider write to return nonzero" >&2 exit 1 fi if run_review readback-failure comment durable-body; then echo "Expected mismatched provider read-back to return nonzero" >&2 exit 1 fi if grep -q 'Added and verified comment' "$OUTPUT_FILE"; then echo "Read-back mismatch reported durable success" >&2 exit 1 fi echo "pr-review.sh durable Gitea comment regression passed"