Webhooks

Allura supports one type of webhook for the moment - repo-push, triggered when a repository receives new commits. It is supported for Git, Mercurial and SVN repositories.

Configure webhooks

  • Go to tools admin page
  • Find 'Webhooks' link under particular repository tool
  • Click 'Create' under appropriate hook type
  • Provide url and (optional) secret

You can also manage webhooks through the REST API.

Payload

The request payload is JSON. Examples:

Git

{
    "after": "a72ab8566ed1a81e485a8451868ee9364069ea6b", 
    "before": "27bc571ceb56beeda796e0069bfba84581f55770",
    "size": 1,
    "commits": [
      {
        "id": "a72ab8566ed1a81e485a8451868ee9364069ea6b", 
        "message": "Update README", 
        "added": [], 
        "copied": [], 
        "removed": [], 
        "modified": [
          "README.md"
        ], 
        "author": {
          "email": "jetmind@example.com", 
          "name": "Igor Bondarenko", 
          "username": "jetmind"
        }, 
        "committer": {
          "email": "jetmind@example.com", 
          "name": "Igor Bondarenko", 
          "username": "jetmind"
        }, 
        "timestamp": "2015-02-23T14:30:42Z", 
        "url": "http://sourceforge.net/p/test/git/ci/a72ab8566ed1a81e485a8451868ee9364069ea6b/"
      }
    ], 
    "ref": "refs/heads/master", 
    "repository": {
      "full_name": "/p/test/git/", 
      "name": "Git", 
      "url": "http://sourceforge.net/p/test/git/"
    }
}


Mercurial

{
    "after": "3f36d4136f4c7151066135335a70d812f7d9251b", 
    "before": "715226c07bcfd410bb655e9290adeb770eb36b1f", 
    "size": 1,
    "commits": [
      {
        "id": "3f36d4136f4c7151066135335a70d812f7d9251b", 
        "message": "Update README", 
        "added": [], 
        "copied": [], 
        "removed": [], 
        "modified": [
          "README.markdown"
        ], 
        "author": {
          "email": "jetmind", 
          "name": "jetmind", 
          "username": ""
        }, 
        "committer": {
          "email": "jetmind", 
          "name": "jetmind", 
          "username": ""
        }, 
        "timestamp": "2015-02-23T14:32:01Z", 
        "url": "http://sourceforge.net/p/test/mercurial/ci/3f36d4136f4c7151066135335a70d812f7d9251b/"
      }
    ], 
    "ref": "refs/tags/tip", 
    "repository": {
      "full_name": "/p/test/mercurial/", 
      "name": "Mercurial", 
      "url": "http://sourceforge.net/p/test/mercurial/"
    }
  }


SVN

{
    "after": "r10", 
    "before": "r9", 
    "size": 1,
    "commits": [
      {
        "id": "r10", 
        "message": "Update README", 
        "added": [], 
        "copied": [],
        "removed": [], 
        "modified": [
          "/trunk/README"
        ], 
        "author": {
          "email": "", 
          "name": "jetmind", 
          "username": ""
        }, 
        "committer": {
          "email": "", 
          "name": "jetmind", 
          "username": ""
        },  
        "timestamp": "2015-02-23T14:33:40Z", 
        "url": "http://sourceforge.net/p/test/svn/10/"
      }
    ], 
    "repository": {
      "full_name": "/p/test/svn/", 
      "name": "SVN", 
      "url": "http://sourceforge.net/p/test/svn/"
    }
  }

Receiving webhooks

If you want to make sure that requests are coming from Allura and not from someone else, you need to:

  • Set up secret when configuring the webhook (you can leave it blank and Allura will automatically generate one for you).
  • On every request validate the signature from the X-Allura-Signature header.

Note: DO NOT ever expose your secret!

The signature is obtained by hashing the webhook payload with secret using HMAC algorithm. You can do something like this to verify it:

def verify(payload, signature, secret):
    actual_signature = hmac.new(secret.encode('utf-8'), payload.encode('utf-8'), hashlib.sha1)
    actual_signature = 'sha1=' + actual_signature.hexdigest()
    return hmac.compare_digest(actual_signature, signature)

verify(request.body, request.headers.get('X-Allura-Signature'), secret)

Related

Tickets: #7829
Wiki: Home