master
sh 53 lines 1.71 KB
Raw
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)"'