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

0

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

About Author

Lucas Jellema, active in IT (and with Oracle) since 1994. Oracle ACE Director and Oracle Developer Champion. Solution architect and developer on diverse areas including SQL, JavaScript, Kubernetes & Docker, Machine Learning, Java, SOA and microservices, events in various shapes and forms and many other things. Author of the Oracle Press book Oracle SOA Suite 12c Handbook. Frequent presenter on user groups and community events and conferences such as JavaOne, Oracle Code, CodeOne, NLJUG JFall and Oracle OpenWorld.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.