Created
October 16, 2018 17:03
-
-
Save thinhbuzz/84e06bc52d1d5cb12292abfa6a6f3c75 to your computer and use it in GitHub Desktop.
Node JS gitlab webhook receiver and trigger pipelines
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const qs = require('querystring'); | |
const http = require('http'); | |
const https = require('https'); | |
const assert = require('assert'); | |
const config = { | |
port: 3000, | |
projectId: '', | |
pipelineTriggerToken: '', | |
secretToken: null | |
}; | |
assert(config.projectId, 'projectId must not empty'); | |
assert(config.pipelineTriggerToken, 'pipelineTriggerToken must not empty'); | |
server = http.createServer((req, res) => { | |
new Promise((resolve, reject) => { | |
res.writeHead(200, {'Content-Type': 'application/json'}); | |
if (req.method === 'POST') { | |
verifyToken(req.headers); | |
let body = ''; | |
req.on('data', data => { | |
body += data; | |
}); | |
req.on('end', () => { | |
try { | |
resolve({body: JSON.parse(body), headers: req.headers}); | |
} catch (error) { | |
reject(error); | |
} | |
}); | |
req.on('error', error => { | |
reject(error); | |
}); | |
} | |
}) | |
.then(({body}) => { | |
switch (body.object_kind) { | |
case 'merge_request': | |
processMergeRequestEvent(body); | |
break; | |
} | |
res.end(JSON.stringify({message: 'nodejs gitlab Webhook receiver'})); | |
res.writeHead(200, {'Content-Type': 'application/json'}); | |
}) | |
.catch(error => { | |
res.writeHead(500, {'Content-Type': 'application/json'}); | |
res.end(JSON.stringify({message: typeof error === 'object' && error.message ? error.message : 'Internal server error!'})); | |
}); | |
}); | |
server.listen(config.port, () => { | |
console.log('Listening on port ' + config.port); | |
}); | |
function processMergeRequestEvent(body) { | |
let ref; | |
switch (body.object_attributes.state) { | |
case 'opened': | |
ref = body.object_attributes.source_branch; | |
break; | |
case 'merged': | |
ref = body.object_attributes.target_branch; | |
break; | |
} | |
if (!ref) { | |
return; | |
} | |
post({ref}) | |
.then(console.info.bind(console, 'Trigger pipelines success with response:')) | |
.catch(console.error.bind(console, 'Trigger pipelines with error:')); | |
} | |
function verifyToken(headers) { | |
if (!config.secretToken) { | |
return; | |
} | |
if (!headers['x-gitlab-token'] || headers['x-gitlab-token'] !== config.secretToken) { | |
throw new Error('Secret token miss match'); | |
} | |
} | |
function post(data) { | |
return new Promise((resolve, reject) => { | |
data['token'] = config.pipelineTriggerToken; | |
const requestData = qs.stringify(data); | |
const requestOptions = { | |
host: 'gitlab.com', | |
port: 443, | |
path: `/api/v4/projects/${config.projectId}/trigger/pipeline`, | |
method: 'POST', | |
headers: { | |
'Content-Type': 'multipart/form-data', | |
'Content-Length': Buffer.byteLength(requestData) | |
} | |
}; | |
const request = https.request(requestOptions, res => { | |
res.setEncoding('utf8'); | |
let body = ''; | |
res.on('data', data => { | |
body += data; | |
}); | |
res.on('end', () => { | |
try { | |
resolve({body: JSON.parse(body), headers: res.headers}); | |
} catch (error) { | |
reject(error); | |
} | |
}); | |
res.on('error', error => { | |
reject(error); | |
}); | |
}); | |
request.write(requestData); | |
request.end(); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment