-
Notifications
You must be signed in to change notification settings - Fork 9
149 lines (133 loc) · 5.98 KB
/
discord-activity.yml
File metadata and controls
149 lines (133 loc) · 5.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
name: 'Discord: repo activity'
on:
push:
branches: ['**']
jobs:
notify:
runs-on: ubuntu-latest
steps:
# ----------------------------------------------------------------------
# Build the per-commit lines.
#
# Wire format per line (one commit):
# N. **`type(scope):`** subject · [`abc1234`](url) · author
#
# Notes for future maintainers (and for whoever reads this from the
# Discord side):
# - We render the SUBJECT only. Bodies are intentionally omitted —
# they fragment readability in chat and the hash link gives the
# full git show one click away.
# - The previous version stripped (), [], and ` from the message to
# "protect" the [hash](url) link that follows. That was a false
# positive: Discord's link parser only triggers on `]` IMMEDIATELY
# followed by `(`, and our hash link sits behind a ` · ` separator
# so subject-side punctuation is safe. Stripping parens turned
# `fix(editor):` into `fixeditor:` and is the bug we are fixing.
# - Conventional Commit prefix (type, optional scope, optional !)
# is detected with a single capture and rendered as bold inline
# code so it pops without breaking non-conventional commits.
# - Control characters (\u0000-\u001f) are still stripped because
# they break Discord rendering and have no legitimate place in a
# commit subject.
# ----------------------------------------------------------------------
- name: Build commit summary (for push)
id: build
env:
EVENT_JSON: ${{ toJSON(github.event) }}
run: |
COUNT=$(jq -r '.commits | length' <<< "$EVENT_JSON")
REF=$(jq -r '.ref' <<< "$EVENT_JSON" | sed 's|refs/heads/||')
COMPARE=$(jq -r '.compare' <<< "$EVENT_JSON")
# Skip the synthetic "build front back" deploy-trigger commit so
# the channel does not get a one-line notification with no signal.
SKIP_NOTIFICATION="false"
if [ "$COUNT" -eq 1 ]; then
FIRST_MSG=$(jq -r '.commits[0].message // "" | split("\n")[0]' <<< "$EVENT_JSON")
if [ "$FIRST_MSG" = "build front back" ]; then
SKIP_NOTIFICATION="true"
echo "⏭️ Skipping Discord notification (build trigger commit)"
fi
fi
REPO_URL="https://github.com/${{ github.repository }}"
jq -r --arg repo "$REPO_URL" '
.commits | to_entries[] |
((1 + .key) | tostring) as $n |
(.value.id[0:7]) as $sha |
($repo + "/commit/" + .value.id) as $url |
(.value.message
| split("\n")[0]
| gsub("[\u0000-\u001f]"; " ")
| gsub("\\s+"; " ")
| gsub("^\\s+|\\s+$"; "")
) as $subject |
# capture() returns an empty stream (not null) on no match,
# which would silently drop the entire commit line. Wrap it in
# an array so non-conventional commits resolve to null and fall
# through to the plain-subject branch below.
([$subject
| capture("^(?<prefix>[a-zA-Z]+(?:\\([^)]+\\))?!?:)\\s*(?<rest>.*)$")
] | .[0]) as $cc |
(if $cc != null then
"**`" + $cc.prefix + "`** " + ($cc.rest | .[0:180])
else
($subject | .[0:200])
end) as $title |
$n + ". " + $title + " · [`" + $sha + "`](" + $url + ") · " + .value.author.name
' <<< "$EVENT_JSON" > /tmp/commits.txt
{
echo "COUNT=$COUNT"
echo "REF=$REF"
echo "COMPARE=$COMPARE"
echo "SKIP_NOTIFICATION=$SKIP_NOTIFICATION"
} >> "$GITHUB_ENV"
# ----------------------------------------------------------------------
# Post to Discord.
#
# Splitting:
# Discord caps content at 2000 chars. We pack as many commit lines as
# fit under MAX_LEN (1900, leaving ~100 char buffer for trailing JSON
# and a bit of slack), then flush. The HEADER is only included in the
# first chunk so subsequent chunks read as continuations.
#
# flags: 4 == SUPPRESS_EMBEDS — keeps the message compact (no GitHub
# link previews stacking under every commit).
# ----------------------------------------------------------------------
- name: Post to Discord (smart split)
if: env.SKIP_NOTIFICATION != 'true'
run: |
HEADER="🚀 **Push** to \`${{ env.REF }}\` by \`${{ github.actor }}\`
📦 \`${{ github.repository }}\` · 📝 ${{ env.COUNT }} commits · 🔗 [View Diff](${{ env.COMPARE }})
**Commits**
"
MAX_LEN=1900
CURRENT_CHUNK=""
CHUNK_NUM=1
send_chunk() {
local message="$1"
curl -sS -H "Content-Type: application/json" \
-d "{\"content\": $(printf '%s' "$message" | jq -Rs .), \"flags\": 4}" \
"${{ secrets.DISCORD_WEBHOOK }}"
sleep 1
}
while IFS= read -r line || [ -n "$line" ]; do
[ -z "$line" ] && continue
TEST_MSG="${HEADER}${CURRENT_CHUNK}${line}"$'\n'
if [ ${#TEST_MSG} -gt $MAX_LEN ] && [ -n "$CURRENT_CHUNK" ]; then
if [ $CHUNK_NUM -eq 1 ]; then
send_chunk "${HEADER}${CURRENT_CHUNK}"
else
send_chunk "${CURRENT_CHUNK}"
fi
CHUNK_NUM=$((CHUNK_NUM + 1))
CURRENT_CHUNK="${line}"$'\n'
else
CURRENT_CHUNK="${CURRENT_CHUNK}${line}"$'\n'
fi
done < /tmp/commits.txt
if [ -n "$CURRENT_CHUNK" ]; then
if [ $CHUNK_NUM -eq 1 ]; then
send_chunk "${HEADER}${CURRENT_CHUNK}"
else
send_chunk "${CURRENT_CHUNK}"
fi
fi