Skip to content

Commit be2371a

Browse files
authored
fix: reply-to-mention doesn't work for review comments on forks (#196)
Signed-off-by: Derek Misler <derek.misler@docker.com>
1 parent 4f5e1f3 commit be2371a

2 files changed

Lines changed: 96 additions & 6 deletions

File tree

.github/workflows/review-pr.yml

Lines changed: 93 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ jobs:
8282
pr-head-sha: ${{ steps.read.outputs.pr-head-sha }}
8383
comment-json: ${{ steps.read.outputs.comment-json }}
8484
comment-author: ${{ steps.read.outputs.comment-author }}
85+
comment-in-reply-to-id: ${{ steps.read.outputs.comment-in-reply-to-id }}
86+
comment-has-mention: ${{ steps.read.outputs.comment-has-mention }}
87+
comment-is-review-cmd: ${{ steps.read.outputs.comment-is-review-cmd }}
88+
comment-author-type: ${{ steps.read.outputs.comment-author-type }}
8589
steps:
8690
- name: Setup credentials
8791
uses: docker/cagent-action/setup-credentials@c22076b8856ee12d9b4c4685bb49cf26eb974079 # v1.5.0
@@ -127,6 +131,10 @@ jobs:
127131
echo 'COMMENT_JSON_EOF'
128132
} >> $GITHUB_OUTPUT
129133
echo "comment-author=$(jq -r '.user.login' /tmp/context/comment.json)" >> $GITHUB_OUTPUT
134+
echo "comment-in-reply-to-id=$(jq -r '.in_reply_to_id // empty' /tmp/context/comment.json)" >> $GITHUB_OUTPUT
135+
echo "comment-has-mention=$(jq -r 'if (.body | contains("@docker-agent")) then "true" else "false" end' /tmp/context/comment.json)" >> $GITHUB_OUTPUT
136+
echo "comment-is-review-cmd=$(jq -r 'if (.body | startswith("/review")) then "true" else "false" end' /tmp/context/comment.json)" >> $GITHUB_OUTPUT
137+
echo "comment-author-type=$(jq -r '.user.type // empty' /tmp/context/comment.json)" >> $GITHUB_OUTPUT
130138
fi
131139
132140
review:
@@ -364,7 +372,7 @@ jobs:
364372
if: |
365373
always() && needs.resolve-context.result != 'failure' && (
366374
(github.event_name == 'pull_request_review_comment' && github.event.comment.in_reply_to_id && github.event.comment.user.login != 'docker-agent' && github.event.comment.user.type != 'Bot') ||
367-
(needs.resolve-context.result == 'success' && needs.resolve-context.outputs.trigger-event == 'pull_request_review_comment' && needs.resolve-context.outputs.comment-author != 'docker-agent')
375+
(needs.resolve-context.result == 'success' && needs.resolve-context.outputs.trigger-event == 'pull_request_review_comment' && needs.resolve-context.outputs.comment-in-reply-to-id != '' && needs.resolve-context.outputs.comment-author != 'docker-agent')
368376
)
369377
runs-on: ubuntu-latest
370378
permissions:
@@ -712,22 +720,95 @@ jobs:
712720
contains(github.event.comment.body, '@docker-agent') &&
713721
!startsWith(github.event.comment.body, '/review') &&
714722
github.event.comment.user.login != 'docker-agent' &&
715-
github.event.comment.user.type != 'Bot')
723+
github.event.comment.user.type != 'Bot') ||
724+
(needs.resolve-context.result == 'success' &&
725+
needs.resolve-context.outputs.trigger-event == 'pull_request_review_comment' &&
726+
needs.resolve-context.outputs.comment-in-reply-to-id == '' &&
727+
needs.resolve-context.outputs.comment-has-mention == 'true' &&
728+
needs.resolve-context.outputs.comment-is-review-cmd != 'true' &&
729+
needs.resolve-context.outputs.comment-author != 'docker-agent' &&
730+
needs.resolve-context.outputs.comment-author-type != 'Bot')
716731
)
717732
runs-on: ubuntu-latest
718733
permissions:
719734
contents: read
720735
pull-requests: write
721736
issues: write
722737
id-token: write
738+
actions: read # download cross-run artifacts
723739

724740
steps:
725741
- name: Setup credentials
726742
uses: docker/cagent-action/setup-credentials@c22076b8856ee12d9b4c4685bb49cf26eb974079 # v1.5.0
727743

