diff --git a/app.js b/app.js index 4d72ec7..5ce240d 100644 --- a/app.js +++ b/app.js @@ -8,7 +8,8 @@ var http = require('http'), Steppy = require('twostep').Steppy, _ = require('underscore'), reader = require('./lib/reader'), - notifier = require('./lib/notifier'); + notifier = require('./lib/notifier'), + project = require('./lib/project'); var staticServer = new nodeStatic.Server('./static'); var server = http.createServer(function(req, res, next) { @@ -70,6 +71,16 @@ Steppy( console.log('Server config:', JSON.stringify(app.config, null, 4)); notifier.init(app.config.notify, this.slot()); + }, + function() { + project.loadAll(app.config.paths.projects, this.slot()); + }, + function(err, projects) { + app.projects = projects; + console.log( + 'Loaded projects: ', + _(projects).chain().pluck('config').pluck('name').value() + ); // init resources require('./resources')(app); diff --git a/data/projects/project1/config.yaml b/data/projects/project1/config.yaml index 65114f5..5c949d2 100644 --- a/data/projects/project1/config.yaml +++ b/data/projects/project1/config.yaml @@ -18,6 +18,11 @@ notify: # jabber: # - oleg.korobenko@gmail.com +trigger: + after: + - status: done + project: project2 + steps: - cmd: > echo "long multiline string" && diff --git a/lib/distributor.js b/lib/distributor.js index 0021bd0..c9b7630 100644 --- a/lib/distributor.js +++ b/lib/distributor.js @@ -20,6 +20,10 @@ function Distributor(params) { self.saveBuild = params.saveBuild || function(build, callback) { callback(null, build); }; + + self.projectsHash = _(params.projects).indexBy(function(project) { + return project.config.name; + }); } inherits(Distributor, EventEmitter); @@ -70,9 +74,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); + self._onBuildComplete(err, build, stepCallback) } ); }); @@ -93,6 +95,35 @@ Distributor.prototype._runNext = function(callback) { ); }; +Distributor.prototype._onBuildComplete = function(err, build, callback) { + var self = this; + + Steppy( + function() { + // process after build triggers + var triggerAfterGroup = this.makeGroup(); + + var after = build.project.trigger && build.project.trigger.after; + if (after) { + _(after).each(function(item) { + if (!item.status || item.status === build.status) { + self.run(item.project, {}, triggerAfterGroup.slot()); + } + }); + } + + }, + function(err, triggerAfterGroupResults) { + // notify about build + notifier.send(build); + + // try to run next project from the queue + self._runNext(this.slot()); + }, + callback + ); +}; + Distributor.prototype._updateBuild = function(build, changes, callback) { var self = this; callback = callback || _.noop; @@ -127,10 +158,12 @@ Distributor.prototype._updateBuild = function(build, changes, callback) { ); }; -Distributor.prototype.run = function(project, params, callback) { - var self = this; +Distributor.prototype.run = function(projectName, params, callback) { + var self = this, + project; Steppy( function() { + project = self.projectsHash[projectName].config; self._updateBuild({}, { project: project, params: params, diff --git a/resources/projects.js b/resources/projects.js index e4daabe..936739d 100644 --- a/resources/projects.js +++ b/resources/projects.js @@ -12,22 +12,9 @@ module.exports = function(app) { var resource = app.dataio.resource('projects'); - var projects, projectsHash; - - project.loadAll(app.config.paths.projects, function(err, loadedProjects) { - if (err) throw err; - projects = loadedProjects; - projectsHash = _(projects).indexBy(function(project) { - return project.config.name; - }); - console.log( - 'Loaded projects: ', - _(projects).chain().pluck('config').pluck('name').value() - ); - }); - var distributor = new Distributor({ nodes: app.config.nodes, + projects: app.projects, saveBuild: function(build, callback) { Steppy( function() { @@ -117,14 +104,13 @@ module.exports = function(app) { }); resource.use('readAll', function(req, res) { - res.send(_(projects).pluck('config')); + res.send(_(app.projects).pluck('config')); }); resource.use('run', function(req, res) { - var projectName = req.data.projectName, - project = projectsHash[projectName]; - console.log('Run the project: %j', project || projectName); - distributor.run(project.config, {}, function(err, build) { + var projectName = req.data.projectName; + console.log('Run the project: %j', projectName); + distributor.run(projectName, {}, function(err, build) { console.log('>>> err, build = ', err && err.stack || err, build); }); res.send(); diff --git a/test/distributor.js b/test/distributor.js index 8fee117..a545be1 100644 --- a/test/distributor.js +++ b/test/distributor.js @@ -9,7 +9,9 @@ var Distributor = require('../lib/distributor').Distributor, describe('Distributor', function() { var distributor, - project1 = {name: 'project1'}; + projects = [{ + config: {name: 'project1'} + }]; var createNodeMock = function(executorRun) { return function(params) { @@ -46,13 +48,14 @@ describe('Distributor', function() { it('instance should be created without errors', function() { distributor = new Distributor({ + projects: projects, nodes: [{type: 'local', maxExecutorsCount: 1}] }); updateBuildSpy = sinon.spy(distributor, '_updateBuild'); }); it('should run without errors', function(done) { - distributor.run(project1, {}, function(err) { + distributor.run('project1', {}, function(err) { expect(err).not.ok(); done(); }); @@ -108,13 +111,14 @@ describe('Distributor', function() { it('instance should be created without errors', function() { distributor = new Distributor({ + projects: projects, nodes: [{type: 'local', maxExecutorsCount: 1}] }); updateBuildSpy = sinon.spy(distributor, '_updateBuild'); }); it('should run without errors', function(done) { - distributor.run(project1, {}, function(err) { + distributor.run('project1', {}, function(err) { expect(err).not.ok(); done(); });