Skip to content

Instantly share code, notes, and snippets.

@balamurugana
Last active December 27, 2017 13:16
Show Gist options
  • Save balamurugana/d95c824963332e049fd2808717aba1b7 to your computer and use it in GitHub Desktop.
Save balamurugana/d95c824963332e049fd2808717aba1b7 to your computer and use it in GitHub Desktop.

Web server listens for github PR events.

  1. Follow https://developer.github.com/webhooks/
  2. While creating webhook for question Which events would you like to trigger this webhook? select Let me select individual events. then check Pull request
  3. Below is a sample python web hook server for github events
#!/usr/bin/env python

"""
Github webhook server for mint automation.
"""

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import json
from pprint import pprint

def _handle_pr_event(event_dict):
    action = event_dict.get('action')
    if not action:
        return
    pprint(action)
    if action not in ['opened', 'closed', 'reopened', 'synchronize']:
        return
    if action == 'closed':
        # [FIXME] cancel running mint verification job if any
        return
    if action == 'synchronize':
        # [FIXME] cancel running mint verification job if any
        pass

    pull_request_url = event_dict.get(
        'pull_request', {}).get('_links', {}).get('html', {}).get('href')

    # [FIXME] start mint verification job
    pprint(pull_request_url)

class GHWebhookHandler(BaseHTTPRequestHandler):
    def _send_error_headers(self):
        self.send_response(400)
        self.end_headers()

    def log_message(self, format, *args):
        pass

    def do_GET(self):
        self._send_error_headers()

    def do_HEAD(self):
        self._send_error_headers()

    def do_PUT(self):
        self._send_error_headers()

    def do_POST(self):
        content_length = int(self.headers['Content-Length'])
        if content_length <= 0:
            self.send_response(411)
            self.end_headers()
            return

        post_data = self.rfile.read(content_length)
        event = json.loads(post_data)
        self.send_response(202)
        self.end_headers()
        _handle_pr_event(event)


def runHTTPServer(port):
    httpd = HTTPServer(('', port), GHWebhookHandler)

    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        pass

    httpd.server_close()

if __name__ == "__main__":
    from sys import argv

    port = 12345
    if len(argv) == 2:
        port = int(argv[1])

    runHTTPServer(port)
  1. Use ngrok to expose this webhook server by ./ngrok http 12345. Add Forwarding HTTP URL shown in ngrok console to Payload URL when creating webhook in github. Make sure Active to checked.
  2. Now the http server starts getting PR events.

Adding a comment in a PR using external program

  1. Create a token with role public_repo at https://github.com/settings/tokens and save generated token in a safe place.
  2. Below python code can be used to add a comment in the pull request.
from github import Github

gh = Github('<GENERATED-GITHUB-TOKEN>')
gh.get_repo("USER/REPO").get_pull(<PULL_REQUEST_ID>).create_issue_comment("<YOUR COMMENT TO ADD>")

Editing previously added comment in a PR using external program

  1. Below python code can be used to add a comment in the pull request.
from github import Github

gh = Github('<GENERATED-GITHUB-TOKEN>')
comments = gh.get_repo("USER/REPO").get_pull(<PULL_REQUEST_ID>).get_issue_comments()
# Identify which comment we added previously.  Assumed here comments[1]
comments[1].edit("<UPDATED COMMENT>")

Giving +1/-1 to a pull request

  1. Refer https://developer.github.com/v3/pulls/reviews/#submit-a-pull-request-review
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment