@@ -3,21 +3,28 @@ set -euo pipefail
33
44echo " === PR #${PR_NUMBER} : Addressing review comments ==="
55
6- # Collect inline review comments with file context and comment id
6+ # Collect inline review comments (exclude our own bot replies)
77COMMENTS=$( gh api " repos/${REPO} /pulls/${PR_NUMBER} /comments" \
8- --jq ' [.[] | select(.user.login != "github-actions[bot]") | {id, path, line, body, user: .user.login}]' 2> /dev/null || echo ' []' )
8+ --jq ' [.[] | select(.user.login != "github-actions[bot]" and (.in_reply_to_id == null) ) | {id, path, line, body, user: .user.login}]' 2> /dev/null || echo ' []' )
99
10- COMMENT_COUNT=$( echo " $COMMENTS " | jq ' length' )
11- if [ " $COMMENT_COUNT " -eq 0 ]; then
10+ # Also get PR-level reviews
11+ PR_REVIEWS=$( gh api " repos/${REPO} /pulls/${PR_NUMBER} /reviews" \
12+ --jq ' [.[] | select(.user.login != "github-actions[bot]" and .body != "") | {id, user: .user.login, state: .state, body}]' 2> /dev/null || echo ' []' )
13+
14+ INLINE_COUNT=$( echo " $COMMENTS " | jq ' length' )
15+ REVIEW_COUNT=$( echo " $PR_REVIEWS " | jq ' length' )
16+ TOTAL=$(( INLINE_COUNT + REVIEW_COUNT))
17+
18+ if [ " $TOTAL " -eq 0 ]; then
1219 echo " No review comments to address"
1320 exit 0
1421fi
1522
16- echo " Found ${COMMENT_COUNT} review comment(s)"
23+ echo " Found ${INLINE_COUNT} inline comment(s), ${REVIEW_COUNT} review (s)"
1724
18- # Also get PR-level review comments
19- PR_REVIEWS =$( gh api " repos/ ${REPO} /pulls/ ${PR_NUMBER} /reviews " \
20- -- jq ' [ .[] | select(.user.login != "github-actions[bot]" and .body != "") | {id, user: .user.login, state: .state, body}] ' 2> /dev/null || echo ' [] ' )
25+ # Format for prompt
26+ FORMATTED =$( echo " $COMMENTS " | jq -r ' .[] | "Comment #\(.id) by \(.user) on \(.path):\(.line):\n\(.body)\n---" ' )
27+ PR_REVIEW_TEXT= $( echo " $PR_REVIEWS " | jq -r ' .[] | "Review by \(.user) (\(. state)):\n\(. body)\n---" ' )
2128
2229# Get PR info
2330PR_TITLE=$( gh pr view " $PR_NUMBER " --repo " $REPO " --json title --jq ' .title' )
@@ -26,100 +33,34 @@ PR_TITLE=$(gh pr view "$PR_NUMBER" --repo "$REPO" --json title --jq '.title')
2633git config user.name " github-actions[bot]"
2734git config user.email " 41898282+github-actions[bot]@users.noreply.github.com"
2835
29- # --- Step 1: Triage each comment (accept/reject + plan) ---
30- echo " --- Triaging comments ---"
31- FORMATTED=$( echo " $COMMENTS " | jq -r ' .[] | "Comment #\(.id) by \(.user) on \(.path):\(.line)\n\(.body)\n---"' )
32- PR_REVIEW_TEXT=$( echo " $PR_REVIEWS " | jq -r ' .[] | "Review by \(.user) (\(.state)):\n\(.body)\n---"' )
36+ # Verify evot works
37+ echo " --- Testing evot ---"
38+ evot -p " say ok" --max-turns 1 --max-duration 10 2>&1 | tail -3 || echo " evot test failed"
3339
34- TRIAGE_OUTPUT=$( evot -p " You are triaging review comments on a documentation PR.
40+ # --- Run evot to triage + fix in one pass ---
41+ echo " --- Processing review feedback ---"
42+ OUTPUT=$( evot -p " You are addressing review feedback on a documentation PR.
3543
3644PR #${PR_NUMBER} : ${PR_TITLE}
3745
3846The Databend source code is available at _databend/src/ for reference.
3947
40- ## Inline comments:
48+ ## Inline review comments:
4149${FORMATTED}
4250
4351## PR-level reviews:
4452${PR_REVIEW_TEXT}
4553
46- For each comment, decide whether to accept or reject it.
47- Output a JSON array:
48- [
49- {\" id\" : <comment_id>, \" accepted\" : true/false, \" reason\" : \" brief explanation\" },
50- ...
51- ]
52-
53- Accept if the feedback is valid and actionable. Reject if it's incorrect, out of scope, or already addressed." \
54- --output-format stream-json \
55- --max-turns 1 --max-duration 120 2>&1 || true)
56-
57- TRIAGE_TEXT=$( echo " $TRIAGE_OUTPUT " | grep ' "run_finished"' | tail -1 | jq -r ' .payload.text // ""' 2> /dev/null || true)
58-
59- # Reply to each inline comment with triage result
60- TRIAGE_JSON=$( echo " $TRIAGE_TEXT " | python3 -c "
61- import sys, json, re
62- t = sys.stdin.read()
63- m = re.search(r'\[.*\]', t, re.DOTALL)
64- if m:
65- try:
66- arr = json.loads(m.group())
67- print(json.dumps(arr))
68- except: print('[]')
69- else: print('[]')
70- " 2> /dev/null || echo ' []' )
71-
72- TRIAGE_COUNT=$( echo " $TRIAGE_JSON " | jq ' length' )
73- for i in $( seq 0 $(( TRIAGE_COUNT - 1 )) ) ; do
74- CID=$( echo " $TRIAGE_JSON " | jq -r " .[$i ].id" )
75- ACCEPTED=$( echo " $TRIAGE_JSON " | jq -r " .[$i ].accepted" )
76- REASON=$( echo " $TRIAGE_JSON " | jq -r " .[$i ].reason" )
77-
78- if [ " $ACCEPTED " = " true" ]; then
79- REPLY=" ✅ **Accepted** — ${REASON} "
80- else
81- REPLY=" ❌ **Declined** — ${REASON} "
82- fi
83-
84- gh api " repos/${REPO} /pulls/${PR_NUMBER} /comments/${CID} /replies" \
85- -f body=" $REPLY " 2> /dev/null || true
86- done
87-
88- # Check if any comments were accepted
89- ACCEPTED_COUNT=$( echo " $TRIAGE_JSON " | jq ' [.[] | select(.accepted == true)] | length' )
90- if [ " $ACCEPTED_COUNT " -eq 0 ]; then
91- echo " No comments accepted, nothing to fix"
92- exit 0
93- fi
94-
95- # --- Step 2: Apply accepted fixes ---
96- echo " --- Applying ${ACCEPTED_COUNT} accepted fix(es) ---"
97- ACCEPTED_COMMENTS=$( echo " $TRIAGE_JSON " | jq -r ' [.[] | select(.accepted == true)] | .[] | "Comment #\(.id): \(.reason)"' )
98-
99- # Get the full comment bodies for accepted ones
100- ACCEPTED_IDS=$( echo " $TRIAGE_JSON " | jq -r ' [.[] | select(.accepted == true) | .id] | @csv' )
101- ACCEPTED_DETAILS=$( echo " $COMMENTS " | jq -r --argjson triage " $TRIAGE_JSON " '
102- [.[] | . as $c | if ($triage | map(select(.id == $c.id and .accepted == true)) | length > 0) then . else empty end]
103- | .[] | "File: \(.path), Line: \(.line)\n\(.body)\n---"
104- ' )
105-
106- OUTPUT=$( evot -p " You are fixing a documentation PR based on accepted review feedback.
107-
108- PR #${PR_NUMBER} : ${PR_TITLE}
109-
110- The Databend source code is available at _databend/src/ for reference.
111-
112- ## Accepted feedback to address:
113- ${ACCEPTED_DETAILS}
114-
11554Task:
116- 1. Read each accepted comment and the referenced file.
117- 2. Make the requested changes.
118- 3. If you modify docs/en/, also update the corresponding docs/cn/ file.
55+ 1. For each comment, decide: accept (valid, actionable) or decline (incorrect, out of scope, already addressed).
56+ 2. Output your triage as a summary first.
57+ 3. Then make the accepted changes to the files.
58+ 4. If you modify docs/en/, also update the corresponding docs/cn/ file.
11959
12060Rules:
12161- Only modify files under docs/en/ and docs/cn/.
122- - Do NOT run git, gh, or any shell commands that modify the repository state." \
62+ - Do NOT run git, gh, or any shell commands that modify the repository state.
63+ - The CI script handles git commit, push, and PR replies." \
12364 --output-format stream-json \
12465 --max-turns 300 --max-duration 600 2>&1 || true)
12566
@@ -129,14 +70,36 @@ STATS=$(echo "$OUTPUT" | grep '"run_finished"' | tail -1 | jq -r '{
12970 duration_s: ((.payload.duration_ms // 0) / 1000 | floor),
13071 input: .payload.usage.input,
13172 output: .payload.usage.output
132- }' 2> /dev/null || echo ' {}' )
133- echo " Stats: $( echo " $STATS " | jq -c .) "
73+ }' 2> /dev/null || echo ' {"turns":"?","duration_s":0,"input":"?","output":"?"}' )
74+
75+ TURNS=$( echo " $STATS " | jq -r ' .turns // "?"' )
76+ DURATION=$( echo " $STATS " | jq -r ' .duration_s // 0' )
77+ INPUT_T=$( echo " $STATS " | jq -r ' .input // "?"' )
78+ OUTPUT_T=$( echo " $STATS " | jq -r ' .output // "?"' )
79+ echo " Stats: turns=${TURNS} duration=${DURATION} s tokens=${INPUT_T} /${OUTPUT_T} "
80+
81+ # Extract assistant log
82+ ASSISTANT_LOG=$( echo " $OUTPUT " | grep ' "assistant_completed"' | jq -r '
83+ .payload.content[]? | select(.type=="text") | .text // empty
84+ ' 2> /dev/null | head -100)
13485
13586# Check for changes
13687if git diff --quiet && git diff --cached --quiet && [ -z " $( git ls-files --others --exclude-standard docs/) " ]; then
137- echo " No changes made "
88+ echo " No file changes "
13889 gh pr comment " $PR_NUMBER " --repo " $REPO " \
139- --body " Reviewed the feedback — accepted ${ACCEPTED_COUNT} comment(s) but no file changes were needed." || true
90+ --body " ### Review feedback processed
91+
92+ Reviewed ${TOTAL} comment(s) — no file changes needed.
93+
94+ Turns: ${TURNS} | Duration: ${DURATION} s | Tokens: ${INPUT_T} in / ${OUTPUT_T} out
95+
96+ <details><summary>Agent log</summary>
97+
98+ \`\`\`
99+ ${ASSISTANT_LOG}
100+ \`\`\`
101+
102+ </details>" || true
140103 exit 0
141104fi
142105
@@ -145,27 +108,16 @@ git add docs/
145108git commit -m " docs: address review feedback on PR #${PR_NUMBER} " || exit 0
146109git push origin HEAD --force-with-lease
147110
148- # Extract assistant log
149- ASSISTANT_LOG=$( echo " $OUTPUT " | grep ' "assistant_completed"' | jq -r '
150- .payload.content[]? | select(.type=="text") | .text // empty
151- ' 2> /dev/null | head -80)
152-
153- TURNS=$( echo " $STATS " | jq -r ' .turns // "?"' )
154- DURATION=$( echo " $STATS " | jq -r ' .duration_s // 0' )
155- INPUT_T=$( echo " $STATS " | jq -r ' .input // "?"' )
156- OUTPUT_T=$( echo " $STATS " | jq -r ' .output // "?"' )
157-
158- # Summary comment on PR
159- COMMENT_BODY=" ### Addressed review feedback
111+ # Comment on PR
112+ gh pr comment " $PR_NUMBER " --repo " $REPO " \
113+ --body " ### Addressed review feedback
160114
161- **Accepted:** ${ACCEPTED_COUNT} / ${COMMENT_COUNT} comments | Turns: ${TURNS} | Duration: ${DURATION} s | Tokens: ${INPUT_T} in / ${OUTPUT_T} out
115+ Reviewed ${TOTAL} comment(s) | Turns: ${TURNS} | Duration: ${DURATION} s | Tokens: ${INPUT_T} in / ${OUTPUT_T} out
162116
163117<details><summary>Agent log</summary>
164118
165119\`\`\`
166120${ASSISTANT_LOG}
167121\`\`\`
168122
169- </details>"
170-
171- gh pr comment " $PR_NUMBER " --repo " $REPO " --body " $COMMENT_BODY " || true
123+ </details>" || true
0 commit comments