Begiak's git plugin

From Apertium
Jump to navigation Jump to search

Begiak has a git plugin that is a post-receive hooks module for the sites it receives commit updates from. The plugin can also provide information about the most recent commits for each repository, and information about individual commits for monitored repositories. The sources for the plugin are in modules/git.py.


Hook Commands[edit]

A post-receive hook is software which performs certain actions on receiving updates about commits from sites like GitHub and Bitbucket. In Begiak's case, Begiak prints out information about commits as they come in to the IRC channels it is present on and notifies administrators. For more about how to set up a webhook, see #Webhook Set-up.

Begiak receives updates from GitHub, Google Code, and Bitbucket. The hook module is started automatically when Begiak is started and connects to an IRC network. All users can check the status of the hook server with

   .gitserver status

and administrators can manually start and stop the server with

   .gitserver start
   .gitserver stop

The command `stopserver' is the same as `.gitserver stop'.


Webhook Set-up[edit]

A webhook consists of two parts: the service that sends updates and the handler that handles them.

Creating handlers simply involves creating HTTP servers which accept POST requests containing commit information sent by a service. Each POST request usually contains information about the repository, revision number, author, commit message, added/modified/deleted files, etc. For security, a code is provided to authenticate the handler. Additionally, the information is normally sent as JSON data. Each service has slightly different JSON fields in the JSON payload, but it's relatively easy to extract the data.

Begiak implements its handler by deriving it from Python's SimpleHTTPRequestHandler and defining a POST request handler (see the link for documentation). Begiak uses Python's json library to decode the JSON payload it receives from each service. Begiak is hosted on this server.

Begiak's git plugin listens at http://apertium.vm.bytemark.co.uk:1234/, so the payload URL/post-commit URL should point there.

However, if you are running locally, Begiak's git plugin will be listening at localhost:1234. However, since localhost is not accessible over the internet, we need to expose our localhost so that sites, such as GitHub, can see it. One such tool that allows you to do so is ngrok. Download ngrok here. Once you start a ngrok server using ./ngrok or such, you can place the resulting URL which is found in Forwarding (.ngrok.io format) into the payload URL.

Setting up webhooks on the service's side is very easy with services like GitHub, Google Code, and Bitbucket. How to set up webhooks on these services is explained below:

GitHub[edit]

To set up a webhook for a repository on GitHub, navigate to the `Settings -> Webhooks & Service' page. Here, GitHub gives you the option of adding a standard webhook or adding a service which is a configurable built-in webhook responding to some actions. However, services do not always do what you want and they are, after all, special hooks, so we'll see how to create a webhook.

Once you click on `Add webhook', GitHub may ask you to confirm your password. It then proceeds to the webhook creation page. Firstly, a payload URL must be specified. This is the URL at which the handler is located. Next comes the `Content type': the format in which the content will be sent, either as JSON or as an HTML form with the JSON payload in it. After that, the secret code to authenticate the handler. You then have to select the events which will trigger the hook; events include pull requests being created, commits being made, etc. and are documented in further detail here. Finally, you mark the webhook as being `active' and submit.

Note that for the `Content type' field, there are two options. If the `application/json' option is selected, the JSON data is sent directly as the body of the POST request to the handler; if the `application/x-www-form-urlencoded' option is selected, the JSON data is sent as an HTML form with a field titled `payload' in which the data is actually stored. Begiak's current handlers all use the HTML form option.

Google Code[edit]

To set up a webhook for a repository on Google Code, navigate to the `Administer -> Source' tab (you might have to sign in to see it). At the very bottom of the page, there are two fields under the heading of `Post-Commit webhooks': a Post-Commit URL and a Post-Commit Authentication Key, which are the URL at which the handler is located and the authentication code for the handler, respectively. Fill these fields in and save your changes via the button provided; the webhook has been created.

Google Code sends data as JSON. For further documentation on Google Code's webhooks service, see the support page.

Bitbucket[edit]

The process of setting up webhooks on Bitbucket is quite well documented on this page.

Adding to Begiak[edit]

To add a new service to Begiak or a Begiak fork, or to implement other types of webhooks (i.e. triggered by different events or performing different actions on getting notified of an event), you have to add handling code to the source file modules/git.py, in the `MyHandler' class' `do_POST' method which handles all the POST requests. Code already exists for data decoding; just adding a clause to identify the service/event and then do something with it will suffice.

After the payload URL, you need to add the repo to the config file or in default.py. To add it into the config file you need to do two things: create a dictionary called git_repositories and git_events or add entries if they already exist.

  1. Create dictionaries, git_repositories and git_events if they do not already exist.
  2. In the dictionary git_repositories add an entry in the format "name" : "github_url" . Example: git_repositories = {"apertium" : "https://github.com/apertium"}
  3. In the dictionary git_events add an entry in the format "repository_name" : "[events]" . Example: git_events = {'apertium/*': ['issues', 'push']}
git_repositories = {"apertium" : "https://github.com/apertium"}
git_events = {'apertium/*': ['issues', 'push']}

For the events, 'issues' and 'issue_comment', you can add extra actions to filter what begiak says to the channel. "Actions" refers to the specific changes (i.e editing, creation) to an issue or issue_comment, so that begiak only speaks on specific events, such as the opening of an issue.

issues_x where x is the action that you would like begiak to speak on. The same goes for 'issue_comment'.

You can still get all of the actions if you just type 'issues' or 'issue_comment'.

Examples:

  1. git_events = {'apertium/*': ['issues_opened', 'issues_closed', 'issue_comment_created']}. This would get all of the issues opened, issues closed, and issue comments created actions.
  2. git_events = {'apertium/*': ['issues', 'issue_comment']} . This would get all of the issue and issue comment actions.
  3. git_events = {'apertium/*': ['issues', 'issue_comment_created']} . This would get all of the issue actions but only the issue_comment created actions.

Recent Commits[edit]

Begiak can get information for the most recent commits for the repositories it monitors. The command

   begiak: recent OR
   begiak, recent

will print the commit reports.

This command currently does not work.

Commit Information[edit]

Begiak can get commit information for a specified repository and revision. The command

   begiak: info <repo> <rev> OR
   begiak, info <repo> <rev>

will print the commit report. Note that this module does not try to handle SVN repositories (they are handled by modules/svnpoller.py) and other repositories it does not monitor.

This command currently does not work.