diff --git a/.github/scripts/discord-helpers.sh b/.github/scripts/discord-helpers.sh index 191b9037..dd323d30 100644 --- a/.github/scripts/discord-helpers.sh +++ b/.github/scripts/discord-helpers.sh @@ -2,8 +2,21 @@ # Discord notification helper functions # Escape markdown special chars and @mentions for safe Discord display -# Bracket expression: ] must be first, then other chars. In POSIX bracket expr, \ is literal. -esc() { sed -e 's/[][\*_()~`>]/\\&/g' -e 's/@/@ /g'; } +# Skips content inside wrappers to preserve URLs intact +esc() { + awk '{ + result = ""; in_url = 0; n = length($0) + for (i = 1; i <= n; i++) { + c = substr($0, i, 1) + if (c == "<" && substr($0, i, 8) ~ /^") in_url = 0 } + else if (c == "@") result = result "@ " + else if (index("[]\\*_()~`", c) > 0) result = result "\\" c + else result = result c + } + print result + }' +} # Truncate to $1 chars (or 80 if wall-of-text with <3 spaces) trunc() { @@ -13,3 +26,9 @@ trunc() { [ "$spaces" -lt 3 ] && [ ${#txt} -gt 80 ] && txt=$(printf '%s' "$txt" | cut -c1-80) printf '%s' "$txt" } + +# Remove incomplete URL at end of truncated text (incomplete URLs are useless) +strip_trailing_url() { sed -E 's~ to suppress Discord embeds (keeps links clickable) +wrap_urls() { sed -E 's~https?://[^[:space:]<>]+~<&>~g'; } diff --git a/.github/workflows/discord.yaml b/.github/workflows/discord.yaml index 109bbb16..9d5c44e6 100644 --- a/.github/workflows/discord.yaml +++ b/.github/workflows/discord.yaml @@ -53,7 +53,11 @@ jobs: TITLE=$(printf '%s' "$PR_TITLE" | trunc $MAX_TITLE | esc) [ ${#PR_TITLE} -gt $MAX_TITLE ] && TITLE="${TITLE}..." - BODY=$(printf '%s' "$PR_BODY" | trunc $MAX_BODY | esc) + BODY=$(printf '%s' "$PR_BODY" | trunc $MAX_BODY) + if [ -n "$PR_BODY" ] && [ ${#PR_BODY} -gt $MAX_BODY ]; then + BODY=$(printf '%s' "$BODY" | strip_trailing_url) + fi + BODY=$(printf '%s' "$BODY" | wrap_urls | esc) [ -n "$PR_BODY" ] && [ ${#PR_BODY} -gt $MAX_BODY ] && BODY="${BODY}..." [ -n "$BODY" ] && BODY=" · $BODY" USER=$(printf '%s' "$PR_USER" | esc) @@ -91,7 +95,11 @@ jobs: TITLE=$(printf '%s' "$ISSUE_TITLE" | trunc $MAX_TITLE | esc) [ ${#ISSUE_TITLE} -gt $MAX_TITLE ] && TITLE="${TITLE}..." - BODY=$(printf '%s' "$ISSUE_BODY" | trunc $MAX_BODY | esc) + BODY=$(printf '%s' "$ISSUE_BODY" | trunc $MAX_BODY) + if [ -n "$ISSUE_BODY" ] && [ ${#ISSUE_BODY} -gt $MAX_BODY ]; then + BODY=$(printf '%s' "$BODY" | strip_trailing_url) + fi + BODY=$(printf '%s' "$BODY" | wrap_urls | esc) [ -n "$ISSUE_BODY" ] && [ ${#ISSUE_BODY} -gt $MAX_BODY ] && BODY="${BODY}..." [ -n "$BODY" ] && BODY=" · $BODY" USER=$(printf '%s' "$USER" | esc) @@ -126,7 +134,11 @@ jobs: TITLE=$(printf '%s' "$ISSUE_TITLE" | trunc $MAX_TITLE | esc) [ ${#ISSUE_TITLE} -gt $MAX_TITLE ] && TITLE="${TITLE}..." - BODY=$(printf '%s' "$COMMENT_BODY" | trunc $MAX_BODY | esc) + BODY=$(printf '%s' "$COMMENT_BODY" | trunc $MAX_BODY) + if [ ${#COMMENT_BODY} -gt $MAX_BODY ]; then + BODY=$(printf '%s' "$BODY" | strip_trailing_url) + fi + BODY=$(printf '%s' "$BODY" | wrap_urls | esc) [ ${#COMMENT_BODY} -gt $MAX_BODY ] && BODY="${BODY}..." USER=$(printf '%s' "$COMMENT_USER" | esc) @@ -162,7 +174,11 @@ jobs: TITLE=$(printf '%s' "$PR_TITLE" | trunc $MAX_TITLE | esc) [ ${#PR_TITLE} -gt $MAX_TITLE ] && TITLE="${TITLE}..." - BODY=$(printf '%s' "$REVIEW_BODY" | trunc $MAX_BODY | esc) + BODY=$(printf '%s' "$REVIEW_BODY" | trunc $MAX_BODY) + if [ -n "$REVIEW_BODY" ] && [ ${#REVIEW_BODY} -gt $MAX_BODY ]; then + BODY=$(printf '%s' "$BODY" | strip_trailing_url) + fi + BODY=$(printf '%s' "$BODY" | wrap_urls | esc) [ -n "$REVIEW_BODY" ] && [ ${#REVIEW_BODY} -gt $MAX_BODY ] && BODY="${BODY}..." [ -n "$BODY" ] && BODY=": $BODY" USER=$(printf '%s' "$REVIEW_USER" | esc) @@ -194,7 +210,11 @@ jobs: TITLE=$(printf '%s' "$PR_TITLE" | trunc $MAX_TITLE | esc) [ ${#PR_TITLE} -gt $MAX_TITLE ] && TITLE="${TITLE}..." - BODY=$(printf '%s' "$COMMENT_BODY" | trunc $MAX_BODY | esc) + BODY=$(printf '%s' "$COMMENT_BODY" | trunc $MAX_BODY) + if [ ${#COMMENT_BODY} -gt $MAX_BODY ]; then + BODY=$(printf '%s' "$BODY" | strip_trailing_url) + fi + BODY=$(printf '%s' "$BODY" | wrap_urls | esc) [ ${#COMMENT_BODY} -gt $MAX_BODY ] && BODY="${BODY}..." USER=$(printf '%s' "$COMMENT_USER" | esc) @@ -224,7 +244,11 @@ jobs: REL_NAME=$(printf '%s' "$NAME" | trunc $MAX_TITLE | esc) [ ${#NAME} -gt $MAX_TITLE ] && REL_NAME="${REL_NAME}..." - BODY=$(printf '%s' "$RELEASE_BODY" | trunc $MAX_BODY | esc) + BODY=$(printf '%s' "$RELEASE_BODY" | trunc $MAX_BODY) + if [ -n "$RELEASE_BODY" ] && [ ${#RELEASE_BODY} -gt $MAX_BODY ]; then + BODY=$(printf '%s' "$BODY" | strip_trailing_url) + fi + BODY=$(printf '%s' "$BODY" | wrap_urls | esc) [ -n "$RELEASE_BODY" ] && [ ${#RELEASE_BODY} -gt $MAX_BODY ] && BODY="${BODY}..." [ -n "$BODY" ] && BODY=" · $BODY" TAG_ESC=$(printf '%s' "$TAG" | esc) @@ -275,7 +299,7 @@ jobs: run: | set -o pipefail [ -z "$WEBHOOK" ] && exit 0 - esc() { sed -e 's/[][\*_()~`>]/\\&/g' -e 's/@/@ /g'; } + esc() { sed -e 's/[][\*_()~`]/\\&/g' -e 's/@/@ /g'; } trunc() { tr '\n\r' ' ' | cut -c1-"$1"; } REF_TRUNC=$(printf '%s' "$REF" | trunc 100)