diff --git a/.github/scripts/discord-helpers.sh b/.github/scripts/discord-helpers.sh index b0ad015d..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() { @@ -14,7 +27,7 @@ trunc() { printf '%s' "$txt" } -# Remove partial URL at end of truncated text (partial URLs are useless) +# 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) diff --git a/.github/workflows/discord.yaml b/.github/workflows/discord.yaml index fdab1d70..9d5c44e6 100644 --- a/.github/workflows/discord.yaml +++ b/.github/workflows/discord.yaml @@ -57,7 +57,7 @@ jobs: if [ -n "$PR_BODY" ] && [ ${#PR_BODY} -gt $MAX_BODY ]; then BODY=$(printf '%s' "$BODY" | strip_trailing_url) fi - BODY=$(printf '%s' "$BODY" | esc | wrap_urls) + 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) @@ -99,7 +99,7 @@ jobs: if [ -n "$ISSUE_BODY" ] && [ ${#ISSUE_BODY} -gt $MAX_BODY ]; then BODY=$(printf '%s' "$BODY" | strip_trailing_url) fi - BODY=$(printf '%s' "$BODY" | esc | wrap_urls) + 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) @@ -138,7 +138,7 @@ jobs: if [ ${#COMMENT_BODY} -gt $MAX_BODY ]; then BODY=$(printf '%s' "$BODY" | strip_trailing_url) fi - BODY=$(printf '%s' "$BODY" | esc | wrap_urls) + BODY=$(printf '%s' "$BODY" | wrap_urls | esc) [ ${#COMMENT_BODY} -gt $MAX_BODY ] && BODY="${BODY}..." USER=$(printf '%s' "$COMMENT_USER" | esc) @@ -178,7 +178,7 @@ jobs: if [ -n "$REVIEW_BODY" ] && [ ${#REVIEW_BODY} -gt $MAX_BODY ]; then BODY=$(printf '%s' "$BODY" | strip_trailing_url) fi - BODY=$(printf '%s' "$BODY" | esc | wrap_urls) + 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) @@ -214,7 +214,7 @@ jobs: if [ ${#COMMENT_BODY} -gt $MAX_BODY ]; then BODY=$(printf '%s' "$BODY" | strip_trailing_url) fi - BODY=$(printf '%s' "$BODY" | esc | wrap_urls) + BODY=$(printf '%s' "$BODY" | wrap_urls | esc) [ ${#COMMENT_BODY} -gt $MAX_BODY ] && BODY="${BODY}..." USER=$(printf '%s' "$COMMENT_USER" | esc) @@ -248,7 +248,7 @@ jobs: if [ -n "$RELEASE_BODY" ] && [ ${#RELEASE_BODY} -gt $MAX_BODY ]; then BODY=$(printf '%s' "$BODY" | strip_trailing_url) fi - BODY=$(printf '%s' "$BODY" | esc | wrap_urls) + 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) @@ -299,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)