parent
e277e89eab
commit
d2460adf36
@ -0,0 +1,48 @@ |
|||||||
|
|
||||||
|
/** |
||||||
|
* Module dependencies. |
||||||
|
*/ |
||||||
|
|
||||||
|
var https = require('https'); |
||||||
|
var fs = require('fs'); |
||||||
|
|
||||||
|
https.globalAgent.options.ca = https.globalAgent.options.ca || []; |
||||||
|
https.globalAgent.options.ca.push(fs.readFileSync("POS-CA.crt")); |
||||||
|
|
||||||
|
var express = require('express'); |
||||||
|
var routes = require('./routes'); |
||||||
|
var http = require('http'); |
||||||
|
var path = require('path'); |
||||||
|
|
||||||
|
var app = express(); |
||||||
|
|
||||||
|
// all environments
|
||||||
|
app.set('port', process.env.PORT || 3000); |
||||||
|
app.set('views', path.join(__dirname, 'views')); |
||||||
|
app.set('view engine', 'jade'); |
||||||
|
app.set('gitpath', 'data/git'); |
||||||
|
app.set('tmpcodepath', 'data/code'); |
||||||
|
app.set('releasepath', 'data/release'); |
||||||
|
app.use(express.favicon()); |
||||||
|
app.use(express.logger('dev')); |
||||||
|
app.use(express.json()); |
||||||
|
app.use(express.urlencoded()); |
||||||
|
app.use(express.methodOverride()); |
||||||
|
app.use(app.router); |
||||||
|
app.use(express.static(path.join(__dirname, 'public'))); |
||||||
|
|
||||||
|
// development only
|
||||||
|
if ('development' == app.get('env')) { |
||||||
|
app.use(express.errorHandler()); |
||||||
|
} |
||||||
|
|
||||||
|
app.get('/', routes.index); |
||||||
|
app.post('/github/postreceive', routes.postreceive); |
||||||
|
app.get('/manual', routes.manual.get); |
||||||
|
app.post('/manual', routes.manual.post); |
||||||
|
app.get('/status', routes.status.image); |
||||||
|
app.get('/status.svg', routes.status.image); |
||||||
|
|
||||||
|
http.createServer(app).listen(app.get('port'), function(){ |
||||||
|
console.log('Express server listening on port ' + app.get('port')); |
||||||
|
}); |
@ -0,0 +1,63 @@ |
|||||||
|
"use strict"; |
||||||
|
|
||||||
|
var fs = require('fs'); |
||||||
|
var fse = require('fs-extra'); |
||||||
|
var gitLoader = require('./git-loader'); |
||||||
|
var processor = require('./task-processor'); |
||||||
|
|
||||||
|
var build = function (options, callback) { |
||||||
|
var url = options.url, |
||||||
|
owner = options.owner, |
||||||
|
reponame = options.reponame, |
||||||
|
rev = options.rev, |
||||||
|
branch = options.branch, |
||||||
|
local = options.app.get('gitpath') + "/" + owner + "/" + reponame + ".git", |
||||||
|
tmp = options.app.get('tmpcodepath') + "/" + owner + "/" + reponame + "/" + branch + "/" + rev, |
||||||
|
exported = tmp + "/code", |
||||||
|
release = options.app.get('releasepath') + "/" + owner + "/" + reponame + "/" + branch + "/" + rev; |
||||||
|
|
||||||
|
fse.mkdirsSync(release); |
||||||
|
|
||||||
|
gitLoader({ |
||||||
|
remote: url + ".git", |
||||||
|
local: local, |
||||||
|
branch: branch, |
||||||
|
hash: rev, |
||||||
|
exported: tmp + "/code", |
||||||
|
}, function(err) { |
||||||
|
if (err) { |
||||||
|
console.log(err); |
||||||
|
} |
||||||
|
console.log("Done loading from git"); |
||||||
|
fs.exists(exported + "/mbs.json", function (exists) { |
||||||
|
if (!exists) { |
||||||
|
return callback(null, "MBSNotFound"); |
||||||
|
} |
||||||
|
fs.readFile(exported + "/mbs.json", function (err, data) { |
||||||
|
if (err) { |
||||||
|
return callback(err, "MBSUnableToRead"); |
||||||
|
} |
||||||
|
|
||||||
|
var task; |
||||||
|
try { |
||||||
|
task = JSON.parse(data); |
||||||
|
} catch(err) { |
||||||
|
console.log("Malformed data: " + data); |
||||||
|
return callback(err, "MBSMalformed"); |
||||||
|
} |
||||||
|
|
||||||
|
processor.processTask(task, function (err, result) { |
||||||
|
if (err) { |
||||||
|
return callback(err, result); |
||||||
|
} |
||||||
|
|
||||||
|
fs.writeFile(release + "/report.json", JSON.stringify(result), function (err) { |
||||||
|
return callback(err, result); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
exports.build = build; |
@ -0,0 +1,95 @@ |
|||||||
|
"use strict"; |
||||||
|
|
||||||
|
var git = require('git-node'), |
||||||
|
async = require('async'), |
||||||
|
fs = require('fs'), |
||||||
|
fse = require('fs-extra'), |
||||||
|
basename = require('path').basename, |
||||||
|
mkdirs = function (path) { |
||||||
|
/*jslint stupid: true */ |
||||||
|
fse.mkdirsSync(path); |
||||||
|
}, |
||||||
|
removedirs = function (path) { |
||||||
|
/*jslint stupid: true */ |
||||||
|
fse.removeSync(path); |
||||||
|
}; |
||||||
|
|
||||||
|
/* |
||||||
|
options = { |
||||||
|
"remote": "https://github.com/visionmedia/express.git", |
||||||
|
"local": "D:\\data\\repositories\\visionmedia\\express.git\\", |
||||||
|
"branch": "1.x", |
||||||
|
"hash": "82e15cf321fccf3215068814d1ea1aeb3581ddb3", |
||||||
|
"exported": "D:\\data\\exportedsource\\visionmedia\\express\\82e15cf321fccf3215068814d1ea1aeb3581ddb3\\", |
||||||
|
} |
||||||
|
*/ |
||||||
|
|
||||||
|
module.exports = function (options, globalCallback) { |
||||||
|
var url = options.remote, |
||||||
|
remote = git.remote(url), |
||||||
|
path = options.local, |
||||||
|
repo = git.repo(path), |
||||||
|
exported = options.exported, |
||||||
|
opts = { |
||||||
|
want: options.branch, |
||||||
|
/*onProgress: function (progress) { |
||||||
|
process.stderr.write(progress); |
||||||
|
}*/ |
||||||
|
}, |
||||||
|
done = function () { |
||||||
|
globalCallback(); |
||||||
|
}; |
||||||
|
|
||||||
|
mkdirs(path); |
||||||
|
|
||||||
|
//console.log("Cloning %s to %s", url, path);
|
||||||
|
|
||||||
|
repo.fetch(remote, opts, function (err) { |
||||||
|
if (err) { |
||||||
|
return globalCallback(err); |
||||||
|
} |
||||||
|
|
||||||
|
//console.log("Done fetching");
|
||||||
|
|
||||||
|
removedirs(exported); |
||||||
|
mkdirs(exported); |
||||||
|
|
||||||
|
var q = async.queue(function (task, callback) { |
||||||
|
//console.log("Going to write file " + task.path + " (" + task.buffer.length + " bytes)");
|
||||||
|
fs.writeFile(exported + "/" + task.path, task.buffer, function (err, result) { |
||||||
|
//console.log("Done writing file " + task.path);
|
||||||
|
callback(err, result); |
||||||
|
}); |
||||||
|
}, 10); |
||||||
|
|
||||||
|
repo.treeWalk(options.hash, function (err, tree) { |
||||||
|
if (err) { |
||||||
|
return globalCallback(err); |
||||||
|
} |
||||||
|
|
||||||
|
var onEntry = function (err, entry) { |
||||||
|
if (err) { |
||||||
|
return globalCallback(err); |
||||||
|
} |
||||||
|
|
||||||
|
if (!entry) { |
||||||
|
if (q.length() === 0) { |
||||||
|
process.nextTick(done); |
||||||
|
} else { |
||||||
|
q.drain = done; |
||||||
|
} |
||||||
|
return; |
||||||
|
} |
||||||
|
//console.log(" %s %s (%s)", entry.hash, entry.path, entry.type);
|
||||||
|
if (entry.type === "tree") { |
||||||
|
mkdirs(exported + "/" + entry.path); |
||||||
|
} else if (entry.type === "blob") { |
||||||
|
q.push({path: entry.path, buffer: entry.body }); |
||||||
|
} |
||||||
|
return tree.read(onEntry); |
||||||
|
}; |
||||||
|
|
||||||
|
tree.read(onEntry); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}; |
@ -0,0 +1,79 @@ |
|||||||
|
"use strict"; |
||||||
|
|
||||||
|
//TaskProcessor does not look like EventEmitter, so no need to extend EventEmitter and use `emit' here.
|
||||||
|
var TaskProcessor = function (task, outerProcessor, callback) { |
||||||
|
if (!this) { |
||||||
|
return new TaskProcessor(task); |
||||||
|
} |
||||||
|
|
||||||
|
var self = this, |
||||||
|
taskImpl = require('./tasks/' + task.type.match(/[\w\-]/g).join("")), |
||||||
|
taskWorker = taskImpl(task.params, self), |
||||||
|
errors = [], |
||||||
|
process = function () { |
||||||
|
taskWorker.process(); |
||||||
|
}, |
||||||
|
getOuterPrefix = function (prefix) { |
||||||
|
return task.name + (prefix ? "/" + prefix : ""); |
||||||
|
}, |
||||||
|
onError = function (message, prefix) { |
||||||
|
errors.push(message); |
||||||
|
outerProcessor.onError(message, getOuterPrefix(prefix)); |
||||||
|
}, |
||||||
|
onWarn = function (message, prefix) { |
||||||
|
outerProcessor.onWarn(message, getOuterPrefix(prefix)); |
||||||
|
}, |
||||||
|
onInfo = function (message, prefix) { |
||||||
|
outerProcessor.onInfo(message, getOuterPrefix(prefix)); |
||||||
|
}, |
||||||
|
processTask = function (innerTask, innerCallback) { |
||||||
|
var innerProcessor = new TaskProcessor(innerTask, self, innerCallback); |
||||||
|
innerProcessor.process(); |
||||||
|
}, |
||||||
|
done = function () { |
||||||
|
callback(errors.join("\r\n")); |
||||||
|
}; |
||||||
|
|
||||||
|
self.process = process; |
||||||
|
self.onError = onError; |
||||||
|
self.onWarn = onWarn; |
||||||
|
self.onInfo = onInfo; |
||||||
|
self.processTask = processTask; |
||||||
|
self.done = done; |
||||||
|
}; |
||||||
|
|
||||||
|
exports.processTask = function (task, callback) { |
||||||
|
var errors = {}, |
||||||
|
warns = {}, |
||||||
|
infos = {}, |
||||||
|
messageProcessor = function (list) { |
||||||
|
return function (message, prefix) { |
||||||
|
var i, |
||||||
|
parts = prefix.split("/"), |
||||||
|
innerList = list; |
||||||
|
|
||||||
|
for (i = 0; i < parts.length; i += 1) { |
||||||
|
innerList = (innerList[parts[i]] = innerList[parts[i]] || {}); |
||||||
|
} |
||||||
|
|
||||||
|
innerList.$messages = innerList.$messages || []; |
||||||
|
innerList.$messages.push(message); |
||||||
|
|
||||||
|
list.$allMessages = list.$allMessages || []; |
||||||
|
list.$allMessages.push({ prefix: prefix, message: message }); |
||||||
|
}; |
||||||
|
}, |
||||||
|
processor = new TaskProcessor(task, { |
||||||
|
onError: messageProcessor(errors), |
||||||
|
onWarn: messageProcessor(warns), |
||||||
|
onInfo: messageProcessor(infos) |
||||||
|
}, function (err) { |
||||||
|
callback(err, { |
||||||
|
errors: errors, |
||||||
|
warns: warns, |
||||||
|
infos: infos |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
processor.process(); |
||||||
|
}; |
@ -0,0 +1,21 @@ |
|||||||
|
"use strict"; |
||||||
|
|
||||||
|
module.exports = function (params, processor) { |
||||||
|
return { |
||||||
|
process: function () { |
||||||
|
if (params.error) { |
||||||
|
processor.onError(params.error); |
||||||
|
} |
||||||
|
|
||||||
|
if (params.warn) { |
||||||
|
processor.onWarn(params.warn); |
||||||
|
} |
||||||
|
|
||||||
|
if (params.info) { |
||||||
|
processor.onInfo(params.info); |
||||||
|
} |
||||||
|
|
||||||
|
processor.done(); |
||||||
|
} |
||||||
|
}; |
||||||
|
}; |
@ -0,0 +1,15 @@ |
|||||||
|
{ |
||||||
|
"name": "micro-build-server", |
||||||
|
"version": "0.0.1", |
||||||
|
"private": true, |
||||||
|
"scripts": { |
||||||
|
"start": "forever -c node app.js" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"express": "3.4.4", |
||||||
|
"jade": "*", |
||||||
|
"async": "~0.2.9", |
||||||
|
"fs-extra": "~0.8.1", |
||||||
|
"git-node": "~0.1.1" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,8 @@ |
|||||||
|
body { |
||||||
|
padding: 50px; |
||||||
|
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; |
||||||
|
} |
||||||
|
|
||||||
|
a { |
||||||
|
color: #00B7FF; |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
|
||||||
|
/* |
||||||
|
* GET home page. |
||||||
|
*/ |
||||||
|
|
||||||
|
exports.index = function(req, res){ |
||||||
|
res.render('index', { title: 'Express' + req + "qq" }); |
||||||
|
}; |
||||||
|
|
||||||
|
exports.postreceive = require('./postreceive'); |
||||||
|
exports.manual = require('./manual'); |
||||||
|
exports.status = require('./status'); |
@ -0,0 +1,19 @@ |
|||||||
|
var builder = require('../lib/builder'); |
||||||
|
|
||||||
|
exports.get = function (req, res) { |
||||||
|
res.render('manual'); |
||||||
|
}; |
||||||
|
|
||||||
|
exports.post = function (req, res) { |
||||||
|
var options = req.body; |
||||||
|
options.app = req.app; |
||||||
|
|
||||||
|
builder.build(options, function (err, result) { |
||||||
|
console.log("Done processing manual request"); |
||||||
|
console.log("Error: " + err); |
||||||
|
console.log("Result:"); |
||||||
|
console.log(result); |
||||||
|
res.render('manual-done', {err: err, result: result}); |
||||||
|
//res.render("manual-done", { err: err, result: result });
|
||||||
|
}); |
||||||
|
}; |
@ -0,0 +1,29 @@ |
|||||||
|
var builder = require('../lib/builder'); |
||||||
|
|
||||||
|
/* |
||||||
|
* POST from github |
||||||
|
*/ |
||||||
|
|
||||||
|
module.exports = function(req, res){ |
||||||
|
if (!req.body || !req.body.payload) { |
||||||
|
res.end(); |
||||||
|
} |
||||||
|
|
||||||
|
var payload = JSON.parse(req.body.payload), |
||||||
|
repository = payload.repository; |
||||||
|
|
||||||
|
builder.build({ |
||||||
|
app: req.app, |
||||||
|
url: repository.url, |
||||||
|
owner: repository.owner.name, |
||||||
|
reponame: repository.name, |
||||||
|
rev: payload.after, |
||||||
|
branch: payload.ref |
||||||
|
}, function (err, result) { |
||||||
|
console.log("Done processing request from GitHub"); |
||||||
|
console.log("Error: " + err); |
||||||
|
console.log("Result:"); |
||||||
|
console.log(result); |
||||||
|
res.end(); |
||||||
|
}); |
||||||
|
}; |
@ -0,0 +1,5 @@ |
|||||||
|
exports.image = function(req, res){ |
||||||
|
console.log(req.headers); |
||||||
|
res.setHeader('Content-Type', 'image/svg+xml'); |
||||||
|
res.render('status-image', { title: 'Express' + req + "qq", status: "Error" }); |
||||||
|
}; |
@ -0,0 +1,5 @@ |
|||||||
|
extends layout |
||||||
|
|
||||||
|
block content |
||||||
|
h1= title |
||||||
|
p Welcome to #{title} |
@ -0,0 +1,7 @@ |
|||||||
|
doctype 5 |
||||||
|
html |
||||||
|
head |
||||||
|
title= title |
||||||
|
link(rel='stylesheet', href='/stylesheets/style.css') |
||||||
|
body |
||||||
|
block content |
@ -0,0 +1,9 @@ |
|||||||
|
extends layout |
||||||
|
|
||||||
|
block content |
||||||
|
h1 Manual build request processed! |
||||||
|
h2 Error |
||||||
|
pre #{err} |
||||||
|
h2 Result |
||||||
|
pre |
||||||
|
= JSON.stringify(result, null, 4) |
@ -0,0 +1,8 @@ |
|||||||
|
extends layout |
||||||
|
|
||||||
|
block content |
||||||
|
h1 Manual build request processed! |
||||||
|
h2 Error |
||||||
|
pre #{err} |
||||||
|
h2 Result |
||||||
|
pre #{result} |
@ -0,0 +1,24 @@ |
|||||||
|
extends layout |
||||||
|
|
||||||
|
block content |
||||||
|
h1 Manual build request |
||||||
|
|
||||||
|
form(method="POST") |
||||||
|
table |
||||||
|
tr |
||||||
|
td URL |
||||||
|
td: input(type="text", name="url", value="https://github.pos/igor-prokhorov/test-github-integration") |
||||||
|
tr |
||||||
|
td Owner |
||||||
|
td: input(type="text", name="owner", value="igor-prokhorov") |
||||||
|
tr |
||||||
|
td Repository |
||||||
|
td: input(type="text", name="reponame", value="test-github-integration") |
||||||
|
tr |
||||||
|
td Version |
||||||
|
td: input(type="text", name="rev", value="0d0ace9a07a43d9c8db2eb4bc8182ac7bd5a25c9") |
||||||
|
tr |
||||||
|
td Branch |
||||||
|
td: input(type="text", name="branch", value="refs/heads/master") |
||||||
|
tr |
||||||
|
td(colspan=2): input(type="submit", value="submit") |
@ -0,0 +1,8 @@ |
|||||||
|
doctype xml |
||||||
|
|
||||||
|
-var fills = {Error: "red", Warn: "yellow", OK: "green" } |
||||||
|
-var colors = {Error: "white", Warn: "black", OK: "black" } |
||||||
|
|
||||||
|
svg(xmlns="http://www.w3.org/2000/svg", version="1.1", width="800px", height="100px") |
||||||
|
rect(width="100%", height="100%", fill=fills[status]) |
||||||
|
text(x=20, y=50, font-size=36, font-weight="bold", fill=colors[status]) Build status: #{status} |
Loading…
Reference in new issue