start working on notifiers

This commit is contained in:
oleg 2015-05-22 00:09:16 +03:00
parent b4d5e785bb
commit a56bc30bc7
9 changed files with 150 additions and 9 deletions

View File

@ -18,6 +18,7 @@ work in progress...
* Ability to change build parameters from ui (at least target branch)
* Semantic versioning and plugins
* Safe id and build numbers generation
* Better tests coverage
## Roadmap

7
app.js
View File

@ -7,7 +7,8 @@ var http = require('http'),
fs = require('fs'),
Steppy = require('twostep').Steppy,
_ = require('underscore'),
reader = require('./lib/reader');
reader = require('./lib/reader'),
notifier = require('./lib/notifier');
var staticServer = new nodeStatic.Server('./static');
var server = http.createServer(function(req, res, next) {
@ -34,6 +35,7 @@ var app = {
app.lib = {};
app.lib.reader = reader;
app.lib.notifier = notifier;
Steppy(
function() {
@ -58,6 +60,7 @@ Steppy(
// register plugins
require('./lib/reader/yaml').register(app);
require('./lib/notifier/console').register(app);
reader.load(app.config.paths.data, 'config', this.slot());
},
@ -66,6 +69,8 @@ Steppy(
console.log('Server config:', JSON.stringify(app.config, null, 4));
notifier.init(app.config.notify, this.slot());
// init resources
require('./resources')(app);
},

View File

@ -2,3 +2,5 @@
nodes:
- type: local
maxExecutorsCount: 1
notify: {}

View File

@ -6,15 +6,26 @@ scm:
repository: ./test/repos/mercurial
rev: default
notify:
on:
- success
- fail
to:
console:
# email:
# - oleg.korobenko@gmail.com
# jabber:
# - oleg.korobenko@gmail.com
steps:
- cmd: >
echo "long multiline string" &&
sleep 2 &&
echo "is not a problem when you're using yaml" &&
echo "cur dir is `pwd`"
- name: sleep
cmd: sleep 4
echo "long multiline string" &&
sleep 2 &&
echo "is not a problem when you're using yaml" &&
echo "cur dir is `pwd`"
# - name: sleep
# cmd: sleep 4
- cmd: echo 1 > 1.txt
- cmd: sleep 4
# - cmd: sleep 4
- cmd: echo 2 > 2.txt
- cmd: cat 1.txt 2.txt

View File

@ -4,7 +4,8 @@ var Steppy = require('twostep').Steppy,
_ = require('underscore'),
Node = require('./node').Node,
EventEmitter = require('events').EventEmitter,
inherits = require('util').inherits;
inherits = require('util').inherits,
notifier = require('./notifier');
function Distributor(params) {
@ -72,6 +73,7 @@ Distributor.prototype._runNext = function(callback) {
error: err ? err.message : null
},
function(err, build) {
notifier.send(build);
// try to run next project from the queue
self._runNext(stepCallback);
}

18
lib/notifier/base.js Normal file
View File

@ -0,0 +1,18 @@
'use strict';
function Notifier() {
}
exports.Notifier = Notifier;
Notifier.prototype.init = function(params, callback) {
callback();
};
/*
* {Object} params.notifyReson
* {Object} params.build
*/
Notifier.prototype.send = function(params, callback) {
callback();
};

26
lib/notifier/console.js Normal file
View File

@ -0,0 +1,26 @@
'use strict';
var BaseNotifier = require('./base').Notifier,
inherits = require('util').inherits;
function Notifier() {
}
inherits(Notifier, BaseNotifier);
exports.register = function(app) {
app.lib.notifier.register('console', Notifier);
};
exports.Notifier = Notifier;
Notifier.prototype.send = function(params, callback) {
var build = params.build;
console.log(
'NOTIFY on %s: build #%s of project %s is %s',
params.notifyReason.strategy,
build.number,
build.project.name,
build.status
);
};

72
lib/notifier/index.js Normal file
View File

@ -0,0 +1,72 @@
'use strict';
var Steppy = require('twostep').Steppy,
_ = require('underscore'),
utils = require('../utils');
var constructors = {},
instances = {};
exports.register = function(type, constructor) {
constructors[type] = constructor;
};
exports.init = function(params, callback) {
Steppy(
function() {
var initGroup = this.makeGroup();
_(constructors).each(function(Constructor, type) {
instances[type] = new Constructor();
instances[type].init(params[type], initGroup.slot());
});
},
callback
);
};
/*
* Check if this completed build should be notified, then notify
*/
exports.send = function(build, callback) {
callback = callback || utils.logErrorCallback;
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();
}
var strategy = _(notify.on).find(function(strategy) {
if (strategy === 'success') {
return build.status === 'done';
} else if (strategy === 'fail') {
return build.status === 'error';
}
});
// Nothing to notify about
if (!strategy) {
return callback();
}
var notifyGroup = this.makeGroup();
_(notify.to).each(function(recipients, type) {
if (type in instances) {
instances[type].send({
build: build,
notifyReason: {strategy: strategy}
}, notifyGroup.slot());
} else {
throw new Error('Unknown notifier: ' + type);
}
});
},
callback
);
};

View File

@ -10,3 +10,7 @@ exports.prune = function(str, length) {
return result.replace(/ $/, words.length ? '...' : '');
};
exports.logErrorCallback = function(err) {
if (err) console.error(err.stack || err);
};