RB Gateway is a microservice designed to wrap self-hosted repositories, providing a consistent API that Review Board can use to talk to services over a network. One thing it lacks today is the ability to notify services (like Review Board) when things happen (such as a new commit or set of commits in a repository). We use such webhooks in services like GitHub and Bitbucket in order to automatically close review requests when commits referencing the review request ID are pushed.

This project involves adding webhook functionality to RB Gateway, for use with Review Board. There are three major tasks involved:

  1. Adding code to rb-gateway for configuring and invoking webhooks
  2. Add a rb-gateway command to invoke webhooks and integrate into repository hook scripts
  3. Adding webhook receivers in Review Board to close review requests when commits are posted

This document will break down these steps.

https://requestb.in/ can be used for testing while developing this feature. It lets you create URLs to POST to in order to inspect the results.

Current progress can be found here https://reviews.reviewboard.org/r/9402/ and described within the "What's been completed" and "What's still missing" sections of this document.

Task 1: Webhooks in rb-gateway

The rb-gateway configuration file should accept new Webhook configuration, which would specify an ID, a destination URL, a secret code for payload signature computation (used to ensure clients are only handling official HTTP requests), whether the hook is currently enabled, a list of events supported by this configuration, and a list of repository names. This would look like:

{
    ...
    "webhooks": [
        {
            "id": "my-webhook1",
            "url": "<http://localhost:8080/blah/blah/>",
            "secret": "ABC123",
            "enabled": true,
            "events": ["post-commit"],
            "repositories": ["repo1"],
        },
        ...
    ]
}

In the future, we'll want to add webhook event types that are not repository-specific, with more than just one type of event, but for now we only want a single event: