This package helps you to create a CI/CD workflow using GitHub webhook events. You can provide scripts that will be executed when certain events happen, or add event listeners to respond to the events right in the your app. Unlike GitHub actions where you're limited to 2000 CI/CD minutes per month
, webhooks are not limited. This package can also be extended if the events available are not adequate for your workflow.
npm install @xavisoft/pipeliner
Check out this link for steps on how to set up the webhooks for your GitHub organization/repository.
- You can set up webhooks for each repository, or for the whole organization, and this tool will handle all repositories in that organization.
- You can integrate more that one webhook on one
Pipeliner
instance. - The
Secret
field is required for this to work. It should match thehmacSecret
parameter used to create thePipeliner
instance.
const Pipeliner = require('@xavisoft/pipeliner');
const child_process = require('child_process');
const options = {
port: 8080,
endpoint: 'webhook',
hmacSecret: 'your_hmac_secret'
}
const pipeliner = new Pipeliner(options);
pipeliner.on('push', data) {
const { repository } = data;
const cmd = `
cd ../${repository};
git pull;
npm install;
pm2 restart ${repository}
`;
child_process.exec(cmd, (err) => {
if (err) {
console.error(err);
}
});
}
You can write Bash or JS scripts that runs on specific events. A script saved at
path/to/scripts/git-organization/repository/eventName.js
OR
path/to/scripts/git-organization/repository/eventName.sh
will run when a certain event happens.
For example we can achieve the above by creating the bash script below:
# Saved at /path/to/project/pipeline_scripts/organization/repository/push.sh
git pull
npm install
pm2 restart {repository} # restaring the app
After every script runs, the results will be passed to pipeliner.notify()
. Override the function as below to send yourself notifications:
class MyPipeliner extends Pipeliner {
async notify(hasErred, err, output, stdout, stderr) {
// your logic to notify yourself
}
}
const pipeliner = new MyPipeliner(options);
pipeliner.init();
The list of events emitted by the package may not be enough for your workflow. That's why we included the event webhook
. The event webhook is included to enable you to extend the list of events emitted by this package. It will emit all the headers and body of the request, so you can process the event as you see fit. This event is always emitted.
pipeliner.on('webhook', payload => {
const { headers, body } = payload;
// do your thing
});
const options = {
port: 8080,
endpoint: '/webhook',
hmacSecret: 'your_hmac_secret',
scriptsPath: __dirname + '/pipeliner_scripts'
}
const pipeliner = new Pipeliner(options);
If you pass port
to the Pipeliner constructor, a new express is going to be created when you call pipeliner.init()
. If you have an already existing express app, you can mount pipeliner on the same app:
const expressApp = app;
const pipeliner = new Pipeliner({
expressApp,
endpoint: '/webhook',
hmacSecret: 'your_hmac_secret',
scriptsPath: __dirname + '/pipeliner_scripts'
});
NB: Make sure your express app supports the Content-Type
you will have selected on your Github Webhook setup.
The Pipeliner class creates objects that listens to GitHub webhooks and emit events
Kind: global class
Emits: push
, pull_request
, merge
, release
, new_branch
, new_tag
, unauthorized_webhook
Param | Type | Description |
---|---|---|
options | object |
|
options.expressApp | object |
an express application (created by require('express)()) |
options.port | object |
The port to make the express application listen to. Only used when options.expressApp was not passed |
options.endpointPath | object |
The path the webhook events will be posted by GitHub |
options.scriptsPath | object |
The path where scripts that response to events are stored |
options.hmacSecret | object |
The secret used to verify if GitHub really sent the webhook events, not some ill-intended party |
To be overidden. It will be called when a script is finished with the output from the script
Kind: instance method of Pipeliner
Param | Type | Description |
---|---|---|
hasErred | boolean |
indicates whether the command ran successfully |
err | Error |
The error that occured. null if hasErred is false |
output | string |
both stdout and stderr logs |
stdout | string |
stdout log |
stderr | string |
stderr log |
This method initialize the pipeliner to start listening for webhook events
Kind: instance method of Pipeliner
This method stops the Pipeliner instance from listening to webhook events
Kind: instance method of Pipeliner
Emmitted when a new tag is created on a repository
Kind: event emitted by Pipeliner
Properties
Name | Type | Description |
---|---|---|
organization | string |
GitHub organization name |
repository | string |
GitHub repository name |
originalPayload | object |
Original data send by GitHub |
data | object |
|
data.tag | string |
Name of the tag created |
data.branch | string |
The branch on which the tag was created |
Emmitted when a new branch is created on a repository
Kind: event emitted by Pipeliner
Properties
Name | Type | Description |
---|---|---|
organization | string |
GitHub organization name |
repository | string |
GitHub repository name |
originalPayload | object |
Original data send by GitHub |
data | object |
|
data.branch | string |
Name of branch that was created |
Emmitted when a new release is created on a repository
Kind: event emitted by Pipeliner
Properties
Name | Type | Description |
---|---|---|
organization | string |
GitHub organization name |
repository | string |
GitHub repository name |
originalPayload | object |
Original data send by GitHub |
data | object |
|
data.branch | string |
Name of branch the realease was created from |
data.tag | string |
Name of tag the release was created from |
Emmitted when changes are pushed to a repository
Kind: event emitted by Pipeliner
Properties
Name | Type | Description |
---|---|---|
organization | string |
GitHub organization name |
repository | string |
GitHub repository name |
originalPayload | object |
Original data send by GitHub |
data | object |
|
data.branch | string |
Name of the branch the changes were pushed to |
Emmitted when a pull request is made
Kind: event emitted by Pipeliner
Properties
Name | Type | Description |
---|---|---|
organization | string |
GitHub organization name |
repository | string |
GitHub repository name |
originalPayload | object |
Original data send by GitHub |
data | object |
|
data.branch | string |
Name of branch requesting to be merged |
data.base_branch | string |
Name of branch the changes are supposed to be merged to |
Emmitted when two branches are merged
Kind: event emitted by Pipeliner
Properties
Name | Type | Description |
---|---|---|
organization | string |
GitHub organization name |
repository | string |
GitHub repository name |
originalPayload | object |
Original data send by GitHub |
data | object |
|
data.branch | string |
Name of branch that was requested to be merged |
data.base_branch | string |
Base branch |
This events has all the headers and body from GitHub. You can extend the capabilities using this package by listening to this event
Kind: event emitted by Pipeliner
Properties
Name | Type | Description |
---|---|---|
headers | object |
Headers sent by GitHub |
body | object |
The body of the request send by GitHub |
This event is emitted an unauthroized client tries to send a webhook event
Kind: event emitted by Pipeliner