2015-05-21 21:09:16 +00:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
var Steppy = require('twostep').Steppy,
|
|
|
|
_ = require('underscore'),
|
2016-01-10 16:37:19 +00:00
|
|
|
logger = require('../logger')('notifier');
|
2015-07-06 17:19:13 +00:00
|
|
|
|
|
|
|
|
2016-01-10 16:37:19 +00:00
|
|
|
function Notifier(params) {
|
|
|
|
this.db = params.db;
|
2015-05-21 21:09:16 +00:00
|
|
|
|
2016-01-10 16:37:19 +00:00
|
|
|
this.constructors = {};
|
|
|
|
this.instances = {};
|
|
|
|
}
|
2015-05-21 21:09:16 +00:00
|
|
|
|
2016-01-10 16:37:19 +00:00
|
|
|
exports.Notifier = Notifier;
|
|
|
|
|
|
|
|
Notifier.prototype.register = function(type, constructor) {
|
|
|
|
this.constructors[type] = constructor;
|
2015-05-21 21:09:16 +00:00
|
|
|
};
|
|
|
|
|
2016-01-10 16:37:19 +00:00
|
|
|
Notifier.prototype.init = function(params, callback) {
|
|
|
|
var self = this;
|
|
|
|
|
2015-05-21 21:09:16 +00:00
|
|
|
Steppy(
|
|
|
|
function() {
|
|
|
|
var initGroup = this.makeGroup();
|
2016-01-10 16:37:19 +00:00
|
|
|
_(self.constructors).each(function(Constructor, type) {
|
|
|
|
self.instances[type] = new Constructor();
|
|
|
|
self.instances[type].init(params[type], initGroup.slot());
|
2015-05-21 21:09:16 +00:00
|
|
|
});
|
|
|
|
},
|
|
|
|
callback
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2015-06-12 13:26:34 +00:00
|
|
|
// Returns previous (by number) build from the same project
|
2016-01-10 16:37:19 +00:00
|
|
|
Notifier.prototype._getPrevBuild = function(build, callback) {
|
|
|
|
var self = this;
|
|
|
|
|
2015-06-12 13:26:34 +00:00
|
|
|
Steppy(
|
|
|
|
function() {
|
2015-07-15 08:19:22 +00:00
|
|
|
// get id of prev build
|
2016-01-10 16:37:19 +00:00
|
|
|
self.db.builds.find({
|
2015-06-12 13:26:34 +00:00
|
|
|
start: {
|
|
|
|
projectName: build.project.name,
|
|
|
|
number: build.number - 1
|
|
|
|
},
|
|
|
|
limit: 1
|
|
|
|
}, this.slot());
|
|
|
|
},
|
2015-07-15 08:19:22 +00:00
|
|
|
function(err, builds) {
|
|
|
|
// get prev build by id
|
2016-01-10 16:37:19 +00:00
|
|
|
self.db.builds.find({start: {id: builds[0].id}}, this.slot());
|
2015-07-15 08:19:22 +00:00
|
|
|
},
|
2015-06-12 13:26:34 +00:00
|
|
|
function(err, builds) {
|
|
|
|
this.pass(builds[0]);
|
|
|
|
},
|
|
|
|
callback
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2015-05-21 21:09:16 +00:00
|
|
|
/*
|
2015-05-25 19:36:09 +00:00
|
|
|
* Check if that's completed build should be notified, then notify
|
2015-05-21 21:09:16 +00:00
|
|
|
*/
|
2016-01-10 16:37:19 +00:00
|
|
|
Notifier.prototype.send = function(build, callback) {
|
2015-07-05 18:03:58 +00:00
|
|
|
callback = callback || function(err) {
|
|
|
|
if (err) {
|
|
|
|
logger.error('Error during send:', err.stack || err);
|
|
|
|
}
|
|
|
|
};
|
2016-01-10 16:37:19 +00:00
|
|
|
var self = this;
|
|
|
|
|
2015-05-21 21:09:16 +00:00
|
|
|
Steppy(
|
|
|
|
function() {
|
|
|
|
if (!build.completed) {
|
|
|
|
throw new Error('Build should be completed before notify');
|
|
|
|
}
|
|
|
|
|
|
|
|
var notify = build.project.notify;
|
|
|
|
|
|
|
|
// TODO: move to project validation during load
|
|
|
|
if (!notify || !notify.on || !notify.to) {
|
|
|
|
return callback();
|
|
|
|
}
|
|
|
|
|
2015-06-12 13:26:34 +00:00
|
|
|
this.pass(notify);
|
|
|
|
|
|
|
|
// get previous build (for some strategies)
|
|
|
|
if (
|
|
|
|
build.number > 1 &&
|
|
|
|
_(notify.on).intersection(['change']).length
|
|
|
|
) {
|
2016-01-10 16:37:19 +00:00
|
|
|
self._getPrevBuild(build, this.slot());
|
2015-06-12 13:26:34 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
function(err, notify, prevBuild) {
|
2015-05-21 21:09:16 +00:00
|
|
|
var strategy = _(notify.on).find(function(strategy) {
|
2015-06-21 20:53:03 +00:00
|
|
|
if (strategy === 'done') {
|
2015-05-21 21:09:16 +00:00
|
|
|
return build.status === 'done';
|
2015-06-21 20:53:03 +00:00
|
|
|
} else if (strategy === 'error') {
|
2015-05-21 21:09:16 +00:00
|
|
|
return build.status === 'error';
|
2015-06-12 13:26:34 +00:00
|
|
|
} else if (strategy === 'change') {
|
|
|
|
// notify on status change or about first build
|
|
|
|
return prevBuild ? build.status !== prevBuild.status: true;
|
2015-05-21 21:09:16 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Nothing to notify about
|
|
|
|
if (!strategy) {
|
|
|
|
return callback();
|
|
|
|
}
|
|
|
|
|
|
|
|
var notifyGroup = this.makeGroup();
|
|
|
|
_(notify.to).each(function(recipients, type) {
|
2015-07-05 18:03:58 +00:00
|
|
|
logger.log(
|
|
|
|
'Notify about ' + build.project.name + ' build #' +
|
2016-01-10 16:37:19 +00:00
|
|
|
build.number + ' "' + strategy + '" via ' + type
|
2015-07-05 18:03:58 +00:00
|
|
|
);
|
2016-01-10 16:37:19 +00:00
|
|
|
if (type in self.instances) {
|
|
|
|
self.instances[type].send({
|
2015-05-21 21:09:16 +00:00
|
|
|
build: build,
|
|
|
|
notifyReason: {strategy: strategy}
|
|
|
|
}, notifyGroup.slot());
|
|
|
|
} else {
|
|
|
|
throw new Error('Unknown notifier: ' + type);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
callback
|
|
|
|
);
|
|
|
|
};
|