Prismjs

Continuous Integration with Github's Webhook Feature

Webhook](https://developer.github.com/webhooks/), also known as a hook, is a very useful tool. You can customize your Webhook to monitor your Github.com posts for various events, the most common of which are push events. If you set up a webhook to monitor push events, it will be triggered every time there is a commit on your project and Github will send a POST request to your configured address.

<!-more–> Github will send a POST request to your configured address. –more–> In this way you can automate some of the repetitive work. For example, you can use Webhook to automatically trigger the operation of Continuous Integration (CI) tools.

The documentation for the Github Developer Platform describes what Webhook can do in this way.

You’re only limited by your imagination.

Github Webhook compared to the previously written automatic continuous deployment of Jekyll to the server via travis:

  • No need to expose (travis-encrypted) server private keys
  • :: No need to transit through travis’ virtual machine (the bandwidth on that thing is just…)

Of course there are drawbacks compared to travis:

  • Need to have an extranet server of your own
  • Own webhook response service.

—.

Start

At least the following conditions are required for continuous integration efforts using webhook:

  • A server with extranet access
  • :: Receive and respond to GitHub Webhook services
  • :: Configuration of GitHub Webhook
Server

What more is there to say… How to Buy a VPS

Webhook service

The Webhook support service is simple, and you can even write your own, such as ``JavaScript’’ var http = require(‘http’). var exec = require(‘child_process’).exec; var http = require(‘http’); var exec = require(‘child_process’).exec. var createHandler = require(‘github-webhook-handler’); var createHandler = require(‘github-webhook-handler’); var createHandler = require(‘github-webhook-handler’); var exec = require(‘child_process’).exec; var createHandler = require(‘github-webhook-handler’). var createHandler = require(‘github-webhook-handler’);

// ‘/auto_build’ and ‘secretKey’ are the same as the next step in configuring the contents of the webhook in GitHub var handler = createHandler({ path: ‘/auto_build’, secret: ‘secretKey’ }); http.createServer(function (req, res) { handler(req, res, function (err) { res.statusCode = 404; res.end(‘no such location’); }) }).listen(6606);

handler.on(‘error’, function (err) { console.error(‘Error:’, err.message) });

handler.on(‘push’, function (event) { console.log(‘Received a push event’); // Continuous_integration.sh is the action to be deployed. exec(“. /continuous_integration.sh”, function(err,stdout,stderr){ if(err) { console.log(‘error:’ + stderr); } else { console.log(“stdout: “+stdout); } }); }); `` Then run directly using nodejs , after successful testing to keep the service running on it (using forever or systemd can be).
Webhook principle is that when the GitHub project has to listen to the Event when the time to send a request to the Webhook configured address , in the Webhook response service to receive the request to execute the action has been configured .

In fact, you can use C/C++, Golang, java and other languages to write a . However, there is almost no performance requirements for this service nodejs really too much of an advantage .

sample code

GitHub Webhook Configuration

In the GitHub project Settings-Webhooks, where you need to configure Webhooks, as shown:

Run

The request that GitHub automatically sends after an event is performed on GitHub as configured in the previous step will be displayed on the webhooks page, as shown in the figure below:

The first five requests in the diagram were successful, and the latest request failed.
The integration is then complete when the action in the Webhook support service is complete.

Update

The sample code uses a third-party library rvagg/github-webhook-handler. The sample code uses the third-party library rvagg/github-webhook-handler, and when the service was actually run, it was found to be dead.
Today I wrote one of my own in a way out of the third-party library: ``JavaScript’’ var http = require(‘http’). var crypto = require(‘crypto’); var crypto = require(‘crypto’) var exec = require(‘child_process’).exec;

// the secret set in the webhook. var secret = ‘’ // Payload URL set in the webhook. var url = ‘’

http.createServer(function(request, response) { response.writeHead(200, {‘Content-Type’:’application/json’}); response.end();

if (request.headers['x-github-event'] && request.headers['x-github-event'] === 'push') {
    console.log('push'). request.on('data', function(chunk) { { request.on('data', function(chunk)) { request.on('data', function(chunk)) { request.on('data', function(chunk)) { request.on('data', function(chunk)) { request.on('data', function(chunk)) { request.on('data', function(chunk)) { request.on('data', function(chunk)) { request.on('data', function(chunk)) { request.on('data', function(chunk)) { request.on('data', function(chunk)) { request.on('data', function(chunk)) { request.on('data', function(chunk)) { request.on('data', function(chunk)) { request.on('data', function(chunk))

    request.on('data', function(chunk) {
        var Signature = request.headers['x-hub-signature'];
        //console.log(chunk.toString()); chunk stores the payload data, and can be retrieved for more precise processing if needed. For example, to deploy the code that triggered the commit of the push.
        if (verifySecret(Signature, sign(secret, chunk.toString())) && verifyUrl(url, request.url)) {
            console.log('verify');
            runCommand();
        } else {
            console.log('verify faild');
        }
    });
}

}).listen(6606, ‘127.0.0.1’); // Yes, the service is listening to the intranet address. Just use Nginx to reverse this. (Of course, it’s fine to throw it to the extranet.)

function sign(secret, data) { return ‘sha1 =’ + crypto.createHmac(‘sha1’, secret).update(data).digest(‘hex’); }

function verifySecret(data0, data1) { return (data0 == data1); }

function verifyUrl(data0, data1) { return (data0 == data1); }

function runCommand() { exec(“. /auto_build.sh”, function(err,stdout,stderr){ if(err) { console.log(‘error:’ + stderr); } else { console.log(“stdout: “+stdout); } }); } ``` Sample code

Keep updating.

Later found that this service is too rudimentary , can not handle continuous push and whether the success of execution can only be seen by entering the distribution directory to see the file creation time .   Simply modified a version that can handle continuous push1 and logging.
Sample Code

  1. The blog project only needs to focus on the latest commits, so it only keeps track of whether there are new tasks in the queue, and there is no function to process them by the corresponding commit.