fix(automation): scan all Claude PRs for review comments; drop author-based bot filter #131
1 changed files with 22 additions and 12 deletions
|
|
@ -94,21 +94,23 @@ if [ ! -d "$WORKDIR/.git" ]; then
|
|||
git -C "$WORKDIR" config user.email "claude-autofix@pelagiamarine.com"
|
||||
fi
|
||||
|
||||
# --- identity + authorization set ---
|
||||
# The bot's own login (so its acknowledgements are never treated as instructions).
|
||||
BOT_LOGIN=$(api GET "/user" | jq -r '.login // ""')
|
||||
# --- authorization set ---
|
||||
# Collaborators = users with write access. The repo owner is always allowed.
|
||||
# (The bot may post as the owner's account, so we never filter by author to spot
|
||||
# the bot's own comments -- its acknowledgements are excluded by the HANDLED_TAG
|
||||
# marker instead, and human acks lack the claude-review: marker anyway.)
|
||||
COLLAB=$(api GET "/repos/$REPO/collaborators?limit=100" \
|
||||
| jq -c --arg owner "$owner" '[.[].login] + [$owner] | unique')
|
||||
log "Authorized commenters: $(printf '%s' "$COLLAB" | jq -r 'join(", ")') (bot=$BOT_LOGIN)"
|
||||
log "Authorized commenters: $(printf '%s' "$COLLAB" | jq -r 'join(", ")')"
|
||||
|
||||
# --- find Claude-raised open PRs (head branch under the prefix, or labelled claude-pr) ---
|
||||
prs=$(api GET "/repos/$REPO/pulls?state=open&limit=50" \
|
||||
| jq -c --arg pfx "$PR_BRANCH_PREFIX" \
|
||||
'[ .[] | select((.head.ref | startswith($pfx)) or (((.labels//[])|map(.name))|index("claude-pr"))) ] | sort_by(.number)')
|
||||
prs=$(printf '%s' "$prs" | jq -c ".[:$MAX_PRS]")
|
||||
# Scan ALL matching PRs (not truncated) -- the per-run cap below limits only how
|
||||
# many PRs Claude actually RUNS on, so comment-less PRs never crowd out newer ones.
|
||||
n_prs=$(printf '%s' "$prs" | jq 'length')
|
||||
log "Found $n_prs Claude-raised open PR(s) to scan for '$MARKER' comments"
|
||||
log "Found $n_prs Claude-raised open PR(s) to scan for '$MARKER' comments (will run Claude on up to $MAX_PRS with new comments)"
|
||||
|
||||
# Pull the instruction text that follows the marker out of a comment body.
|
||||
instr_of() { # BODY -> text after the first marker occurrence, trimmed
|
||||
|
|
@ -117,6 +119,7 @@ instr_of() { # BODY -> text after the first marker occurrence, trimmed
|
|||
}
|
||||
|
||||
p=0
|
||||
processed=0
|
||||
while [ "$p" -lt "$n_prs" ]; do
|
||||
pr=$(printf '%s' "$prs" | jq -c ".[$p]")
|
||||
p=$((p+1))
|
||||
|
|
@ -133,15 +136,17 @@ while [ "$p" -lt "$n_prs" ]; do
|
|||
handled=$(printf '%s' "$conv" | jq -c --arg tag "$HANDLED_TAG" \
|
||||
'[ .[].body // "" | select(contains($tag)) | scan("(?:conv|summary|inline):[0-9]+") ] | unique')
|
||||
|
||||
# A candidate must carry the marker, NOT be one of the bot's own ack comments
|
||||
# (those carry HANDLED_TAG), and come from an authorized (collaborator) user.
|
||||
sel='select(.body != null) | select(.body | contains($m))
|
||||
| select(.user.login as $u | ($collab | index($u)))
|
||||
| select(.user.login != $bot)'
|
||||
| select(.body | contains($tag) | not)
|
||||
| select(.user.login as $u | ($collab | index($u)))'
|
||||
|
||||
conv_tasks=$(printf '%s' "$conv" | jq -c --arg m "$MARKER" --argjson collab "$COLLAB" --arg bot "$BOT_LOGIN" "
|
||||
conv_tasks=$(printf '%s' "$conv" | jq -c --arg m "$MARKER" --arg tag "$HANDLED_TAG" --argjson collab "$COLLAB" "
|
||||
[ .[] | $sel | { key:(\"conv:\"+(.id|tostring)), kind:\"conv\", id:.id, user:.user.login,
|
||||
loc:\"PR conversation\", body:.body } ]")
|
||||
|
||||
summary_tasks=$(printf '%s' "$reviews" | jq -c --arg m "$MARKER" --argjson collab "$COLLAB" --arg bot "$BOT_LOGIN" "
|
||||
summary_tasks=$(printf '%s' "$reviews" | jq -c --arg m "$MARKER" --arg tag "$HANDLED_TAG" --argjson collab "$COLLAB" "
|
||||
[ .[] | select(.body != \"\") | $sel
|
||||
| { key:(\"summary:\"+(.id|tostring)), kind:\"summary\", id:.id, user:.user.login,
|
||||
loc:\"review summary\", body:.body } ]")
|
||||
|
|
@ -151,7 +156,7 @@ while [ "$p" -lt "$n_prs" ]; do
|
|||
for rid in $(printf '%s' "$reviews" | jq -r '.[].id'); do
|
||||
rc=$(api_soft GET "/repos/$REPO/pulls/$num/reviews/$rid/comments")
|
||||
[ -z "$rc" ] && continue
|
||||
t=$(printf '%s' "$rc" | jq -c --arg m "$MARKER" --argjson collab "$COLLAB" --arg bot "$BOT_LOGIN" "
|
||||
t=$(printf '%s' "$rc" | jq -c --arg m "$MARKER" --arg tag "$HANDLED_TAG" --argjson collab "$COLLAB" "
|
||||
[ .[] | $sel
|
||||
| { key:(\"inline:\"+(.id|tostring)), kind:\"inline\", id:.id, user:.user.login,
|
||||
loc:(\"inline \"+(.path//\"?\")+\":\"+((.line // .original_line // 0)|tostring)),
|
||||
|
|
@ -164,7 +169,12 @@ while [ "$p" -lt "$n_prs" ]; do
|
|||
fresh=$(printf '%s' "$fresh" | jq -c ".[:$MAX_COMMENTS]")
|
||||
n=$(printf '%s' "$fresh" | jq 'length')
|
||||
if [ "$n" -eq 0 ]; then log " no new '$MARKER' comments"; continue; fi
|
||||
log " $n new '$MARKER' comment(s) to address"
|
||||
if [ "$processed" -ge "$MAX_PRS" ]; then
|
||||
log " $n new '$MARKER' comment(s) but per-run cap ($MAX_PRS) reached; deferring PR #$num to next run"
|
||||
continue
|
||||
fi
|
||||
processed=$((processed+1))
|
||||
log " $n new '$MARKER' comment(s) to address (PR $processed/$MAX_PRS this run)"
|
||||
|
||||
# ---- check out the PR branch in the work clone ----
|
||||
git -C "$WORKDIR" fetch origin -q
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue