GitLab

A connector for GitLab.

Note that this connector emits only upports sending messages back to the event (Issue, Merge Request), if you need to create more elaborate workflow, please use the GitLab API in your skill.

Requirements

Configuration

connectors:
  gitlab:
    # Optional but recommended
    webhook-token: "my-very-secret-webhook-secret"
    # Required if you want opsdroid to reply to issues/MRs
    token: "<personal access token>"

Setup Webhook

You need to expose Opsdroid to the internet, when you have your url, you can go to your repository, click Settings and then select Webhook, you can then add the url with the connector/<connector name> enpoint. For example, assume that you are using example.com as your base url and using this connector with the default name, you can use the following url https://example.com/connector/gitlab to receive events from your repository.

You can then choose a secret token - this will be your webhook-token in the Opsdroid configuration. It’s highly recommended that you choose a strong token to validate the requests coming into the https://example.com/connector/gitlab endpoint.

Finally, you can choose which events you want Gitlab to send you and choose if you want to turn off SSL verification. It’s recommended that you use SSL at all times.

Examples

The GitLab connector allows you to send back a message when an event is triggered. This is a great way to automate some workflows. For example, let’s assume that you want to thank every user that opens a new issue in your repository.

Here’s a small example of how the opsdroid configuration looks like:

connectors:
  gitlab:
  webhook-token: "my-secret-token"
  token: "my-personal-token"
skills:
  thankyou:
    path: "<skill pwd>"

Then you can create a new folder for your skill and write the following:

from opsdroid.skill import Skill
from opsdorid.matchers import match_event
from opsdroid.connector.gitlab.events import GitlabIssueCreated
from opsdroid.events import Message

class ThankUser(Skill):
    def __init__(self, opsdroid, config, *args, **kwargs):
        super().__init__(opsdroid, config, *args, **kwargs)
        self.opsdroid = opsdroid
    
    @match_event(GitlabIssueCreated)
    async def say_thank_you(self, event):
        """Send message to issue, thanking user."""
        await event.respond(
            Message(
                text="Thank you for opening this issue, a team member will be with you shortly!",
                target=event.target
            )
        )

Now let’s assume that you want to notify a slack channel every time a label was changed in an MR. This can be useful if you want to alert your team that an MR is ready for code review.

A more robust opsdroid configuration:

connectors:
  gitlab:
    webhook-token: "/secret-t0k3n|"
    token: "<your secret token>"
  slack:
    bot-token: "<your token>"
    socket-mode: false
    bot-name: "Review-Bot"
    default-room: "#code-reviews"
skills:
  alert-team:
    path: "<skill pwd>"

The skill will look somewhat similar to the previous example with a few changes:

from opsdroid.skill import Skill
from opsdorid.matchers import match_event
from opsdroid.connector.gitlab.events import GitlabIssueCreated
from opsdroid.events import Message

class AlertTeam(Skill):
    def __init__(self, opsdroid, config, *args, **kwargs):
        super().__init__(opsdroid, config, *args, **kwargs)
        self.opsdroid = opsdroid
    
    @match_event(MRLabeled)
    async def mr_labeled(self, event):
        """Send message slack if MR was labeled as code-review."""
        slack = self.opsdroid.get_connector("slack")
        if "code-review" in event.labels:
            await slack.send(
                Message(
                    text=f"Hey folks, the MR ({event.url}) was just marked as ready for review!",
                )
            )

This skill will trigger every time an MR gets labeled with something but only sends the message to the Slack channel #code-reviews when the MR is labeled with the code-review label.

Events Available

Currently, the GitLab connector handles Merge Requests and Issues events, any other event such as pipeline events, for example, will be retured as GenericGitlabEvent.

class opsdroid.connector.gitlab.events.GenericGitlabEvent(project, user, title, description, labels, url, *args, **kwargs)

Event class that triggers when an unhandled event is sent.

