Skip to content

Commit d088f4f

Browse files
committed
Send slack notification in IDE integration tests
1 parent 7dd98f8 commit d088f4f

File tree

5 files changed

+81
-24
lines changed

5 files changed

+81
-24
lines changed

.werft/build.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as fs from 'fs';
22
import { SpanStatusCode } from '@opentelemetry/api';
33
import { Werft } from './util/werft';
4-
import { reportBuildFailureInSlack } from './util/slack';
4+
import { reportToSlack } from './util/slack';
55
import * as Tracing from './observability/tracing'
66
import * as VM from './vm/vm'
77
import { buildAndPublish } from './jobs/build/build-and-publish';
@@ -31,14 +31,16 @@ Tracing.initialize()
3131
werft.endAllSpans()
3232

3333
if (context.Repository.ref === "refs/heads/main") {
34-
reportBuildFailureInSlack(context, err, () => process.exit(1));
34+
reportErrorToSlack(context, err).then(() => {
35+
VM.stopKubectlPortForwards();
36+
process.exit(1);
37+
});
3538
} else {
3639
console.log('Error', err)
3740
// Explicitly not using process.exit as we need to flush tracing, see tracing.js
3841
process.exitCode = 1
42+
VM.stopKubectlPortForwards();
3943
}
40-
41-
VM.stopKubectlPortForwards()
4244
})
4345

4446
async function run(context: any) {
@@ -58,3 +60,14 @@ async function run(context: any) {
5860
await deployToPreviewEnvironment(werft, config)
5961
await triggerIntegrationTests(werft, config, context.Owner)
6062
}
63+
64+
async function reportErrorToSlack(context: any, error: any) {
65+
const repo = context.Repository.host + "/" + context.Repository.owner + "/" + context.Repository.repo;
66+
const message = ":X: *build failure*\n_Repo:_ `" + repo + "`\n_Build:_ `" + context.Name + "`";
67+
const werftJobUrl = "https://werft.gitpod-dev.com/job/" + context.Name;
68+
try {
69+
await reportToSlack(error, message, werftJobUrl);
70+
} catch (err) {
71+
console.log("Slack webhook notification failed", err);
72+
}
73+
}

.werft/integration-tests-startup.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ pod:
8484
8585
if ! werft job logs ${TEST_BUILD_ID} | werft log slice "test";
8686
then
87-
echo "ingetration test failed" | werft log slice "test"
87+
echo "integration test failed" | werft log slice "test"
8888
exit 1
8989
fi
90-
echo "ingetration test success" | werft log slice "test"
90+
echo "integration test success" | werft log slice "test"

.werft/notifySlack.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { reportToSlack } from './util/slack';
2+
3+
async function main(args: string[]) {
4+
if (args.length < 3) {
5+
return;
6+
}
7+
8+
const error = args[0];
9+
const message = args[1];
10+
const werftJobUrl = args[2];
11+
try {
12+
await reportToSlack(error, message, werftJobUrl);
13+
} catch (err) {
14+
console.log("Slack webhook notification failed", err);
15+
}
16+
}
17+
18+
if (require.main === module) {
19+
main(process.argv.slice(2))
20+
.then(() => process.exit(0))
21+
}

.werft/run-integration-tests-ide.yaml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,19 @@ pod:
7272
secretKeyRef:
7373
name: github-roboquat-automatic-changelog
7474
key: token
75+
- name: SLACK_NOTIFICATION_PATH
76+
valueFrom:
77+
secretKeyRef:
78+
name: slack-webhook-urls
79+
key: ide_jobs
7580
command:
7681
- /bin/bash
7782
- -c
7883
- |
7984
sleep 1
8085
set -Eeuo pipefail
8186
82-
printf '{{ toJson .Annotations }}' > context.json
87+
printf '{{ toJson . }}' > context.json
8388
8489
echo "[prep] receiving config..."
8590
export GOOGLE_APPLICATION_CREDENTIALS="/config/gcloud/legacy_credentials/cd-gitpod-deployer@gitpod-core-dev.iam.gserviceaccount.com/adc.json"
@@ -105,6 +110,16 @@ pod:
105110
RC=${PIPESTATUS[0]}
106111
if [ $RC -eq 1 ]; then
107112
echo "[int-tests|FAIL]"
113+
114+
context_name = $(jq -r '.Name' context.json)
115+
context_host = $(jq -r '.Repository.host' context.json)
116+
context_owner = $(jq -r '.Repository.owner' context.json)
117+
context_repo = $(jq -r '.Repository.repo' context.json)
118+
repo = "${context_host}/${context_owner}/${context_repo}"
119+
message = ":X: *IDE integration test failure*\n_Repo:_ ${context_repo}\n_Build:_ ${context_name}";
120+
werftJobUrl = "https://werft.gitpod-dev.com/job/${context_name}"
121+
errorMsg = "Some IDE integration test failed, please check the werf job logs and try to fix them"
122+
npx ts-node .werft/notifySlack.ts "$errorMsg" "$message" "$werftJobUrl"
108123
else
109124
echo "[int-tests|DONE]"
110125
fi

.werft/util/slack.ts

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import * as https from 'https';
22

3-
export function reportBuildFailureInSlack(context, err, onErr) {
4-
const repo = context.Repository.host + "/" + context.Repository.owner + "/" + context.Repository.repo;
3+
export function reportToSlack(error:string, message:string, werfJobUrl:string): Promise<void> {
54
const data = JSON.stringify({
65
"blocks": [
76
{
87
"type": "section",
98
"text": {
109
"type": "mrkdwn",
11-
"text": ":X: *build failure*\n_Repo:_ `" + repo + "`\n_Build:_ `" + context.Name + "`"
10+
"text": message
1211
},
1312
"accessory": {
1413
"type": "button",
@@ -18,30 +17,39 @@ export function reportBuildFailureInSlack(context, err, onErr) {
1817
"emoji": true
1918
},
2019
"value": "click_me_123",
21-
"url": "https://werft.gitpod-dev.com/job/" + context.Name,
20+
"url": werfJobUrl,
2221
"action_id": "button-action"
2322
}
2423
},
2524
{
2625
"type": "section",
2726
"text": {
2827
"type": "mrkdwn",
29-
"text": "```\n" + err + "\n```"
28+
"text": "```\n" + error + "\n```"
3029
}
3130
}
3231
]
3332
});
34-
const req = https.request({
35-
hostname: "hooks.slack.com",
36-
port: 443,
37-
path: process.env.SLACK_NOTIFICATION_PATH.trim(),
38-
method: "POST",
39-
headers: {
40-
'Content-Type': 'application/json',
41-
'Content-Length': data.length,
33+
34+
return new Promise((resolve, reject) => {
35+
const options: https.RequestOptions = {
36+
hostname: "hooks.slack.com",
37+
port: 443,
38+
path: process.env.SLACK_NOTIFICATION_PATH.trim(),
39+
method: "POST",
40+
headers: {
41+
'Content-Type': 'application/json',
42+
'Content-Length': data.length,
43+
}
4244
}
43-
}, onErr);
44-
req.on('error', onErr);
45-
req.write(data);
46-
req.end();
45+
const req = https.request(options, (res) => {
46+
if (res.statusCode < 200 || res.statusCode >= 300) {
47+
return reject(new Error('statusCode=' + res.statusCode));
48+
}
49+
res.on('end', () => resolve());
50+
});
51+
req.on('error', (err) => reject(err));
52+
req.write(data);
53+
req.end();
54+
});
4755
}

0 commit comments

Comments
 (0)