hubot-rocketchat-gitlab
Version:
Hubot script to integrate with gitlab
344 lines (267 loc) • 10.2 kB
JavaScript
// Description:
// Create and mark tasks to do, done, etc.
// Commands:
// hubot p|project search <term>
// hubot p|project list
// hubot p|project set <project_id>
// hubot u|user list
// hubot m|milestone list <all|opened|closed>?
// hubot b|build list <created|pending|running|failed|success|canceled|skipped>?
// hubot b|build play <build_id>
// hubot b|build retry <build_id>
// hubot b|build erase <build_id>
// hubot i|issue list <all|opened|closed>?
// hubot i|issue create <title>\n<body>
// hubot i|issue assign <issue_id> <username>
// hubot i|issue <close|reopen|remove> <issue_id>
// hubot pi|pipeline list
// hubot d|deployment list
// Dependencies:
// hubot-redis-brain node-gitlab
/*jslint node: true*/
module.exports = function(robot) {
// var GITLAB_RECORD_LIMIT = process.env.GITLAB_RECORD_LIMIT || 20;
var GITLAB_URL = process.env.GITLAB_URL;
var GITLAB_TOKEN = process.env.GITLAB_TOKEN;
var gitlab = require('gitlab')({
url: GITLAB_URL,
token: GITLAB_TOKEN
});
var _ = require('underscore');
var help = {};
robot.brain.on('loaded', function() {
});
function describe(command, description) {
help[command] = description;
}
function limitResult(res, result) {
if (res.params.limit > 0) {
return result.slice(0, res.params.limit);
}
return result;
}
function extractParams(res, params) {
params = params.replace(/\s+/g, '').split(',');
var defaultParams = {
'project': function() {
return robot.brain.get('gitlab_project_by_room_'+res.envelope.room);
}
};
for (var i = 0; i < params.length; i++) {
var param = params[i];
res.params[param] = res.match[i+1];
if (!res.params[param] && defaultParams[param]) {
res.params[param] = typeof defaultParams[param] === 'function' ? defaultParams[param]() : defaultParams[param];
}
}
// console.log('Params:', JSON.stringify(res.params, null, 2));
}
function getSetProjectMessage() {
var robot_name = robot.alias || robot.name;
return `Use \`${robot_name} project set #PROJECT_ID\` to set default project`;
}
// Renders
function renderProjects(res, msg, records) {
var found = false;
_.forEach(limitResult(res, records), function(item) {
msg += `\n[#${item.id} - ${item.path_with_namespace}](${item.web_url})`;
if (String(item.id) === String(res.params.project)) {
found = true;
msg += ' - **default**';
}
});
if (found === false) {
msg += '\n\n'+getSetProjectMessage();
}
return msg;
}
function renderUsers(res, msg, records) {
var found = false;
_.forEach(limitResult(res, records), function(item) {
msg += `\n[#${item.id} - ${item.username} - ${item.name}](${item.web_url})`;
});
return msg;
}
function renderMilestones(res, msg, records) {
_.forEach(limitResult(res, records), function(item) {
msg += `\n#${item.iid} - ${item.title}`;
if (item.state === 'closed') {
msg += ' **CLOSED**';
}
});
return msg;
}
function renderIssues(res, msg, records) {
_.forEach(limitResult(res, records), function(item) {
msg += `\n[#${item.iid} - ${item.title}](${item.web_url})`;
if (item.state === 'closed') {
msg += ' **CLOSED**';
}
});
return msg;
}
function renderPipelines(res, msg, records) {
_.forEach(limitResult(res, records), function(item) {
msg += `\n#${item.id} - ${item.ref} - **${item.status}**`;
});
return msg;
}
function renderBuilds(res, msg, records) {
_.forEach(limitResult(res, records), function(item) {
msg += `\n#${item.id} - ${item.name} (stage: ${item.stage}, branch: ${item.ref}) - **${item.status}**`;
});
return msg;
}
robot.listenerMiddleware(function(context, next, done) {
context.response.params = context.response.params || {};
if (!context.listener.options) {
return next();
}
if (context.listener.options.params) {
extractParams(context.response, context.listener.options.params);
}
if (context.listener.options.requireProject === true) {
context.response.params.project = robot.brain.get('gitlab_project_by_room_' + context.response.envelope.room);
if (!context.response.params.project) {
return context.response.reply(getSetProjectMessage());
}
}
next();
});
// Project
robot.respond(/p(?:roject)? search (.+)/i, {params: 'search', requireProject: true}, function(res) {
gitlab.projects.search(res.params.search, function(records) {
var msg = 'Here is your list of projects\n';
res.reply(renderProjects(res, msg, records));
});
});
robot.respond(/p(?:roject)? list/i, {params: 'project'}, function(res) {
gitlab.projects.all(function(records) {
var msg = 'Here is your list of projects\n';
res.reply(renderProjects(res, msg, records));
});
});
robot.respond(/p(?:roject)? set (\d+)/i, {params: 'project'}, function(res) {
gitlab.projects.show(res.params.project, function(record) {
if (!record) {
return res.reply(`Project #${res.params.project} not found`);
}
robot.brain.set('gitlab_project_by_room_'+res.envelope.room, record.id);
res.reply(`Default project setted to \`#${robot.brain.get('gitlab_project_by_room_'+res.envelope.room)} - ${record.name}\``);
});
});
// User
robot.respond(/u(?:ser)? list/i, function(res) {
gitlab.users.all(function(records) {
var msg = 'Here is your list of users\n';
console.log(records);
res.reply(renderUsers(res, msg, records));
});
});
// Milestone
robot.respond(/m(?:ilestone)? list\s?(all|opened|closed)*/i, {params: 'status', requireProject: true}, function(res) {
gitlab.projects.milestones.all(res.params.project, function(records) {
var msg = `Milestones from **Project #${res.params.project}**\n`;
res.reply(renderMilestones(res, msg, records));
});
});
// Builds
robot.respond(/b(?:uild)? list\s?(created|pending|running|failed|success|canceled|skipped)?/i, {params: 'scope', requireProject: true}, function(res) {
var params = {};
if (res.params.scope) {
params.scope = res.params.scope;
}
gitlab.projects.builds.listBuilds(res.params.project, params, function(records) {
var msg = `Builds from **Project #${res.params.project}**\n`;
res.reply(renderBuilds(res, msg, records));
});
});
robot.respond(/b(?:uild)? play (\d+)/i, {params: 'build', requireProject: true}, function(res) {
gitlab.projects.builds.play(res.params.project, res.params.build, function(record) {
var msg = `Playing build ${res.params.build} in **Project #${res.params.project}**\n`;
if (record == true) {
return res.reply(msg+'Build already executed or nonexistent');
}
res.reply(renderBuilds(res, msg, [record]));
});
});
robot.respond(/b(?:uild)? retry (\d+)/i, {params: 'build', requireProject: true}, function(res) {
gitlab.projects.builds.retry(res.params.project, res.params.build, function(record) {
var msg = `Retrying build ${res.params.build} in **Project #${res.params.project}**\n`;
res.reply(renderBuilds(res, msg, [record]));
});
});
robot.respond(/b(?:uild)? erase (\d+)/i, {params: 'build', requireProject: true}, function(res) {
gitlab.projects.builds.erase(res.params.project, res.params.build, function(record) {
var msg = `Erasing build ${res.params.build} in **Project #${res.params.project}**\n`;
if (record == true) {
return res.reply(msg+'Build already erased or nonexistent');
}
res.reply(renderBuilds(res, msg, [record]));
});
});
// Issue
robot.respond(/i(?:ssue)? list\s?(all|opened|closed)*/i, {params: 'status', requireProject: true}, function(res) {
gitlab.projects.issues.list(res.params.project, function(records) {
var msg = `Issues from **Project #${res.params.project}**\n`;
res.reply(renderIssues(res, msg, records));
});
});
robot.respond(/i(?:ssue)? create\s(.+)\s*\n?((?:.*\n?)*)/i, {params: 'title, description', requireProject: true}, function(res) {
var data = {
title: res.params.title,
description: res.params.description
};
gitlab.issues.create(res.params.project, data, function(record) {
var msg = `Issue created in **Project #${res.params.project}**\n`;
res.reply(renderIssues(res, msg, [record]));
});
});
robot.respond(/i(?:ssue)? assign (\d+) (\w+)/i, {params: 'issue, username', requireProject: true}, function(res) {
gitlab.users.all(function(users) {
var user = _.findWhere(users, {username: res.params.username});
if (!user) {
return res.reply(`User with username \`${res.params.username}\` not found`);
}
var data = {
assignee_id: user.id
};
gitlab.issues.edit(res.params.project, res.params.issue, data, function(record) {
var msg = `Issue assigned to \`${user.username}\` in **Project #${res.params.project}**\n`;
res.reply(msg);
});
});
});
robot.respond(/i(?:ssue)? (close|reopen) (\d+)/i, {params: 'action, issue', requireProject: true}, function(res) {
var data = {
state_event: res.params.action
};
gitlab.issues.edit(res.params.project, res.params.issue, data, function(record) {
var msg = `Issue ${record.id} is now ${record.state} in **Project #${res.params.project}**\n`;
res.reply(renderIssues(res, msg, [record]));
});
});
robot.respond(/i(?:ssue)? (remove) (\d+)/i, {params: 'action, issue', requireProject: true}, function(res) {
gitlab.issues.remove(res.params.project, res.params.issue, function(record) {
if (record === true) {
res.reply(`Issue ${res.params.issue} was removed in **Project #${res.params.project}**`);
} else {
res.reply(`There was a problem removing issue ${res.params.isseu} in **Project #${res.params.project}**`);
}
});
});
// Pipeline
robot.respond(/pi(?:peline)? list/i, {requireProject: true}, function(res) {
gitlab.pipelines.all(res.params.project, function(records) {
var msg = `Pipeline list in **Project #${res.params.project}**\n`;
res.reply(renderPipelines(res, msg, records));
});
});
// Deployments
robot.respond(/d(?:eployment)? list/i, {requireProject: true}, function(res) {
gitlab.deployments.all(res.params.project, function(records) {
var msg = `Pipeline list in **Project #${res.params.project}**\n`;
res.reply(renderPipelines(res, msg, records));
});
});
};