Test cleaned comment formatting #32
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: PR Slack Notifications | |
| 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 |