...
 
Commits (4)
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -4,19 +4,18 @@
"description": "",
"main": "index.js",
"dependencies": {
"babel-cli": "^6.26.0",
"babel-plugin-transform-async-to-generator": "^6.24.1",
"babel-polyfill": "^6.26.0",
"babel-preset-es2015": "^6.24.1",
"delay": "^2.0.0",
"express": "^4.15.5",
"express-winston": "^2.4.0",
"nodemon": "^1.12.1",
"superagent": "^3.7.0",
"superagent-use": "^0.1.0",
"winston": "^3.0.0-rc1"
"winston": "^2.4.0"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-transform-async-to-generator": "^6.24.1",
"babel-polyfill": "^6.26.0",
"babel-preset-es2015": "^6.24.1"
},
"devDependencies": {},
"scripts": {
"build": "rm -rf dist && babel src --out-dir dist --source-maps inline",
"start": "nodemon -L -w src -w /etc/amenda --exec 'npm run build && nodejs ./dist/index.js'",
......
......@@ -11,13 +11,50 @@ import express from 'express';
import bodyParser from 'body-parser';
import expressWinston from 'express-winston';
import {GitLabAPI, GitLabWebhook} from 'amenda-gitlab';
import logger from './logger';
import GitLabAPI from './GitLabAPI';
import GitLabWebhook from './GitLabWebhook';
(async () => {
async function addMissingProjectHooks(gitlab) {
const requiredProjectHooks = require('./webhook/project').required;
const projects = await gitlab.getProjects();
for (var project of projects) {
const projectHooks = await gitlab.getProjectHooks(project.id);
const missingProjectHooks = requiredProjectHooks.filter((rh) => projectHooks.filter(hook => hook.url == rh.url).length == 0);
for (var missingHook of missingProjectHooks) {
logger.info("adding missing project webhook", {project: project.id, webhook: missingHook});
await gitlab.addProjectHook(project.id, missingHook.url, config.gitlabBot.token, false, missingHook.options);
}
}
}
async function addMissingSystemHooks(gitlab) {
const requiredSystemHooks = require('./webhook/system').required;
const hooks = await gitlab.getSystemHooks();
const missingSystemHooks = requiredSystemHooks.filter((rh) => hooks.filter(hook => hook.url == rh.url).length == 0);
for (var missingHook of missingSystemHooks) {
logger.info("adding missing system webhook", {webhook: missingHook});
await gitlab.addSystemHook(missingHook.url, config.gitlabBot.token, false, missingHook.options);
}
}
function setupAllWebhooks(app) {
const requiredSystemHooks = require('./webhook/system').required;
const requiredProjectHooks = require('./webhook/project').required;
for (const hook of requiredSystemHooks) {
hook.setup(app);
}
for (const hook of requiredProjectHooks) {
hook.setup(app);
}
}
const app = express();
const gitlab = new GitLabAPI(config.gitlab.url);
const gitlab = new GitLabAPI(logger, config.gitlab.url);
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
......@@ -34,9 +71,9 @@ import GitLabWebhook from './GitLabWebhook';
await gitlab.waitUntilReady();
logger.info('GitLab API is ready!');
await GitLabWebhook.addMissingProjectHooks(gitlab);
await GitLabWebhook.addMissingSystemHooks(gitlab);
GitLabWebhook.setupAllWebhooks(app);
await addMissingProjectHooks(gitlab);
await addMissingSystemHooks(gitlab);
setupAllWebhooks(app);
app.get('/ping', (req, res) => res.json({ping: 'pong'}));
......
import { createLogger, format, transports } from 'winston';
import createLogger from 'amenda-logger';
const label = 'gitlab-bot';
const MESSAGE = Symbol.for('message');
const customFormat = format((info, opt) => {
const meta = JSON.stringify(
Object.assign({}, info.meta || info, {
level: undefined,
message: undefined,
splat: undefined,
timestamp: undefined,
label: undefined,
}),
false,
2
);
info[MESSAGE] = info.timestamp + ' ' + info.level + ': ' + info.message + (meta == '{}' ? '' : '\n' + meta);
return info;
});
const logger = createLogger({
level: process.env.NODE_ENV == 'production' ? 'info' : 'debug',
exitOnError: true,
format: format.combine(
format.timestamp(),
format.label({ label: label }),
format.json(),
),
transports: [
new transports.File({ filename: 'error.log', level: 'error' }),
new transports.File({ filename: 'combined.log' }),
],
});
if (process.env.NODE_ENV !== 'production') {
logger.add(
new transports.Console({
handleExceptions: true,
format: format.combine(
format.timestamp(),
format.label({ label: label }),
format.colorize(),
format.splat(),
customFormat(),
),
})
);
}
const logger = createLogger('gitlab-bot');
export default logger;
import config from '/etc/amenda/amenda.json';
import { execSync } from 'child_process';
import {GitLabAPI, GitLabWebhook} from 'amenda-gitlab';
import logger from '../../logger';
import GitLabAPI from '../../GitLabAPI';
import GitLabWebhook from '../../GitLabWebhook';
// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#merge-request-events
export default class MergeRequest extends GitLabWebhook {
......@@ -24,7 +23,7 @@ export default class MergeRequest extends GitLabWebhook {
}
);
const gitlab = new GitLabAPI(config.gitlab.url);
const gitlab = new GitLabAPI(logger, config.gitlab.url);
await gitlab.oauth2Connect(config.gitlab.adminEmail, config.gitlab.adminPassword);
const commits = await gitlab.getMergeRequestCommits(
......
import config from '/etc/amenda/amenda.json';
import logger from '../../logger';
import GitLabAPI from '../../GitLabAPI';
import GitLabWebhook from '../../GitLabWebhook';
import {GitLabAPI, GitLabWebhook} from 'amenda-gitlab';
import {required as requiredProjectHooks} from '../project';
......@@ -13,7 +12,7 @@ export default class ProjectCreated extends GitLabWebhook {
async callback(req, res) {
const webhook = req.body;
const gitlab = new GitLabAPI(config.gitlab.url);
const gitlab = new GitLabAPI(logger, config.gitlab.url);
await gitlab.oauth2Connect(config.gitlab.adminEmail, config.gitlab.adminPassword);
......@@ -27,7 +26,7 @@ export default class ProjectCreated extends GitLabWebhook {
);
await gitlab.addProjectHook(
webhook.project_id, projectHook.url, config.webhook.token, false, projectHook.options
webhook.project_id, projectHook.url, config.gitlabBot.token, false, projectHook.options
);
}
......
This diff is collapsed.
{
"name": "amenda-gitlab",
"version": "0.0.1",
"description": "",
"main": "dist/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "rm -rf dist && babel src --out-dir dist --source-maps inline"
},
"author": "",
"dependencies": {
"babel-plugin-add-module-exports": "^0.2.1",
"delay": "^2.0.0",
"superagent": "^3.7.0",
"superagent-use": "^0.1.0"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-plugin-transform-async-to-generator": "^6.24.1",
"babel-polyfill": "^6.26.0",
"babel-preset-es2015": "^6.24.1"
},
"babel": {
"presets": [
"es2015"
],
"plugins": [
"transform-async-to-generator",
"add-module-exports"
]
}
}
......@@ -3,13 +3,12 @@ const request = require('superagent-use')(require('superagent'));
import fs from 'fs';
import delay from 'delay';
import logger from './logger';
request.use((req) => req.set('Accept', 'application/json'));
export default class GitLabAPI {
constructor(url) {
constructor(logger, url) {
this.url = url;
this.logger = logger;
}
async waitUntilReady() {
......@@ -46,7 +45,7 @@ export default class GitLabAPI {
.get(this.url + '/api/v4/projects')
.set('Authorization', 'Bearer ' + token.access_token);
} catch (e) {
logger.info('getting/renewing OAuth2 token for user %s', username);
this.logger.info('getting/renewing OAuth2 token for user %s', username);
const res = await request
.post(this.url + '/oauth/token')
......@@ -88,7 +87,7 @@ export default class GitLabAPI {
return res.body;
} catch (e) {
logger.error(e);
this.logger.error(e);
}
}
......@@ -113,7 +112,7 @@ export default class GitLabAPI {
return res.body;
} catch (e) {
logger.error(e);
this.logger.error(e);
}
}
......
import config from '/etc/amenda/amenda.json';
import logger from './logger';
export default class GitLabWebhook {
constructor(route, options, eventHeader = false, eventNames = null) {
this.route = route;
......@@ -34,43 +32,5 @@ export default class GitLabWebhook {
setup(app) {
app.post(this.route, this.middleware.bind(this), this.callback.bind(this));
logger.info('webhook setup on %s', this.route, {webhook: this});
}
static async addMissingProjectHooks(gitlab) {
const requiredProjectHooks = require('./webhook/project').required;
const projects = await gitlab.getProjects();
for (var project of projects) {
const projectHooks = await gitlab.getProjectHooks(project.id);
const missingProjectHooks = requiredProjectHooks.filter((rh) => projectHooks.filter(hook => hook.url == rh.url).length == 0);
for (var missingHook of missingProjectHooks) {
logger.info("adding missing project webhook", {project: project.id, webhook: missingHook});
await gitlab.addProjectHook(project.id, missingHook.url, config.gitlabBot.oken, false, missingHook.options);
}
}
}
static async addMissingSystemHooks(gitlab) {
const requiredSystemHooks = require('./webhook/system').required;
const hooks = await gitlab.getSystemHooks();
const missingSystemHooks = requiredSystemHooks.filter((rh) => hooks.filter(hook => hook.url == rh.url).length == 0);
for (var missingHook of missingSystemHooks) {
logger.info("adding missing system webhook", {webhook: missingHook});
await gitlab.addSystemHook(missingHook.url, config.gitlabBot.token, false, missingHook.options);
}
}
static setupAllWebhooks(app) {
const requiredSystemHooks = require('./webhook/system').required;
const requiredProjectHooks = require('./webhook/project').required;
for (const hook of requiredSystemHooks) {
hook.setup(app);
}
for (const hook of requiredProjectHooks) {
hook.setup(app);
}
}
}
export {default as GitLabAPI} from './GitLabAPI';
export {default as GitLabWebhook} from './GitLabWebhook';
This diff is collapsed.
{
"name": "amenda-logger",
"version": "0.0.1",
"description": "",
"main": "dist/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "rm -rf dist && babel src --out-dir dist --source-maps inline"
},
"author": "",
"dependencies": {
"babel-plugin-add-module-exports": "^0.2.1",
"winston": "^3.0.0-rc1"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-polyfill": "^6.26.0",
"babel-preset-es2015": "^6.24.1"
},
"babel": {
"presets": [
"es2015"
],
"plugins": [
"add-module-exports"
]
}
}
import { createLogger, format, transports } from 'winston';
const MESSAGE = Symbol.for('message');
const customFormat = format((info, opt) => {
const meta = JSON.stringify(
Object.assign({}, info.meta || info, {
level: undefined,
message: undefined,
splat: undefined,
timestamp: undefined,
label: undefined,
}),
false,
2
);
info[MESSAGE] = info.timestamp + ' ' + info.level + ': ' + info.message + (meta == '{}' ? '' : '\n' + meta);
return info;
});
export default (label) => {
const logger = createLogger({
level: process.env.NODE_ENV == 'production' ? 'info' : 'debug',
exitOnError: true,
format: format.combine(
format.timestamp(),
format.label({ label: label }),
format.json(),
),
transports: [
new transports.File({ filename: 'error.log', level: 'error' }),
new transports.File({ filename: 'combined.log' }),
],
});
if (process.env.NODE_ENV !== 'production') {
logger.add(
new transports.Console({
handleExceptions: true,
format: format.combine(
format.timestamp(),
format.label({ label: label }),
format.colorize(),
format.splat(),
customFormat(),
),
})
);
}
return logger;
};
......@@ -6,7 +6,7 @@ ssl_certs_common_name: "{{ hostname }}"
docker_group_members:
- ubuntu
nodejs_version: "6.x"
nodejs_version: "8.x"
gitlab_bot_webhook_token: "a153b0d18961a9947a63888de405eb40"
gitlab_bot_user:
......
......@@ -6,6 +6,7 @@
- { role: config, tags: ["config", "api", "gitlab-bot"] }
- { role: gitlab, tags: ["api", "gitlab", "gitlab-bot"] }
- { role: reverse-proxy, tags: ["api", "doc", "gitlab"] }
- { role: lib, tags: ["lib", "gitlab-bot"] }
- { role: api, tags: ["api"] }
- { role: app, tags: ["app"] }
- { role: gitlab-bot, tags: ["gitlab-bot", "gitlab"] }
......
......@@ -9,21 +9,23 @@
pip:
name: git+https://github.com/Legilibre/SedLex.git
virtualenv_python: python3
virtualenv: /opt/duralex-sedlex
virtualenv: /opt/sedlex
when: not duralex_sedlex_sedlex_bin.stat.exists
- name: Install sedlex dependencies
- name: Install SedLex dependencies
pip:
requirements: /srv/sedlex/requirements.txt
virtualenv_python: python3
virtualenv: /opt/sedlex
when: duralex_sedlex_sedlex_bin.stat.exists
- name: Link the sedlex binary
file:
src: "{{ duralex_sedlex_sedlex_bin.stat.exists | ternary('/srv/sedlex/bin/sedlex', '/opt/duralex-sedlex/bin/sedlex') }}"
dest: /usr/local/bin/sedlex
state: link
- name: Install SedLex
pip:
name: /srv/sedlex
editable: yes
virtualenv_python: python3
virtualenv: /opt/sedlex
when: duralex_sedlex_sedlex_bin.stat.exists
- name: Check if /srv/duralex/bin/duralex exists
stat:
......@@ -34,19 +36,20 @@
pip:
name: git+git://github.com/Legilibre/DuraLex.git@0.3
virtualenv_python: python3
virtualenv: /opt/duralex-sedlex
virtualenv: /opt/duralex
when: not duralex_sedlex_duralex_bin.stat.exists
- name: Install duralex dependencies
- name: Install DuraLex dependencies
pip:
requirements: /srv/duralex/requirements.txt
virtualenv_python: python3
virtualenv: /opt/duralex
when: duralex_sedlex_duralex_bin.stat.exists
- name: Link the duralex binary
file:
src: "{{ duralex_sedlex_duralex_bin.stat.exists | ternary('/srv/duralex/bin/duralex', '/opt/duralex-sedlex/bin/duralex') }}"
dest: /usr/local/bin/duralex
state: link
force: yes
- name: Install DuraLex
pip:
name: /srv/duralex
editable: yes
virtualenv_python: python3
virtualenv: /opt/duralex
when: duralex_sedlex_sedlex_bin.stat.exists
---
gitlab_version: 10.1.0-ce.0
gitlab_version: 10.1.4-ce.0
gitlab_users:
---
- file:
src: "/vagrant/lib/{{ item }}"
dest: "/usr/local/lib/npm/lib/node_modules/{{ item }}"
state: "link"
with_items:
- amenda-gitlab
- amenda-logger
- npm:
path: /vagrant/lib/{{ item }}
with_items:
- amenda-gitlab
- amenda-logger