deploy-notify-slack 0.5.7 → 0.5.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/notify.js +70 -61
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
## Dummy script to send notification about new version deployment to a Slack channel
|
|
2
2
|
|
|
3
|
+
<a href="https://www.npmjs.com/package/deploy-notify-slack" target="_blank"><img src="https://img.shields.io/npm/v/deploy-notify-slack" alt="NPM Version" /></a>
|
|
4
|
+
<a href="https://www.npmjs.com/package/deploy-notify-slack" target="_blank"><img src="https://img.shields.io/npm/l/deploy-notify-slack" alt="Package License" /></a>
|
|
5
|
+
|
|
3
6
|
- no npm dependencies, plain nodejs 8.x or higher
|
|
4
7
|
- use Slack incoming webhooks API to send a message
|
|
5
8
|
- can attach version description Markdown files
|
|
@@ -17,6 +20,9 @@ You can use default message template with the following env variables:
|
|
|
17
20
|
|
|
18
21
|
- TITLE - ('Deployment' by default) notification title
|
|
19
22
|
- CHANGELOG_PATH - path of your deployed version details file (`changelog` by default as well as we assume that the package installed locally, so this option is required if the package installed globally)
|
|
23
|
+
- COLOR - ('#7f8583' by default) left bar notification color. Should be hex color code without `#` symbol
|
|
24
|
+
- EMOJI - (':rocket:' by default) emoji to be displayed in the notification title
|
|
25
|
+
- MAX_BLOCKS - (5 by default) maximum amount of large blocks(2500 symbols) available in slack message. If your changelog is bigger than this value it will be truncated.
|
|
20
26
|
|
|
21
27
|
> version details file is a Markdown file having the name like `${STAGE}-v${VERSION}.md`.
|
|
22
28
|
>
|
|
@@ -156,4 +162,4 @@ Then you can run the script with the following command:
|
|
|
156
162
|
npm i --location=global deploy-notify-slack@latest
|
|
157
163
|
CUSTOM_MESSAGE=$(cat message.json)
|
|
158
164
|
SLACK_WEBHOOK_URL=${SLACK_WEBHOOK_URL} CUSTOM_MESSAGE=$CUSTOM_MESSAGE node /usr/local/lib/node_modules/deploy-notify-slack/notify.js
|
|
159
|
-
```
|
|
165
|
+
```
|
package/notify.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const https = require('https');
|
|
2
2
|
const fs = require('fs');
|
|
3
|
-
const path = require('path')
|
|
3
|
+
const path = require('path');
|
|
4
4
|
|
|
5
5
|
const slackWebHookURL = process.env.SLACK_WEBHOOK_URL;
|
|
6
6
|
const stage = process.env.STAGE;
|
|
@@ -8,6 +8,8 @@ const version = process.env.VERSION;
|
|
|
8
8
|
const title = process.env.TITLE || 'Deployment';
|
|
9
9
|
const color = process.env.COLOR || '7f8583';
|
|
10
10
|
const emoji = process.env.EMOJI || ':rocket:';
|
|
11
|
+
const maxTextBlocksAvailable = process.env.MAX_BLOCKS || 5;
|
|
12
|
+
|
|
11
13
|
const customMessage = process.env.CUSTOM_MESSAGE;
|
|
12
14
|
const changelogPath = process.env.CHANGELOG_PATH || path.join(__dirname, '../../changelog');
|
|
13
15
|
const failsIfNotSent = process.env.FAILS_IF_NOT_SENT !== undefined
|
|
@@ -16,14 +18,19 @@ const failsIfNotSent = process.env.FAILS_IF_NOT_SENT !== undefined
|
|
|
16
18
|
|
|
17
19
|
function getChangelog() {
|
|
18
20
|
try {
|
|
19
|
-
return fs.readFileSync(path.join(changelogPath, `${stage}-v${version}.md`), 'utf8')
|
|
21
|
+
return fs.readFileSync(path.join(changelogPath, `${stage}-v${version}.md`), 'utf8');
|
|
20
22
|
} catch (e) {
|
|
21
|
-
console.log(`Description "${stage}-v${version}.md" not found in "${changelogPath}"`)
|
|
23
|
+
console.log(`Description "${stage}-v${version}.md" not found in "${changelogPath}"`);
|
|
22
24
|
}
|
|
23
25
|
try {
|
|
24
|
-
return fs.readFileSync(path.join(changelogPath, `v${version}.md`), 'utf8')
|
|
26
|
+
return fs.readFileSync(path.join(changelogPath, `v${version}.md`), 'utf8');
|
|
25
27
|
} catch (e) {
|
|
26
|
-
console.log(`Description "v${version}.md" not found in "${changelogPath}"`)
|
|
28
|
+
console.log(`Description "v${version}.md" not found in "${changelogPath}"`);
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
return fs.readFileSync(path.join(changelogPath, `changelog.md`), 'utf8');
|
|
32
|
+
} catch (e) {
|
|
33
|
+
console.log(`Description "changelog.md" not found in "${changelogPath}"`);
|
|
27
34
|
}
|
|
28
35
|
return '';
|
|
29
36
|
}
|
|
@@ -31,30 +38,30 @@ function getChangelog() {
|
|
|
31
38
|
function notificationBody() {
|
|
32
39
|
if (customMessage) {
|
|
33
40
|
return {
|
|
34
|
-
|
|
35
|
-
}
|
|
41
|
+
'attachments': [JSON.parse(customMessage)],
|
|
42
|
+
};
|
|
36
43
|
}
|
|
37
44
|
let blocks = [
|
|
38
45
|
{
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
46
|
+
'type': 'section',
|
|
47
|
+
'text': {
|
|
48
|
+
'type': 'mrkdwn',
|
|
49
|
+
'text': `${emoji} *${title}*`,
|
|
50
|
+
},
|
|
44
51
|
},
|
|
45
52
|
{
|
|
46
|
-
|
|
47
|
-
|
|
53
|
+
'type': 'section',
|
|
54
|
+
'fields': [
|
|
48
55
|
{
|
|
49
|
-
|
|
50
|
-
|
|
56
|
+
'type': 'mrkdwn',
|
|
57
|
+
'text': `*stage*\n ${stage}`,
|
|
51
58
|
},
|
|
52
59
|
{
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
]
|
|
57
|
-
}
|
|
60
|
+
'type': 'mrkdwn',
|
|
61
|
+
'text': `*version*\n ${version}`,
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
},
|
|
58
65
|
];
|
|
59
66
|
|
|
60
67
|
const changelog = getChangelog();
|
|
@@ -62,35 +69,35 @@ function notificationBody() {
|
|
|
62
69
|
const changelogBlocks = splitTextToBlocks(changelog);
|
|
63
70
|
blocks.push(
|
|
64
71
|
{
|
|
65
|
-
|
|
66
|
-
}
|
|
72
|
+
'type': 'divider',
|
|
73
|
+
},
|
|
67
74
|
);
|
|
68
75
|
blocks.push({
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
})
|
|
76
|
+
'type': 'section',
|
|
77
|
+
'text': {
|
|
78
|
+
'type': 'mrkdwn',
|
|
79
|
+
'text': '*Description:* \n\n' + changelogBlocks[0],
|
|
80
|
+
},
|
|
81
|
+
});
|
|
75
82
|
if (changelogBlocks.length > 1) {
|
|
76
83
|
for (let i = 1; i < changelogBlocks.length; i++) {
|
|
77
84
|
blocks.push({
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
})
|
|
85
|
+
'type': 'section',
|
|
86
|
+
'text': {
|
|
87
|
+
'type': 'mrkdwn',
|
|
88
|
+
'text': changelogBlocks[i],
|
|
89
|
+
},
|
|
90
|
+
});
|
|
84
91
|
}
|
|
85
92
|
}
|
|
86
93
|
}
|
|
87
94
|
return {
|
|
88
|
-
|
|
95
|
+
'attachments': [
|
|
89
96
|
{
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
]
|
|
97
|
+
'color': `#${color}`,
|
|
98
|
+
'blocks': blocks,
|
|
99
|
+
},
|
|
100
|
+
],
|
|
94
101
|
};
|
|
95
102
|
}
|
|
96
103
|
|
|
@@ -101,7 +108,7 @@ function notificationBody() {
|
|
|
101
108
|
* @param messageBody
|
|
102
109
|
* @return {Promise}
|
|
103
110
|
*/
|
|
104
|
-
function sendSlackMessage
|
|
111
|
+
function sendSlackMessage(webhookURL, messageBody) {
|
|
105
112
|
// make sure the incoming message body can be parsed into valid JSON
|
|
106
113
|
try {
|
|
107
114
|
messageBody = JSON.stringify(messageBody);
|
|
@@ -115,15 +122,14 @@ function sendSlackMessage (webhookURL, messageBody) {
|
|
|
115
122
|
const requestOptions = {
|
|
116
123
|
method: 'POST',
|
|
117
124
|
header: {
|
|
118
|
-
'Content-Type': 'application/json'
|
|
119
|
-
}
|
|
125
|
+
'Content-Type': 'application/json',
|
|
126
|
+
},
|
|
120
127
|
};
|
|
121
128
|
|
|
122
129
|
// actual request
|
|
123
130
|
const req = https.request(webhookURL, requestOptions, (res) => {
|
|
124
131
|
let response = '';
|
|
125
132
|
|
|
126
|
-
|
|
127
133
|
res.on('data', (d) => {
|
|
128
134
|
response += d;
|
|
129
135
|
});
|
|
@@ -131,7 +137,7 @@ function sendSlackMessage (webhookURL, messageBody) {
|
|
|
131
137
|
// response finished, resolve the promise with data
|
|
132
138
|
res.on('end', () => {
|
|
133
139
|
resolve(response);
|
|
134
|
-
})
|
|
140
|
+
});
|
|
135
141
|
});
|
|
136
142
|
|
|
137
143
|
// there was an error, reject the promise
|
|
@@ -151,23 +157,26 @@ function splitTextToBlocks(text) {
|
|
|
151
157
|
let endIndex = 0;
|
|
152
158
|
|
|
153
159
|
const MAX_BLOCK_SIZE = 2500;
|
|
154
|
-
|
|
160
|
+
const MAX_SYMBOLS_AVAILABLE = MAX_BLOCK_SIZE * maxTextBlocksAvailable;
|
|
161
|
+
const croppedText = text.length > MAX_SYMBOLS_AVAILABLE ? text.substring(0, MAX_SYMBOLS_AVAILABLE) + '...' : text;
|
|
162
|
+
|
|
163
|
+
while (startIndex < croppedText.length) {
|
|
155
164
|
endIndex = startIndex + MAX_BLOCK_SIZE;
|
|
156
165
|
|
|
157
166
|
// If the block does not end with a newline character, backtrack to the previous newline character.
|
|
158
|
-
if (endIndex <
|
|
159
|
-
while (endIndex > startIndex &&
|
|
167
|
+
if (endIndex < croppedText.length && croppedText[endIndex] !== '\n') {
|
|
168
|
+
while (endIndex > startIndex && croppedText[endIndex] !== '\n') {
|
|
160
169
|
endIndex--;
|
|
161
170
|
}
|
|
162
171
|
}
|
|
163
172
|
|
|
164
173
|
// If end index is greater than text length, just take the rest of the text
|
|
165
|
-
if (endIndex >
|
|
166
|
-
endIndex =
|
|
174
|
+
if (endIndex > croppedText.length) {
|
|
175
|
+
endIndex = croppedText.length;
|
|
167
176
|
}
|
|
168
177
|
|
|
169
178
|
// Add the block to the array
|
|
170
|
-
blocks.push(
|
|
179
|
+
blocks.push(croppedText.substring(startIndex, endIndex));
|
|
171
180
|
|
|
172
181
|
// Move the start index to the next position, skipping the newline character
|
|
173
182
|
startIndex = endIndex + 1;
|
|
@@ -176,21 +185,21 @@ function splitTextToBlocks(text) {
|
|
|
176
185
|
return blocks;
|
|
177
186
|
}
|
|
178
187
|
|
|
179
|
-
function stringToBool(str, defaultValue = false){
|
|
180
|
-
switch(str.toLowerCase().trim()){
|
|
181
|
-
case
|
|
182
|
-
case
|
|
183
|
-
case
|
|
188
|
+
function stringToBool(str, defaultValue = false) {
|
|
189
|
+
switch (str.toLowerCase().trim()) {
|
|
190
|
+
case 'true':
|
|
191
|
+
case 'yes':
|
|
192
|
+
case '1':
|
|
184
193
|
return true;
|
|
185
194
|
|
|
186
|
-
case
|
|
187
|
-
case
|
|
188
|
-
case
|
|
195
|
+
case 'false':
|
|
196
|
+
case 'no':
|
|
197
|
+
case '0':
|
|
189
198
|
case null:
|
|
190
199
|
return false;
|
|
191
200
|
|
|
192
201
|
default:
|
|
193
|
-
return defaultValue
|
|
202
|
+
return defaultValue;
|
|
194
203
|
}
|
|
195
204
|
}
|
|
196
205
|
|
|
@@ -219,7 +228,7 @@ function validate() {
|
|
|
219
228
|
}
|
|
220
229
|
|
|
221
230
|
// main
|
|
222
|
-
(async function
|
|
231
|
+
(async function() {
|
|
223
232
|
if (!validate()) {
|
|
224
233
|
process.exit(3);
|
|
225
234
|
}
|