class opsdroid.connector.gitlab.events.GitlabIssueCreated(project, user, title, description, labels, url, *args, **kwargs)

Event class that triggers when a new issue is created.

class opsdroid.connector.gitlab.events.GitlabIssueClosed(project, user, title, description, labels, url, *args, **kwargs)

Event class that triggers when an issue is closed.

class opsdroid.connector.gitlab.events.GitlabIssueEdited(project, user, title, description, labels, url, *args, **kwargs)

Event class that triggers when an issue is edited.

class opsdroid.connector.gitlab.events.GitlabIssueLabeled(project, user, title, description, labels, url, *args, **kwargs)

Event class that triggers when an issue is labeled.

class opsdroid.connector.gitlab.events.GenericIssueEvent(project, user, title, description, labels, url, *args, **kwargs)

Event class that triggers when any other issue action happen.

class opsdroid.connector.gitlab.events.MRCreated(project, user, title, description, labels, url, *args, **kwargs)

Event class that triggers when a MR is created.

class opsdroid.connector.gitlab.events.MRMerged(project, user, title, description, labels, url, *args, **kwargs)

Event class that triggers when a MR is merged.

class opsdroid.connector.gitlab.events.MRClosed(project, user, title, description, labels, url, *args, **kwargs)

Event class that triggers when a MR is closed.

class opsdroid.connector.gitlab.events.MRLabeled(project, user, title, description, labels, url, *args, **kwargs)

Event class that triggers when a MR label is updated.

class opsdroid.connector.gitlab.events.MRApproved(project, user, title, description, labels, url, *args, **kwargs)

Event class that triggers when a MR is approved.

class opsdroid.connector.gitlab.events.GenericMREvent(project, user, title, description, labels, url, *args, **kwargs)

Event class that triggers when a Generic MR events.Event happens.

Reference

This dataclass is used internally within the Gitlab connector, but is worth noting a few things here.

class opsdroid.connector.gitlab.GitlabPayload(attributes, changes, labels, project_name, url, target, description, title, username, action, raw_payload)

Generate Gitlab Payload object.

This dataclass will be used to handle the gitlab payload and to build the object from the payload returned by Gitlab webhooks. The main reason for that is because Gitlab might return different structures depending on the event that was sent.

Note

  • url is refered to the event url (for example the MR url)

  • target is the API endpoint to send a reply by using ConnectorGitlab.send_message.

classmethod from_dict(payload)

Create the GitlabPayload object from a dictionary.

This is the Connector reference

class opsdroid.connector.gitlab.ConnectorGitlab(config, opsdroid=None)

A connector for Gitlab.

async connect()

Connect method for Gitlab.

This connector is using webhook events only. This method is used only to create the routes for the webhooks.

async gitlab_webhook_handler(request)

Handle event from Gitlab webhooks.

Return type

Response

async handle_issue_event(payload)

Handle issues events.

Return type

Event

async handle_merge_request_event(payload)

Handle Merge Request Events.

When a user opens a MR Gitlab will throw an event, then when something happens within that particular MR (labels, commits, milestones), Gitlab will emit new events. This method handles all of these events based on the payload and builds the appropriate opsdroid events.

Return type

Event

async listen()

Listen method of the connector.

Since we are using webhook events, this method does nothing.

async send_message(message)

Respond with a message.

Gitlab uses notes to push messages to Issues, Snippets, Merge Requests and Epics. The URL is usually <event target>/notes so we can simply get the target from the Message event and use that to reply.

Note that if we don’t have a target then we won’t return any message.

async validate_request(request)

Validate webhook request.

Gitlab allow us to add a secret token to be added to the X-Gitlab-Token HTTP header, this method will simply check the request and compare the value of this header against the token that the user specified in the configuration.

If no secret is specified in opsdroid configuration, then we are assuming that every request is a valid one. Note that, you should add a secret otherwise anyone could submit a POST request to the URL and pretent to be GitLab.

Return type

bool