744+
- name: Download trigger context
745+
if: inputs.trigger-run-id != ''
746+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
747+
with:
748+
name: pr-review-context
749+
path: /tmp/context
750+
run-id: ${{ inputs.trigger-run-id }}
751+
github-token: ${{ env.GITHUB_APP_TOKEN }}
752+
753+
- name: Synthesize mention-reply event context
754+
if: inputs.trigger-run-id != ''
755+
shell: bash
756+
run: |
757+
if [ ! -f /tmp/context/comment.json ]; then
758+
echo "::warning::comment.json not found in artifact — cannot synthesize mention event"
759+
exit 0
760+
fi
761+
PR_NUMBER=$(cat /tmp/context/pr_number.txt 2>/dev/null || echo '')
762+
if [ -z "$PR_NUMBER" ]; then
763+
echo "::warning::pr_number.txt missing or empty — cannot synthesize mention event"
764+
exit 0
765+
fi
766+
PR_HEAD_SHA=$(cat /tmp/context/pr_head_sha.txt 2>/dev/null || echo '')
767+
REPO_NAME="${GITHUB_REPOSITORY##*/}"
768+
REPO_FULL="${GITHUB_REPOSITORY}"
769+
REPO_OWNER="${GITHUB_REPOSITORY_OWNER}"
770+
jq -n \
771+
--slurpfile comment /tmp/context/comment.json \
772+
--arg pr_number "$PR_NUMBER" \
773+
--arg pr_head_sha "$PR_HEAD_SHA" \
774+
--arg repo_name "$REPO_NAME" \
775+
--arg repo_full_name "$REPO_FULL" \
776+
--arg repo_owner "$REPO_OWNER" \
777+
'{
778+
action: "created",
779+
pull_request: {
780+
number: ($pr_number | tonumber),
781+
head: { sha: $pr_head_sha }
782+
},
783+
comment: $comment[0],
784+
repository: {
785+
name: $repo_name,
786+
full_name: $repo_full_name,
787+
owner: { login: $repo_owner }
788+
},
789+
sender: $comment[0].user
790+
}' > /tmp/mention_event.json
791+
echo "✅ Synthesized mention-reply event context at /tmp/mention_event.json"
792+
793+
- name: Resolve event context for mention-reply action
794+
id: resolve-event
795+
shell: bash
796+
run: |
797+
if [ -f /tmp/mention_event.json ]; then
798+
echo "path=/tmp/mention_event.json" >> $GITHUB_OUTPUT
799+
echo "name=pull_request_review_comment" >> $GITHUB_OUTPUT
800+
else
801+
echo "path=$GITHUB_EVENT_PATH" >> $GITHUB_OUTPUT
802+
echo "name=$GITHUB_EVENT_NAME" >> $GITHUB_OUTPUT
803+
fi
804+
728805
- name: Run mention-reply handler
729806
id: mention-context
807+
if: steps.resolve-event.outputs.path != ''
730808
uses: docker/cagent-action/.github/actions/mention-reply@c22076b8856ee12d9b4c4685bb49cf26eb974079 # v1.5.0
809+
env:
810+
GITHUB_EVENT_PATH: ${{ steps.resolve-event.outputs.path }}
811+
GITHUB_EVENT_NAME: ${{ steps.resolve-event.outputs.name }}
731812
with:
732813
github-token: ${{ env.GITHUB_APP_TOKEN || github.token }}
733814
org-membership-token: ${{ env.ORG_MEMBERSHIP_TOKEN }}
@@ -755,14 +836,22 @@ jobs:
755836
env:
756837
GH_TOKEN: ${{ env.GITHUB_APP_TOKEN || github.token }}
757838
REPO: ${{ github.repository }}
758-
COMMENT_ID: ${{ github.event.comment.id }}
839+
EVENT_COMMENT_ID: ${{ github.event.comment.id }}
759840
OUTCOME: ${{ steps.run-reply.outcome }}
760841
EVENT_NAME: ${{ github.event_name }}
761842
run: |
762843
if [ "$OUTCOME" != "success" ]; then
763844
exit 0
764845
fi
765-
if [ "$EVENT_NAME" = "pull_request_review_comment" ]; then
846+
COMMENT_ID="$EVENT_COMMENT_ID"
847+
if [ -z "$COMMENT_ID" ] && [ -f /tmp/mention_event.json ]; then
848+
COMMENT_ID=$(jq -r '.comment.id // empty' /tmp/mention_event.json)
849+
fi
850+
if [ -z "$COMMENT_ID" ]; then
851+
echo "::warning::No comment ID available — skipping completion reaction"
852+
exit 0
853+
fi
854+
if [ -f /tmp/mention_event.json ] || [ "$EVENT_NAME" = "pull_request_review_comment" ]; then
766855
gh api "repos/$REPO/pulls/comments/$COMMENT_ID/reactions" \
767856
-X POST -f content='+1' || true
768857
else

review-pr/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ pull_request (opened / ready_for_review / review_requested)
123123
pull_request_review_comment
124124
→ pr-review-trigger.yml (saves context as artifact)
125125
→ workflow_run fires
126-
→ pr-review.yml (downloads artifact, routes to reply)
126+
→ pr-review.yml (downloads artifact, routes to reply-to-feedback for replies to agent
127+
comments, or reply-to-mention for top-level @-mentions)
127128

128129
/review comment –OR– @docker-agent mention
129130
→ pr-review.yml directly (issue_comment has full permissions)
@@ -164,7 +165,7 @@ with:
164165
| PR opened/ready | Auto-reviews when a PR is opened or marked ready for review. |
165166
| `/review` comment | Re-trigger a review, or trigger manually when auto-review hasn't run (e.g. after a force-push). Shows as a check run if `checks: write` is granted. |
166167
| Reply to review comment | Responds in-thread and captures feedback to improve future reviews. |
167-
| `@docker-agent` mention | Answers questions and clarifies review findings in PR comments. |
168+
| `@docker-agent` mention | Answers questions and clarifies review findings. Works in both PR-level issue comments and inline file-line review comments, including on fork PRs (via the trigger workflow). |
168169

169170
> **Built-in defense-in-depth:**
170171
>

0 commit comments

Comments
 (0)