Skip to content

Test cleaned comment formatting #36

Test cleaned comment formatting

Test cleaned comment formatting #36

name: PR Slack Notification
on:
pull_request:
types: [opened, reopened]
issue_comment:
types: [created, edited]
pull_request_review_comment:
types: [created, edited]
jobs:
notify-slack:
# For issue_comment, only run if the comment is on a pull request
if: >
github.event_name == 'pull_request' ||
github.event_name == 'pull_request_review_comment' ||
(github.event_name == 'issue_comment' && github.event.issue.pull_request)
runs-on: ubuntu-latest
steps:
- name: Send Slack notification
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }}
EVENT_NAME: ${{ github.event_name }}
EVENT_ACTION: ${{ github.event.action }}
COMMENT_ID: ${{ github.event.comment.id }}
COMMENT_BODY: ${{ github.event.comment.body }}
COMMENT_URL: ${{ github.event.comment.html_url }}
COMMENTER: ${{ github.event.comment.user.login }}
COMMENTER_AVATAR: ${{ github.event.comment.user.avatar_url }}
REPO: ${{ github.repository }}
# pull_request event
PR_URL_PR: ${{ github.event.pull_request.html_url }}
PR_TITLE_PR: ${{ github.event.pull_request.title }}
PR_NUMBER_PR: ${{ github.event.pull_request.number }}
PR_AUTHOR_PR: ${{ github.event.pull_request.user.login }}
PR_AUTHOR_AVATAR_PR: ${{ github.event.pull_request.user.avatar_url }}
# pull_request_review_comment event
PR_URL_REVIEW: ${{ github.event.pull_request.html_url }}
PR_TITLE_REVIEW: ${{ github.event.pull_request.title }}
PR_NUMBER_REVIEW: ${{ github.event.pull_request.number }}
# issue_comment event
PR_URL_ISSUE: ${{ github.event.issue.pull_request.html_url }}
PR_TITLE_ISSUE: ${{ github.event.issue.title }}
PR_NUMBER_ISSUE: ${{ github.event.issue.number }}
run: |
# Determine PR details based on event type
if [ "$EVENT_NAME" = "pull_request" ]; then
PR_URL="$PR_URL_PR"
PR_TITLE="$PR_TITLE_PR"
PR_NUMBER="$PR_NUMBER_PR"
elif [ "$EVENT_NAME" = "pull_request_review_comment" ]; then
PR_URL="$PR_URL_REVIEW"
PR_TITLE="$PR_TITLE_REVIEW"
PR_NUMBER="$PR_NUMBER_REVIEW"
else
PR_URL="$PR_URL_ISSUE"
PR_TITLE="$PR_TITLE_ISSUE"
PR_NUMBER="$PR_NUMBER_ISSUE"
fi
REPO_SHORT="${REPO#*/}"
# Ensure bot has joined the channel
curl -s -X POST "https://slack.com/api/conversations.join" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"channel\": \"$SLACK_CHANNEL_ID\"}" > /dev/null
# Search channel history for an existing thread about this PR
find_thread_ts() {
HISTORY=$(curl -s "https://slack.com/api/conversations.history?channel=$SLACK_CHANNEL_ID&limit=200" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN")
# Look for a message containing this PR's URL
THREAD_TS=$(echo "$HISTORY" | jq -r --arg pr_url "$PR_URL" '
.messages[]
| select(.text != null and (.text | contains($pr_url)))
| .ts' | tail -1)
if [ -n "$THREAD_TS" ] && [ "$THREAD_TS" != "null" ]; then
echo "$THREAD_TS"
fi
}
if [ "$EVENT_NAME" = "pull_request" ]; then
# PR opened/reopened — post a new top-level thread-starting message
PAYLOAD=$(jq -n \
--arg channel "$SLACK_CHANNEL_ID" \
--arg repo_short "$REPO_SHORT" \
--arg pr_url "$PR_URL" \
--arg pr_number "$PR_NUMBER" \
--arg pr_title "$PR_TITLE" \
--arg author "$PR_AUTHOR_PR" \
--arg avatar "$PR_AUTHOR_AVATAR_PR" \
'{
"channel": $channel,
"username": $author,
"icon_url": $avatar,
"text": ("New pull request [" + $repo_short + "#" + $pr_number + "] <" + $pr_url + "|" + $pr_title + "> by " + $author),
"unfurl_links": false,
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ("New pull request [" + $repo_short + "#" + $pr_number + "] <" + $pr_url + "|" + $pr_title + "> by " + $author)
}
}
]
}')
curl -s -X POST "https://slack.com/api/chat.postMessage" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
-H "Content-Type: application/json" \
-d "$PAYLOAD"
else
# Comment event — try to find existing thread, then reply in it
THREAD_TS=$(find_thread_ts)
# Clean comment body:
# 1. Remove HTML comments (<!-- ... -->)
# 2. Remove <details>...</details> blocks (CodeRabbit analysis chains)
# 3. Remove GitHub admonitions (> [!TIP], > [!NOTE], etc. and their continuation lines)
# 4. Remove --- separators and everything after them
# 5. Remove remaining HTML tags (<sub>, <summary>, etc.)
# 6. Remove lines that are only whitespace or markdown artifacts
# 7. Trim leading/trailing whitespace
CLEANED_BODY=$(echo "$COMMENT_BODY" | perl -0777 -pe '
s/<!--.*?-->//gs;
s/<details>.*?<\/details>//gs;
s/^>\s*\[!(TIP|NOTE|WARNING|CAUTION|IMPORTANT)\]\s*\n(^>.*\n)*//gm;
s/\n---\s*\n.*//s;
s/<[^>]+>//g;
s/^\s*\n//gm;
s/^\s+|\s+$//g;
')
# Truncate to 200 chars
if [ ${#CLEANED_BODY} -gt 200 ]; then
TRUNCATED_BODY="${CLEANED_BODY:0:200}..."
else
TRUNCATED_BODY="$CLEANED_BODY"
fi
# Build the blocks for the comment
COMMENT_BLOCKS=$(jq -n --arg comment_body "$TRUNCATED_BODY" '[
{
"type": "rich_text",
"elements": [
{
"type": "rich_text_quote",
"elements": [
{
"type": "text",
"text": $comment_body
}
]
}
]
}
]')
# Build metadata to tag this Slack message with the GitHub comment ID
METADATA=$(jq -n --arg comment_id "$COMMENT_ID" '{
"event_type": "github_comment",
"event_payload": { "comment_id": $comment_id }
}')
if [ "$EVENT_ACTION" = "edited" ] && [ -n "$THREAD_TS" ]; then
# Edit — find the existing Slack message for this GitHub comment and update it
REPLIES=$(curl -s "https://slack.com/api/conversations.replies?channel=$SLACK_CHANNEL_ID&ts=$THREAD_TS&include_all_metadata=true&limit=200" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN")
SLACK_MSG_TS=$(echo "$REPLIES" | jq -r --arg cid "$COMMENT_ID" '
.messages[]
| select(.metadata.event_payload.comment_id == $cid)
| .ts' | head -1)
if [ -n "$SLACK_MSG_TS" ] && [ "$SLACK_MSG_TS" != "null" ]; then
# Found the message — update it
UPDATE_PAYLOAD=$(jq -n \
--arg channel "$SLACK_CHANNEL_ID" \
--arg ts "$SLACK_MSG_TS" \
--arg comment_body "$TRUNCATED_BODY" \
--argjson blocks "$COMMENT_BLOCKS" \
--argjson metadata "$METADATA" \
'{
"channel": $channel,
"ts": $ts,
"text": $comment_body,
"blocks": $blocks,
"metadata": $metadata
}')
curl -s -X POST "https://slack.com/api/chat.update" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
-H "Content-Type: application/json" \
-d "$UPDATE_PAYLOAD"
else
# Could not find the original message — post as new reply
PAYLOAD=$(jq -n \
--arg channel "$SLACK_CHANNEL_ID" \
--arg commenter "$COMMENTER" \
--arg comment_body "$TRUNCATED_BODY" \
--arg avatar "$COMMENTER_AVATAR" \
--arg thread_ts "$THREAD_TS" \
--argjson blocks "$COMMENT_BLOCKS" \
--argjson metadata "$METADATA" \
'{
"channel": $channel,
"username": $commenter,
"icon_url": $avatar,
"thread_ts": $thread_ts,
"text": $comment_body,
"unfurl_links": false,
"blocks": $blocks,
"metadata": $metadata
}')
curl -s -X POST "https://slack.com/api/chat.postMessage" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
-H "Content-Type: application/json" \
-d "$PAYLOAD"
fi
elif [ -n "$THREAD_TS" ]; then
# New comment with existing thread — reply in thread
PAYLOAD=$(jq -n \
--arg channel "$SLACK_CHANNEL_ID" \
--arg commenter "$COMMENTER" \
--arg comment_body "$TRUNCATED_BODY" \
--arg avatar "$COMMENTER_AVATAR" \
--arg thread_ts "$THREAD_TS" \
--argjson blocks "$COMMENT_BLOCKS" \
--argjson metadata "$METADATA" \
'{
"channel": $channel,
"username": $commenter,
"icon_url": $avatar,
"thread_ts": $thread_ts,
"text": $comment_body,
"unfurl_links": false,
"blocks": $blocks,
"metadata": $metadata
}')
curl -s -X POST "https://slack.com/api/chat.postMessage" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
-H "Content-Type: application/json" \
-d "$PAYLOAD"
else
# No thread found — post top-level with full context
HEADER_BLOCK=$(jq -n \
--arg repo_short "$REPO_SHORT" \
--arg pr_url "$PR_URL" \
--arg pr_number "$PR_NUMBER" \
--arg pr_title "$PR_TITLE" \
--arg commenter "$COMMENTER" \
'{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ($commenter + " commented on [" + $repo_short + "#" + $pr_number + "] <" + $pr_url + "|" + $pr_title + ">")
}
}')
ALL_BLOCKS=$(echo "$COMMENT_BLOCKS" | jq --argjson header "$HEADER_BLOCK" '[$header] + .')
PAYLOAD=$(jq -n \
--arg channel "$SLACK_CHANNEL_ID" \
--arg repo_short "$REPO_SHORT" \
--arg pr_url "$PR_URL" \
--arg pr_number "$PR_NUMBER" \
--arg pr_title "$PR_TITLE" \
--arg commenter "$COMMENTER" \
--arg avatar "$COMMENTER_AVATAR" \
--argjson blocks "$ALL_BLOCKS" \
--argjson metadata "$METADATA" \
'{
"channel": $channel,
"username": $commenter,
"icon_url": $avatar,
"text": ($commenter + " commented on [" + $repo_short + "#" + $pr_number + "] <" + $pr_url + "|" + $pr_title + ">"),
"unfurl_links": false,
"blocks": $blocks,
"metadata": $metadata
}')
curl -s -X POST "https://slack.com/api/chat.postMessage" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
-H "Content-Type: application/json" \
-d "$PAYLOAD"
fi
fi