Discord Release Notification #8
Workflow file for this run
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: Discord Release Notification | |
| on: | |
| release: | |
| types: [published] | |
| jobs: | |
| notify-discord: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Post changelog to Discord | |
| env: | |
| DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_URL }} | |
| RELEASE_TAG: ${{ github.event.release.tag_name }} | |
| RELEASE_NAME: ${{ github.event.release.name }} | |
| RELEASE_URL: ${{ github.event.release.html_url }} | |
| RELEASE_BODY: ${{ github.event.release.body }} | |
| RELEASE_PRERELEASE: ${{ github.event.release.prerelease }} | |
| run: | | |
| # ------------------------------------------------------------------- | |
| # Transform GitHub Release body -> Discord-friendly embed | |
| # ------------------------------------------------------------------- | |
| # All user-controlled data is passed via env vars (not expressions) | |
| # to prevent script injection. JSON is built with jq for safety. | |
| # Discord embed description limit: 4096 chars. | |
| # ------------------------------------------------------------------- | |
| # --- Markdown transformations for Discord --- | |
| BODY="$RELEASE_BODY" | |
| # Remove horizontal rules (--- renders as text in Discord) | |
| BODY=$(printf '%s' "$BODY" | sed '/^[[:space:]]*---[[:space:]]*$/d') | |
| # Collapse 3+ consecutive blank lines into 2 | |
| BODY=$(printf '%s' "$BODY" | cat -s) | |
| # Strip leading/trailing whitespace | |
| BODY=$(printf '%s' "$BODY" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//') | |
| # --- Determine embed color --- | |
| if [ "$RELEASE_PRERELEASE" = "true" ]; then | |
| COLOR=16744448 # Orange | |
| BADGE="BETA" | |
| else | |
| COLOR=5763719 # Discord green | |
| BADGE="STABLE" | |
| fi | |
| TITLE="${RELEASE_NAME:-$RELEASE_TAG}" | |
| FOOTER="QManager ${RELEASE_TAG} • ${BADGE}" | |
| TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ) | |
| # --- Truncate if over Discord's 4096 char limit --- | |
| if [ ${#BODY} -gt 4000 ]; then | |
| BODY="${BODY:0:3990} | |
| ...*[Read full changelog](${RELEASE_URL})*" | |
| fi | |
| # --- Build JSON payload safely with jq --- | |
| PAYLOAD=$(jq -n \ | |
| --arg title "$TITLE" \ | |
| --arg url "$RELEASE_URL" \ | |
| --arg desc "$BODY" \ | |
| --argjson color "$COLOR" \ | |
| --arg footer "$FOOTER" \ | |
| --arg ts "$TIMESTAMP" \ | |
| '{ | |
| embeds: [{ | |
| title: $title, | |
| url: $url, | |
| description: $desc, | |
| color: $color, | |
| footer: { text: $footer }, | |
| timestamp: $ts | |
| }] | |
| }') | |
| # --- Send to Discord --- | |
| HTTP_CODE=$(curl -s -o /tmp/discord_response.txt -w '%{http_code}' \ | |
| -H "Content-Type: application/json" \ | |
| -d "$PAYLOAD" \ | |
| "$DISCORD_WEBHOOK") | |
| if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then | |
| echo "Discord notification sent for ${RELEASE_TAG} (HTTP ${HTTP_CODE})" | |
| else | |
| echo "::error::Discord webhook failed (HTTP ${HTTP_CODE})" | |
| cat /tmp/discord_response.txt | |
| exit 1 | |
| fi |