Handle a GitHub Push Event from a Web Hook Trigger in a Node application image 20

Handle a GitHub Push Event from a Web Hook Trigger in a Node application

My requirement in this case: a push of one or more commits to a GitHub repository need to trigger a Node application that inspects the commit and when specific conditions are met – it will download the contents of the commit.

image

I have implemented this functionality using a Node application – primarily because it offers me an easy way to create a REST end point that I can configure as a WebHook in GitHub.

Implementing the Node application

The requirements for a REST endpoint that can be configured as a webhook endpoint are quite simple: handle a POST request  no response required. I can do that!

In my implementation, I inspect the push event, extract some details about the commits it contains and write the summary to the console. The code is quite straightforward and self explanatory; it can easily be extended to support additional functionality:

app.post('/github/push', function (req, res) {
  var githubEvent = req.body
  // - githubEvent.head_commit is the last (and frequently the only) commit
  // - githubEvent.pusher is the user of the pusher pusher.name and pusher.email
  // - timestamp of final commit: githubEvent.head_commit.timestamp
  // - branch:  githubEvent.ref (refs/heads/master)

  var commits = {}
  if (githubEvent.commits)
    commits = githubEvent.commits.reduce(
      function (agg, commit) {
        agg.messages = agg.messages + commit.message + ";"
        agg.filesTouched = agg.filesTouched.concat(commit.added).concat(commit.modified).concat(commit.removed)
          .filter(file => file.indexOf("src/js/jet-composites/input-country") > -1)
        return agg
      }
      , { "messages": "", "filesTouched": [] })

  var push = {
    "finalCommitIdentifier": githubEvent.after,
    "pusher": githubEvent.pusher,
    "timestamp": githubEvent.head_commit.timestamp,
    "branch": githubEvent.ref,
    "finalComment": githubEvent.head_commit.message,
    "commits": commits
  }
  console.log("WebHook Push Event: " + JSON.stringify(push))
  if (push.commits.filesTouched.length > 0) {
    console.log("This commit involves changes to the input-country component, so let's update the composite component for it ")
    var compositeName = "input-country"
    compositeloader.updateComposite(compositeName)
  }

  var response = push
  res.json(response)
})

Configuring the WebHook in GitHub

A web hook can be configured in GitHub for any of your repositories. You indicate the endpoint URL, the type of event that should trigger the web hook and optionally a secret. See my configuration:

image

Trying out the WebHook and receiving Node application

In this particular case, the Node application is running locally on my laptop. I have used ngrok to expose the local application on a public internet address:

image

(note: this is the address you saw in the web hook configuration)

I have committed and pushed a small change in a file in the repository on which the webhook is configured:

image

The ngrok agent has received the WebHook request:

image

The Node application has received the push event and has done its processing:

image

One Response

  1. Catalin Duta July 30, 2020