Skip to content

Commit d8089c4

Browse files
committed
CI: fix Discord changelog chunker dropping the last message
The chunker reserved footer space in LAST_BUDGET but never used it — every chunk accumulated against MIDDLE_BUDGET (1900), then the footer was appended to the final message, pushing it past Discord's 2000-char limit (HTTP 400). The failure was also swallowed (only echoed), so the workflow still reported success. - Reserve FOOTER_LEN in every chunk budget (alpha + stable blocks) so the final message + footer always fits. - Emit a ::error:: annotation and fail the step on any non-2xx response, with the Discord response body and message length for diagnostics.
1 parent 32a93e0 commit d8089c4

1 file changed

Lines changed: 35 additions & 12 deletions

File tree

.github/workflows/release.yml

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,14 @@ jobs:
135135
136136
FOOTER="*${CHANNEL_UPPER} builds are available on CurseForge by selecting \"${CHANNEL_UPPER}\" in the file dropdown, or from [GitHub Releases](<https://github.com/DanderBot/DandersFrames/releases>).*"
137137
138-
# Split body into chunks that fit Discord's 2000 char limit
139-
# Reserve space for header/footer text in first/last messages
138+
# Split body into chunks that fit Discord's 2000 char limit.
139+
# The footer is appended to whichever message ends up last, and we
140+
# don't know which that is until the loop finishes — so reserve footer
141+
# room in EVERY chunk. The first message also carries the header.
140142
HEADER_LEN=${#HEADER}
141143
FOOTER_LEN=${#FOOTER}
142-
FIRST_BUDGET=$((1900 - HEADER_LEN))
143-
MIDDLE_BUDGET=1900
144-
LAST_BUDGET=$((1900 - FOOTER_LEN))
144+
FIRST_BUDGET=$((1900 - HEADER_LEN - FOOTER_LEN))
145+
MIDDLE_BUDGET=$((1900 - FOOTER_LEN))
145146
146147
MESSAGES=()
147148
CURRENT=""
@@ -166,6 +167,7 @@ jobs:
166167
[ -n "$CURRENT" ] && MESSAGES+=("$CURRENT")
167168
168169
TOTAL=${#MESSAGES[@]}
170+
FAILED=0
169171
for i in "${!MESSAGES[@]}"; do
170172
MSG=""
171173
if [ "$i" -eq 0 ]; then
@@ -181,18 +183,27 @@ jobs:
181183
MSG=$(echo "$MSG" | sed 's/^ //')
182184
183185
PAYLOAD=$(jq -n --arg content "$MSG" '{ content: $content }')
184-
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
186+
HTTP_CODE=$(curl -s -o /tmp/discord_resp -w "%{http_code}" \
185187
-H "Content-Type: application/json" \
186188
-d "$PAYLOAD" \
187189
"$DISCORD_WEBHOOK_URL")
188-
echo "Message $((i+1))/${TOTAL}: HTTP ${HTTP_CODE}"
190+
echo "Message $((i+1))/${TOTAL}: HTTP ${HTTP_CODE} (len ${#MSG})"
191+
case "$HTTP_CODE" in
192+
2*) ;;
193+
*) echo "::error::Discord message $((i+1))/${TOTAL} failed (HTTP ${HTTP_CODE}, len ${#MSG}): $(cat /tmp/discord_resp 2>/dev/null)"; FAILED=1 ;;
194+
esac
189195
190196
# Small delay between messages to preserve ordering
191197
if [ "$i" -lt $((TOTAL - 1)) ]; then
192198
sleep 1
193199
fi
194200
done
195201
202+
if [ "$FAILED" -ne 0 ]; then
203+
echo "::error::One or more Discord messages failed to post — see above."
204+
exit 1
205+
fi
206+
196207
- name: Notify Discord (release channel — stable only)
197208
if: steps.guard.outputs.skip != 'true' && success() && steps.changelog.outputs.channel == 'release'
198209
env:
@@ -219,9 +230,11 @@ jobs:
219230
HEADER_LEN=${#HEADER}
220231
FOOTER_LEN=${#FOOTER}
221232
ROLE_LEN=${#ROLE_MENTION}
222-
FIRST_BUDGET=$((1900 - HEADER_LEN))
223-
MIDDLE_BUDGET=$((1900 - ROLE_LEN - 1))
224-
LAST_BUDGET=$((1900 - FOOTER_LEN - ROLE_LEN - 1))
233+
# Every non-first message is prefixed with the role mention, and the
234+
# footer lands on whichever message is last — reserve room for both in
235+
# every chunk so the final message + footer can't exceed 2000.
236+
FIRST_BUDGET=$((1900 - HEADER_LEN - FOOTER_LEN))
237+
MIDDLE_BUDGET=$((1900 - ROLE_LEN - 1 - FOOTER_LEN))
225238
226239
MESSAGES=()
227240
CURRENT=""
@@ -246,6 +259,7 @@ jobs:
246259
[ -n "$CURRENT" ] && MESSAGES+=("$CURRENT")
247260
248261
TOTAL=${#MESSAGES[@]}
262+
FAILED=0
249263
for i in "${!MESSAGES[@]}"; do
250264
MSG=""
251265
if [ "$i" -eq 0 ]; then
@@ -262,13 +276,22 @@ jobs:
262276
MSG=$(echo "$MSG" | sed 's/^ //')
263277
264278
PAYLOAD=$(jq -n --arg content "$MSG" '{ content: $content }')
265-
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
279+
HTTP_CODE=$(curl -s -o /tmp/discord_resp -w "%{http_code}" \
266280
-H "Content-Type: application/json" \
267281
-d "$PAYLOAD" \
268282
"$DISCORD_WEBHOOK_URL")
269-
echo "Message $((i+1))/${TOTAL}: HTTP ${HTTP_CODE}"
283+
echo "Message $((i+1))/${TOTAL}: HTTP ${HTTP_CODE} (len ${#MSG})"
284+
case "$HTTP_CODE" in
285+
2*) ;;
286+
*) echo "::error::Discord message $((i+1))/${TOTAL} failed (HTTP ${HTTP_CODE}, len ${#MSG}): $(cat /tmp/discord_resp 2>/dev/null)"; FAILED=1 ;;
287+
esac
270288
271289
if [ "$i" -lt $((TOTAL - 1)) ]; then
272290
sleep 1
273291
fi
274292
done
293+
294+
if [ "$FAILED" -ne 0 ]; then
295+
echo "::error::One or more Discord messages failed to post — see above."
296+
exit 1
297+
fi

0 commit comments

Comments
 (0)