Project

General

Profile

Actions

Feature #4024

closed

[ce] Integrations/Webhooks

Added by Daniel D over 8 years ago. Updated over 8 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
-
Target version:
Start date:
15.06.2016
Due date:
% Done:

0%

Estimated time:
Sorting:
Commit Number:

Description

Currently there is a WIP to implement integrations in the rhodecode ui, in a way that is simple for an end user to configure.

There are a few tasks which must be done to make this work:

  1. Create a unified first class citizen event object system, these should be generated in relevant models eg. PullrequestModel.create to create and fire PullRequestCreateEvent(pullrequest) - they should also gather relevant environment data such as request context - each event has a string describing it, of the form 'repo.push' and a special wildcard '*' string will match any event

  2. These objects should expose a json dict which describe the entirety of the event - such as repo (plus repo data), user, relevant commits etc. - It would be a good idea to use the data structs returned by the rhodecode api, eg. {'event': 'pullrequest.create', 'repo': repo.get_repo_api_data()}

  3. This json dict is the basis of all integrations/webhooks - it must be as complete as possible to allow any integration/webhook to utilize the data without needing further apicalls/lookups (later we can allow post_processors "extensions" to be registered on the events - to let them add extra data).

  4. Now that we have a basis to describe an event - we can work on hooks - A table of event hooks of the form:

CREATE TABLE event_hooks (
      event_type VARCHAR,
      integration_id INT
)

and an integrations table of the form:

CREATE TABLE integrations (
      integration_id INT primary_key,

      # this is a string which is used as a
      # discriminator to load the correct integration
      # eg. 'slack' => SlackIntegration
      integration_type VARCHAR,

      # this is a json string which exposes settings for the integration
      # these will be exposed in the user interface as a form
      integration_settings_json VARCHAR

      # when this is null, will apply the integration on any repo
      # instead of having to create a new integration per repo
      # you can make all repo.push use same integration
      # it will also be null for global type events such as `user.create`
      repo_id INT,
)

which maps eg. events => integrations, where integration will be database objects that inherit from a base Integration class that define how to interact with the incoming json data - and do the analogous integration - for example with these values:

+------------+----------------+
| event_type | integration_id |
+------------+----------------+
| repo.push  |              1 |
| repo.pull  |              1 |
| repo.pull  |              2 |
| *          |              3 |
+------------+----------------+
+----------------+---------+------------------+---------------------------------+
| integration_id | repo_id | integration_type |    integration_settings_json    |
+----------------+---------+------------------+---------------------------------+
|              1 | 1       | slack            | '{"channel": "#develop"}'       |
|              2 | null    | slack            | '{"channel": "#general"}'       |
|              3 | null    | webhook          | '{"url": "http://logs-server"}' |
+----------------+---------+------------------+---------------------------------+

A push to repo(id=1) will fire two integrations:

  • integration(id=1) - sends a message to slack channel #develop
  • integration(id=3) - POSTS the repo push json to http://logs-server

A pull to repo(id=1) will fire three integrations

  • integration(id=1) - sends a message to slack channel #develop
  • integration(id=2) - sends a message to slack channel #general
  • integration(id=3) - POSTS the repo push json to http://logs-server

A pull to repo(id=2) will fire two integrations

  • integration(id=2) - sends a message to slack channel #general
  • integration(id=3) - POSTS the repo push json to http://logs-server

In fact any event will be posted to the http://log-server - and any pull event will be sent to slack #general.

Actions

Also available in: Atom PDF