| 1 | #!/usr/bin/env bash |
| 2 | # Reply inside an existing review-comment thread. |
| 3 | # |
| 4 | # Usage: |
| 5 | # reply-thread.sh <pr-number> <comment-id> <body-text> |
| 6 | # reply-thread.sh <pr-number> <comment-id> @<file> |
| 7 | # |
| 8 | # <comment-id> is the REST databaseId of any comment in the thread (e.g. one |
| 9 | # of `databaseId` from review-threads.json -> .comments.nodes[]). The new |
| 10 | # reply is anchored under that thread automatically. |
| 11 | # |
| 12 | # To resolve the thread after replying, call resolve-thread.sh with the |
| 13 | # thread's GraphQL node id. |
| 14 | |
| 15 | set -euo pipefail |
| 16 | |
| 17 | # shellcheck source=./_lib.sh |
| 18 | # shellcheck disable=SC1091 |
| 19 | source "$(dirname "$0")/_lib.sh" |
| 20 | pr_require_gh |
| 21 | |
| 22 | PR="${1:?usage: $0 <pr-number> <comment-id> <body>}" |
| 23 | pr_require_numeric "${PR}" |
| 24 | COMMENT_ID="${2:?usage}" |
| 25 | BODY_ARG="${3:?usage}" |
| 26 | |
| 27 | pr_require_numeric "${COMMENT_ID}" "comment-id" |
| 28 | |
| 29 | if [[ "${BODY_ARG}" == @* ]]; then |
| 30 | body_file="${BODY_ARG#@}" |
| 31 | if [[ ! -f "${body_file}" || ! -r "${body_file}" || ! -s "${body_file}" ]]; then |
| 32 | echo -e "${PR_RED}[ERROR]${PR_NC} body file not a readable, non-empty regular file: '${body_file}'" >&2 |
| 33 | exit 1 |
| 34 | fi |
| 35 | BODY="$(cat "${body_file}")" |
| 36 | else |
| 37 | BODY="${BODY_ARG}" |
| 38 | fi |
| 39 | |
| 40 | # Strip ALL whitespace (spaces, tabs, newlines, carriage returns) before |
| 41 | # the empty-body check; previous version stripped spaces only and would |
| 42 | # accept a tab-only or newline-only body. |
| 43 | if [[ -z "${BODY//[[:space:]]/}" ]]; then |
| 44 | echo -e "${PR_RED}[ERROR]${PR_NC} Empty body (whitespace-only)." >&2 |
| 45 | exit 2 |
| 46 | fi |
| 47 | |
| 48 | SLUG="$(pr_require_slug)" |
| 49 | echo -e "${PR_GRAY}[reply-thread] PR ${SLUG}#${PR} reply to comment ${COMMENT_ID}${PR_NC}" >&2 |
| 50 | |
| 51 | gh api --method POST "/repos/${SLUG}/pulls/${PR}/comments/${COMMENT_ID}/replies" \ |
| 52 | -f body="${BODY}" \ |
| 53 | --jq '"posted reply id=\(.id) url=\(.html_url)"' |