send emails on task failure
This commit is contained in:
Родитель
ad0f60caf5
Коммит
22ef634e80
|
@ -19,6 +19,7 @@
|
|||
"irc-colors": "^1.2.1",
|
||||
"jerk": "^1.1.23",
|
||||
"peoplestring-parse": "^2.0.3",
|
||||
"postmark": "^1.2.1",
|
||||
"request-json": "^0.5.6",
|
||||
"taskcluster-client": "^1.0.1"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import postmark_ from "postmark";
|
||||
const postmark = postmark_(process.env.POSTMARK_API_TOKEN);
|
||||
|
||||
const FROM = "NSS Taskcluster <nss-tc@timtaubert.de>";
|
||||
|
||||
async function send(recipients, subject, body) {
|
||||
let addresses = recipients.map(recipient => {
|
||||
if (recipient.email) {
|
||||
return `"${recipient.name || recipient.email}" <${recipient.email}>`;
|
||||
}
|
||||
}).filter(x => x);
|
||||
|
||||
if (!addresses.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
postmark.send({
|
||||
From: FROM,
|
||||
To: addresses.join(", "),
|
||||
Subject: subject,
|
||||
TextBody: body
|
||||
});
|
||||
}
|
||||
|
||||
module.exports.send = send;
|
16
src/hg.js
16
src/hg.js
|
@ -37,8 +37,7 @@ async function shortenRevision(revision) {
|
|||
return tryShortenedRevisionHash(12);
|
||||
};
|
||||
|
||||
async function fetchChangesets(revision, options = {}) {
|
||||
let includeHref = options && options.includeHref;
|
||||
async function fetchChangesets(revision) {
|
||||
let json = await jsonRequest(HG_REPO + "/json-pushes?full&changeset=" + revision);
|
||||
|
||||
let id = Object.keys(json)[0];
|
||||
|
@ -46,20 +45,13 @@ async function fetchChangesets(revision, options = {}) {
|
|||
|
||||
for (let changeset of changesets) {
|
||||
changeset.author = parse(changeset.author);
|
||||
changeset.desc = changeset.desc.split("\n")[0];
|
||||
|
||||
if (includeHref) {
|
||||
let short_rev = await shortenRevision(revision);
|
||||
changeset.href = HG_HOST + HG_REPO + "/rev/" + short_rev;
|
||||
}
|
||||
let short_rev = await shortenRevision(revision);
|
||||
changeset.href = HG_HOST + HG_REPO + "/rev/" + short_rev;
|
||||
}
|
||||
|
||||
return changesets;
|
||||
}
|
||||
|
||||
async function fetchBlamelist(revision) {
|
||||
let changesets = await fetchChangesets(revision);
|
||||
return changesets.map(changeset => changeset.author);
|
||||
};
|
||||
|
||||
module.exports.fetchChangesets = fetchChangesets;
|
||||
module.exports.fetchBlamelist = fetchBlamelist;
|
||||
|
|
27
src/index.js
27
src/index.js
|
@ -5,6 +5,7 @@
|
|||
import hg from "./hg";
|
||||
import irc from "./irc";
|
||||
import tcc from "./tcc";
|
||||
import email from "./email";
|
||||
import colors from "irc-colors";
|
||||
import unique from "array-unique";
|
||||
|
||||
|
@ -34,13 +35,11 @@ tcc.onTaskDefined(async function (msg) {
|
|||
return;
|
||||
}
|
||||
|
||||
let options = {includeHref: true};
|
||||
let changesets = await hg.fetchChangesets(th.revision, options);
|
||||
let level = colors.blue("push");
|
||||
let changesets = await hg.fetchChangesets(th.revision);
|
||||
|
||||
for (let changeset of changesets) {
|
||||
let level = colors.blue("push");
|
||||
let desc = changeset.desc.split("\n")[0];
|
||||
irc.say(`[${level}] ${changeset.href} - ${changeset.author.name} - ${desc}`);
|
||||
irc.say(`[${level}] ${changeset.href} - ${changeset.author.name} - ${changeset.desc}`);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -58,11 +57,25 @@ tcc.onTaskFailed(async function (msg) {
|
|||
let collection = Object.keys(th.collection || {})[0] || "opt";
|
||||
let platform = PLATFORMS[th.build.platform] || th.build.platform;
|
||||
|
||||
let level = colors.red("failure");
|
||||
// Fetch changesets.
|
||||
let changesets = await hg.fetchChangesets(th.revision);
|
||||
let authors = changesets.map(changeset => changeset.author);
|
||||
let url = TASK_INSPECTOR_URL + taskId;
|
||||
let authors = await hg.fetchBlamelist(th.revision);
|
||||
let level = colors.red("failure");
|
||||
|
||||
let blame = unique(authors.map(author => author.name)).join(", ");
|
||||
irc.say(`[${level}] ${url} - ${task.metadata.name} @ ${platform} ${collection} (blame: ${blame})`);
|
||||
|
||||
// Build descriptions.
|
||||
let descriptions = changesets.map(changeset => {
|
||||
return `${changeset.author.name} - ${changeset.desc}\n${changeset.href}`;
|
||||
});
|
||||
|
||||
// Send emails.
|
||||
email.send(authors,
|
||||
`[NSS Taskcluster] ${task.metadata.name} FAILING on ${platform} ${collection} @ ${th.revision}`,
|
||||
`${task.metadata.name} @ ${platform} ${collection}\n` +
|
||||
`${url}\n\n${descriptions.join("\n\n")}`);
|
||||
});
|
||||
|
||||
// Join ASAP.
|
||||
|
|
Загрузка…
Ссылка в новой задаче