Skip to content

Commit a5c9ca5

Browse files
committed
chore: fix release notification (#DS-5129)
1 parent 904888e commit a5c9ca5

2 files changed

Lines changed: 63 additions & 19 deletions

File tree

.github/workflows/publish.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,3 @@ jobs:
3434
NPM_TOKEN_KOOBIQ: ${{ secrets.NPM_PUBLISH_TOKEN }}
3535
MATTERMOST_WEBHOOK_URL: ${{ secrets.MM_WEBHOOK_URL }}
3636
MATTERMOST_CHANNEL: ${{ secrets.MM_CHANNEL_NAME }}
37-
MATTERMOST_USERNAME: ${{ secrets.MM_BOT_NAME }}

packages/cli/src/release/notify-release.ts

Lines changed: 63 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,85 @@
11
import chalk from 'chalk';
2+
import { request as httpsRequest } from 'https';
23
import { ChangelogReleaseNotes } from './extract-release-notes';
34

4-
const { green, red, cyan } = chalk;
5+
const { cyan, green, red } = chalk;
56

67
type MattermostConfig = {
78
url: string;
89
channel: string;
9-
username: string;
1010
};
1111

1212
function getMattermostConfig(): MattermostConfig | null {
1313
const url = process.env['MATTERMOST_WEBHOOK_URL'];
1414
const channel = process.env['MATTERMOST_CHANNEL'];
15-
const username = process.env['MATTERMOST_USERNAME'];
1615

17-
if (!url || !channel || !username) {
16+
if (!url || !channel) {
1817
return null;
1918
}
2019

21-
return { url, channel, username };
20+
return { url, channel };
2221
}
2322

23+
// Use https.request (not fetch/undici) — the Mattermost webhook is behind a WAF
24+
// that blocks requests by TLS fingerprint / HTTP/2. The Node built-in HTTP stack
25+
// (HTTP/1.1 + standard TLS) is the same one @actions/http-client uses and passes
26+
// the WAF. Don't "modernize" this back to fetch without re-checking the WAF.
2427
async function sendNotification(url: string, body: object): Promise<void> {
25-
const headers: Record<string, string> = { 'Content-Type': 'application/json' };
26-
const requestOptions: RequestInit = {
27-
method: 'POST',
28-
headers,
29-
body: JSON.stringify(body)
28+
const payload = JSON.stringify(body);
29+
const headers: Record<string, string> = {
30+
'Content-Type': 'application/json; charset=utf-8',
31+
Accept: 'application/json',
32+
'Content-Length': Buffer.byteLength(payload).toString()
3033
};
3134

32-
console.info(cyan('POST notification:'), { headers, body: JSON.stringify(body) });
33-
34-
const response = await fetch(url, requestOptions);
35-
36-
if (!response.ok) {
37-
throw new Error(`Failed to post notification: ${response.status} ${response.statusText}`);
35+
console.info(cyan(' [DEBUG] HTTP request:'), {
36+
method: 'POST',
37+
url,
38+
headers,
39+
body: payload
40+
});
41+
42+
const parsed = new URL(url);
43+
const { statusCode, statusMessage, responseBody } = await new Promise<{
44+
statusCode: number;
45+
statusMessage: string;
46+
responseBody: string;
47+
}>((resolve, reject) => {
48+
const req = httpsRequest(
49+
{
50+
method: 'POST',
51+
hostname: parsed.hostname,
52+
port: parsed.port || undefined,
53+
path: parsed.pathname + parsed.search,
54+
headers
55+
},
56+
(res) => {
57+
let data = '';
58+
59+
res.setEncoding('utf8');
60+
res.on('data', (chunk: string) => {
61+
data += chunk;
62+
});
63+
res.on('end', () => {
64+
resolve({
65+
statusCode: res.statusCode ?? 0,
66+
statusMessage: res.statusMessage ?? '',
67+
responseBody: data
68+
});
69+
});
70+
}
71+
);
72+
73+
req.on('error', reject);
74+
req.write(payload);
75+
req.end();
76+
});
77+
78+
console.info(cyan(` [DEBUG] HTTP response: ${statusCode} ${statusMessage}`));
79+
80+
if (statusCode < 200 || statusCode >= 300) {
81+
console.error(red(` ✘ Mattermost response body: ${responseBody}`));
82+
throw new Error(`Failed to post notification: ${statusCode} ${statusMessage}`);
3883
}
3984
}
4085

@@ -67,8 +112,8 @@ export async function notify(releaseData: ChangelogReleaseNotes): Promise<void>
67112
}
68113

69114
const body = {
70-
channel: `${config.channel}`,
71-
username: `${config.username}`,
115+
channel: config.channel,
116+
username: 'Wall-e',
72117
text: `${releaseData.releaseTitle}\n${releaseData.releaseNotes}`
73118
};
74119

0 commit comments

Comments
 (0)