Skip to content

Commit 48a59bf

Browse files
authored
Merge pull request #4 from coderabbit-demo/feature/edit-comment-sync
Sync GitHub comment edits to Slack
2 parents fb0ea19 + 0354609 commit 48a59bf

File tree

1 file changed

+130
-51
lines changed

1 file changed

+130
-51
lines changed

.github/workflows/pr-comment-slack-notify.yml

Lines changed: 130 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ on:
44
pull_request:
55
types: [opened, reopened]
66
issue_comment:
7-
types: [created]
7+
types: [created, edited]
88
pull_request_review_comment:
9-
types: [created]
9+
types: [created, edited]
1010

1111
jobs:
1212
notify-slack:
@@ -22,6 +22,8 @@ jobs:
2222
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
2323
SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }}
2424
EVENT_NAME: ${{ github.event_name }}
25+
EVENT_ACTION: ${{ github.event.action }}
26+
COMMENT_ID: ${{ github.event.comment.id }}
2527
COMMENT_BODY: ${{ github.event.comment.body }}
2628
COMMENT_URL: ${{ github.event.comment.html_url }}
2729
COMMENTER: ${{ github.event.comment.user.login }}
@@ -118,11 +120,19 @@ jobs:
118120
119121
# Clean comment body:
120122
# 1. Remove HTML comments (<!-- ... -->)
121-
# 2. Remove GitHub admonitions (> [!TIP], > [!NOTE], etc. and their continuation lines)
122-
# 3. Trim leading/trailing whitespace
123+
# 2. Remove <details>...</details> blocks (CodeRabbit analysis chains)
124+
# 3. Remove GitHub admonitions (> [!TIP], > [!NOTE], etc. and their continuation lines)
125+
# 4. Remove --- separators and everything after them
126+
# 5. Remove remaining HTML tags (<sub>, <summary>, etc.)
127+
# 6. Remove lines that are only whitespace or markdown artifacts
128+
# 7. Trim leading/trailing whitespace
123129
CLEANED_BODY=$(echo "$COMMENT_BODY" | perl -0777 -pe '
124130
s/<!--.*?-->//gs;
131+
s/<details>.*?<\/details>//gs;
125132
s/^>\s*\[!(TIP|NOTE|WARNING|CAUTION|IMPORTANT)\]\s*\n(^>.*\n)*//gm;
133+
s/\n---\s*\n.*//s;
134+
s/<[^>]+>//g;
135+
s/^\s*\n//gm;
126136
s/^\s+|\s+$//g;
127137
')
128138
@@ -133,83 +143,152 @@ jobs:
133143
TRUNCATED_BODY="$CLEANED_BODY"
134144
fi
135145
136-
if [ -n "$THREAD_TS" ]; then
137-
# Thread reply — just show the comment text, no header
146+
# Build the blocks for the comment
147+
COMMENT_BLOCKS=$(jq -n --arg comment_body "$TRUNCATED_BODY" '[
148+
{
149+
"type": "rich_text",
150+
"elements": [
151+
{
152+
"type": "rich_text_quote",
153+
"elements": [
154+
{
155+
"type": "text",
156+
"text": $comment_body
157+
}
158+
]
159+
}
160+
]
161+
}
162+
]')
163+
164+
# Build metadata to tag this Slack message with the GitHub comment ID
165+
METADATA=$(jq -n --arg comment_id "$COMMENT_ID" '{
166+
"event_type": "github_comment",
167+
"event_payload": { "comment_id": $comment_id }
168+
}')
169+
170+
if [ "$EVENT_ACTION" = "edited" ] && [ -n "$THREAD_TS" ]; then
171+
# Edit — find the existing Slack message for this GitHub comment and update it
172+
REPLIES=$(curl -s "https://slack.com/api/conversations.replies?channel=$SLACK_CHANNEL_ID&ts=$THREAD_TS&include_all_metadata=true&limit=200" \
173+
-H "Authorization: Bearer $SLACK_BOT_TOKEN")
174+
175+
SLACK_MSG_TS=$(echo "$REPLIES" | jq -r --arg cid "$COMMENT_ID" '
176+
.messages[]
177+
| select(.metadata.event_payload.comment_id == $cid)
178+
| .ts' | head -1)
179+
180+
if [ -n "$SLACK_MSG_TS" ] && [ "$SLACK_MSG_TS" != "null" ]; then
181+
# Found the message — update it
182+
UPDATE_PAYLOAD=$(jq -n \
183+
--arg channel "$SLACK_CHANNEL_ID" \
184+
--arg ts "$SLACK_MSG_TS" \
185+
--arg comment_body "$TRUNCATED_BODY" \
186+
--argjson blocks "$COMMENT_BLOCKS" \
187+
--argjson metadata "$METADATA" \
188+
'{
189+
"channel": $channel,
190+
"ts": $ts,
191+
"text": $comment_body,
192+
"blocks": $blocks,
193+
"metadata": $metadata
194+
}')
195+
196+
curl -s -X POST "https://slack.com/api/chat.update" \
197+
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
198+
-H "Content-Type: application/json" \
199+
-d "$UPDATE_PAYLOAD"
200+
else
201+
# Could not find the original message — post as new reply
202+
PAYLOAD=$(jq -n \
203+
--arg channel "$SLACK_CHANNEL_ID" \
204+
--arg commenter "$COMMENTER" \
205+
--arg comment_body "$TRUNCATED_BODY" \
206+
--arg avatar "$COMMENTER_AVATAR" \
207+
--arg thread_ts "$THREAD_TS" \
208+
--argjson blocks "$COMMENT_BLOCKS" \
209+
--argjson metadata "$METADATA" \
210+
'{
211+
"channel": $channel,
212+
"username": $commenter,
213+
"icon_url": $avatar,
214+
"thread_ts": $thread_ts,
215+
"text": $comment_body,
216+
"unfurl_links": false,
217+
"blocks": $blocks,
218+
"metadata": $metadata
219+
}')
220+
221+
curl -s -X POST "https://slack.com/api/chat.postMessage" \
222+
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
223+
-H "Content-Type: application/json" \
224+
-d "$PAYLOAD"
225+
fi
226+
elif [ -n "$THREAD_TS" ]; then
227+
# New comment with existing thread — reply in thread
138228
PAYLOAD=$(jq -n \
139229
--arg channel "$SLACK_CHANNEL_ID" \
140230
--arg commenter "$COMMENTER" \
141231
--arg comment_body "$TRUNCATED_BODY" \
142232
--arg avatar "$COMMENTER_AVATAR" \
143233
--arg thread_ts "$THREAD_TS" \
234+
--argjson blocks "$COMMENT_BLOCKS" \
235+
--argjson metadata "$METADATA" \
144236
'{
145237
"channel": $channel,
146238
"username": $commenter,
147239
"icon_url": $avatar,
148240
"thread_ts": $thread_ts,
149241
"text": $comment_body,
150242
"unfurl_links": false,
151-
"blocks": [
152-
{
153-
"type": "rich_text",
154-
"elements": [
155-
{
156-
"type": "rich_text_quote",
157-
"elements": [
158-
{
159-
"type": "text",
160-
"text": $comment_body
161-
}
162-
]
163-
}
164-
]
165-
}
166-
]
243+
"blocks": $blocks,
244+
"metadata": $metadata
167245
}')
246+
247+
curl -s -X POST "https://slack.com/api/chat.postMessage" \
248+
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
249+
-H "Content-Type: application/json" \
250+
-d "$PAYLOAD"
168251
else
169252
# No thread found — post top-level with full context
253+
HEADER_BLOCK=$(jq -n \
254+
--arg repo_short "$REPO_SHORT" \
255+
--arg pr_url "$PR_URL" \
256+
--arg pr_number "$PR_NUMBER" \
257+
--arg pr_title "$PR_TITLE" \
258+
--arg commenter "$COMMENTER" \
259+
'{
260+
"type": "section",
261+
"text": {
262+
"type": "mrkdwn",
263+
"text": ($commenter + " commented on [" + $repo_short + "#" + $pr_number + "] <" + $pr_url + "|" + $pr_title + ">")
264+
}
265+
}')
266+
267+
ALL_BLOCKS=$(echo "$COMMENT_BLOCKS" | jq --argjson header "$HEADER_BLOCK" '[$header] + .')
268+
170269
PAYLOAD=$(jq -n \
171270
--arg channel "$SLACK_CHANNEL_ID" \
172271
--arg repo_short "$REPO_SHORT" \
173272
--arg pr_url "$PR_URL" \
174273
--arg pr_number "$PR_NUMBER" \
175274
--arg pr_title "$PR_TITLE" \
176275
--arg commenter "$COMMENTER" \
177-
--arg comment_body "$TRUNCATED_BODY" \
178276
--arg avatar "$COMMENTER_AVATAR" \
277+
--argjson blocks "$ALL_BLOCKS" \
278+
--argjson metadata "$METADATA" \
179279
'{
180280
"channel": $channel,
181281
"username": $commenter,
182282
"icon_url": $avatar,
183283
"text": ($commenter + " commented on [" + $repo_short + "#" + $pr_number + "] <" + $pr_url + "|" + $pr_title + ">"),
184284
"unfurl_links": false,
185-
"blocks": [
186-
{
187-
"type": "section",
188-
"text": {
189-
"type": "mrkdwn",
190-
"text": ($commenter + " commented on [" + $repo_short + "#" + $pr_number + "] <" + $pr_url + "|" + $pr_title + ">")
191-
}
192-
},
193-
{
194-
"type": "rich_text",
195-
"elements": [
196-
{
197-
"type": "rich_text_quote",
198-
"elements": [
199-
{
200-
"type": "text",
201-
"text": $comment_body
202-
}
203-
]
204-
}
205-
]
206-
}
207-
]
285+
"blocks": $blocks,
286+
"metadata": $metadata
208287
}')
209-
fi
210288
211-
curl -s -X POST "https://slack.com/api/chat.postMessage" \
212-
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
213-
-H "Content-Type: application/json" \
214-
-d "$PAYLOAD"
289+
curl -s -X POST "https://slack.com/api/chat.postMessage" \
290+
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
291+
-H "Content-Type: application/json" \
292+
-d "$PAYLOAD"
293+
fi
215294
fi

0 commit comments

Comments
 (0)