-
Notifications
You must be signed in to change notification settings - Fork 32
/
index.js
149 lines (126 loc) · 4.13 KB
/
index.js
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
const { IncomingWebhook } = require('@slack/client');
const humanizeDuration = require('humanize-duration');
const Octokit = require('@octokit/rest');
const config = require('./config.json');
module.exports.webhook = new IncomingWebhook(config.SLACK_WEBHOOK_URL);
module.exports.status = config.GC_SLACK_STATUS;
module.exports.getGithubCommit = async (build, octokit) => {
try {
const cloudSourceRepo = build.source.repoSource.repoName;
const { commitSha } = build.sourceProvenance.resolvedRepoSource;
// format github_ownerName_repoName
const [, githubOwner, githubRepo] = cloudSourceRepo.split('_');
// get github commit
const githubCommit = await octokit.git.getCommit({
commit_sha: commitSha,
owner: githubOwner,
repo: githubRepo,
});
// return github commit
return githubCommit;
} catch (err) {
return err;
}
};
// subscribe is the main function called by GCF.
module.exports.subscribe = async (event) => {
try {
const token = process.env.GITHUB_TOKEN;
const octokit = token && new Octokit({
auth: `token ${token}`,
});
const build = module.exports.eventToBuild(event.data);
// Skip if the current status is not in the status list.
const status = module.exports.status || ['SUCCESS', 'FAILURE', 'INTERNAL_ERROR', 'TIMEOUT'];
if (status.indexOf(build.status) === -1) {
return;
}
const githubCommit = await module.exports.getGithubCommit(build, octokit);
const message = await module.exports.createSlackMessage(build, githubCommit);
// Send message to slack.
module.exports.webhook.send(message);
} catch (err) {
module.exports.webhook.send(`Error: ${err}`);
}
};
// eventToBuild transforms pubsub event message to a build object.
module.exports.eventToBuild = data => JSON.parse(Buffer.from(data, 'base64').toString());
const DEFAULT_COLOR = '#4285F4'; // blue
const STATUS_COLOR = {
QUEUED: DEFAULT_COLOR,
WORKING: DEFAULT_COLOR,
SUCCESS: '#34A853', // green
FAILURE: '#EA4335', // red
TIMEOUT: '#FBBC05', // yellow
INTERNAL_ERROR: '#EA4335', // red
};
// createSlackMessage create a message from a build object.
module.exports.createSlackMessage = async (build, githubCommit) => {
const buildFinishTime = new Date(build.finishTime);
const buildStartTime = new Date(build.startTime);
const isWorking = build.status === 'WORKING';
const timestamp = Math.round(((isWorking) ? buildStartTime : buildFinishTime).getTime() / 1000);
const text = (isWorking)
? `Build \`${build.id}\` started`
: `Build \`${build.id}\` finished`;
const fields = [{
title: 'Status',
value: build.status,
}];
if (!isWorking) {
const buildTime = humanizeDuration(buildFinishTime - buildStartTime);
fields.push({
title: 'Duration',
value: buildTime,
});
}
const message = {
text,
mrkdwn: true,
attachments: [
{
color: STATUS_COLOR[build.status] || DEFAULT_COLOR,
title: 'Build logs',
title_link: build.logUrl,
fields,
footer: 'Google Cloud Build',
footer_icon: 'https://ssl.gstatic.com/pantheon/images/containerregistry/container_registry_color.png',
ts: timestamp,
},
],
};
let repoName, branchName;
if (build.source && build.source.repoSource) {
({ repoName, branchName } = build.source.repoSource);
}
else if (build.substitutions) {
repoName = build.substitutions.REPO_NAME;
branchName = build.substitutions.BRANCH_NAME;
}
// Add source information to the message.
if (repoName && branchName) {
message.attachments[0].fields.push({
title: 'Repository',
value: repoName,
});
message.attachments[0].fields.push({
title: 'Branch',
value: branchName,
});
if (githubCommit) {
message.attachments[0].fields.push({
title: 'Commit Author',
value: githubCommit.data.author.name,
});
}
}
// Add image(s) to the message.
const images = build.images || [];
if (images.length) {
message.attachments[0].fields.push({
title: `Image${(images.length > 1) ? 's' : ''}`,
value: images.join('\n'),
});
}
return message;
};