Skip to content

[gitlab] Add GitLab connection and EventInfo classes#370

Open
sondrebr wants to merge 19 commits into
EESSI:gitlabfrom
sondrebr:add-gitlab-support-event-info-classes
Open

[gitlab] Add GitLab connection and EventInfo classes#370
sondrebr wants to merge 19 commits into
EESSI:gitlabfrom
sondrebr:add-gitlab-support-event-info-classes

Conversation

@sondrebr
Copy link
Copy Markdown
Collaborator

First step towards implementing GitLab support for the bot. This PR adds:

  • New/updated dependencies (python-gitlab, PyGHee with GitLab support)
  • New config sections git and gitlab
  • connections/gitlab.py for connecting to GitLab
  • tools/git.py with functions:
    • get_hosting_platform() gets the configured Git hosting platform (GitHub/GitLab)
    • connect_to_host() performs initial connection to GitHub/GitLab
  • tools/event_info.py with:
    • BaseEventInfo class intended as an "interface" to implement for each Git hosting platform
    • GitHubEventInfo class implementing BaseEventInfo for GitHub
    • GitLabEventInfo class implementing BaseEventInfo for GitLab
    • create_event_info_instance() creating an instance of the correct EventInfo class
  • A handle_event() override in the event handler to use the new EventInfo classes

The PR does not any methods for handling GitLab events, but the events will be logged, e.g.:

[20260421-T10:53:03] Event received (id: 39c64e78-fdd1-4799-a9c6-568d9b7ffb4b, type: note, action: create), event data logged at [...]
[20260421-T10:53:03] Request verified: signature OK!
[20260421-T10:53:03] WARNING: [event id 39c64e78-fdd1-4799-a9c6-568d9b7ffb4b] No handler found for event type 'note' (action: create) - event was received but left unhandled!

get_hosting_platform() is intended to be used whenever platform-specific logic is required, to simplify adding support for other platforms in the future (e.g. Forgejo/Codeberg, Gitea, ...).

The *EventInfo classes were implemented to handle the differences between the GitHub and GitLab webhooks, such that the necessary information can be retrieved through class properties. For example, event_info.action returns the event action. If GitLabEventInfo is used, the action property converts the action to its GH equivalent before returning, e.g. update becomes edited.
The classes currently have support for (as far as I can tell) all event_info fields used by the bot.
They also have a __getitem__() override to support subscripting for compatibility with the existing uses of event_info - this version of the bot should therefore still have full GitHub support.

Usage

Because webhooks signatures are not yet supported by GitLab (though they are in development), it is necessary to run a custom Smee server to sign the webhooks. I have a fork here which should sign the events in the same way as they will be signed on GitLab in the future. I have also added a "Quickstart" section on top of the README in the fork with instructions on how to run the server.

To "use" the bot in its current state on GitLab, you need to do the following:

  • Install the requirements (pip install -r requirements.txt)
    Ensure the correct version of PyGHee (commit c5e1063...) is installed.
  • Create a webhook on a GitLab project (Settings -> Webhooks -> Add new)
    The webhook should have the Comments and Merge request events triggers, and must be configured with a secret token. The secret token can be generated e.g. by running python -c "import secrets; print(secrets.token_hex())", and must be stored as the environment variable GITLAB_WEBHOOK_SECRET_TOKEN. The webhooks must also be set up to send events to the custom Smee server.
  • Create a project access token for the same GitLab project (Settings -> Access tokens -> Add new token)
    In the future, the api scope and Planner will be required for the bot to be able to write comments. For this PR, however, it just needs to be able to connect to GitLab, so the read_api scope and Guest role should be sufficient. The access token must be stored as the environment variable GITLAB_PROJECT_ACCESS_TOKEN.
  • Configure the git and gitlab sections in app.cfg
    In the git section, hosting_platform = gitlab must be set (if it is set to github instead, the bot should function normally).
    In the gitlab section, the api_timeout, bot_name, and instance_url options must be set. For the instance_url option, you must enter the base URL of your GitLab instance, which is used along with the access token to connect to GitLab.

@sondrebr sondrebr changed the base branch from gitlab to develop April 23, 2026 11:51
@sondrebr sondrebr changed the base branch from develop to gitlab April 23, 2026 11:51
@sondrebr
Copy link
Copy Markdown
Collaborator Author

Had to temporarily switch the base branch to get rid of some old commits 🤦 Ready for review now.

Copy link
Copy Markdown
Contributor

@trz42 trz42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a solid PR tackling the first step towards supporting repositories hosted on GitLab and GitHub.

What's a bit missing is explaining some kind of data model that is used to form the interface defined by BaseEventInfo. This doesn't need to cover all kinds of events and actions GitHub and GitLab support, but only the ones we currently use in the bot which only supports GitHub.

While the difference in how events are generated for labels might trigger a more substantial UI change (replacing setting the label bot:deploy with a new command bot:deploy [ARGS]), we might live with a workaround as the bot only supports one specific label (bot:deploy).

More comments (mostly suggesting changes ... not really requesting them) are provided with the code.

Comment thread requirements.txt Outdated
Comment thread connections/gitlab.py Outdated
Comment thread connections/gitlab.py Outdated
Comment thread connections/gitlab.py Outdated
Comment thread connections/gitlab.py
Comment thread tools/event_info.py Outdated
Comment thread tools/event_info.py Outdated
Comment thread tools/event_info.py Outdated
Comment thread tools/event_info.py
Comment thread tools/event_info.py
sondrebr and others added 10 commits May 4, 2026 13:24
Python 3.9 needs its own pin as python-gitlab dropped support with version 7.0.0.
Co-authored-by: Thomas Röblitz <trz42@users.noreply.github.com>
Currently unused - may be reintroduced later if needed
pr_number and pr_url would previously also be used to get issue numbers/URLs
The new name more accurately describes the property
Co-authored-by: Thomas Röblitz <trz42@users.noreply.github.com>
@sondrebr
Copy link
Copy Markdown
Collaborator Author

sondrebr commented May 8, 2026

What's a bit missing is explaining some kind of data model that is used to form the interface defined by BaseEventInfo. This doesn't need to cover all kinds of events and actions GitHub and GitLab support, but only the ones we currently use in the bot which only supports GitHub.

I have these notes (which I've cleaned up a bit) from when I prepared to start working on GL support for the bot. Hopefully they show the basis for BaseEventInfo, which I think covers all fields below. Note that with the pr_url property now split up into issue_url and pr_url, issue_url will be used, while pr_url as far as I can tell will be unused. Maybe a use case pops up, or we can remove it?

For the section documenting raw_request_body, the entries have the variable name used in the bot on the left-hand side, showing (to some degree) how the field is used. The _.{field} notation shows which field it is in the body, e.g. _.comment.body corresponds to event_info['raw_request_body']['comment']['body'].


Where fields are used

raw_request_body

  • update_pr_comment() function in tools/pr_comments.py (unused?)
    • comment_new = _.comment.body
    • repo_name = _.repository.full_name
    • pr_number = _.issue.number
    • issue_id = _.comment.id
  • deploy_built_artefacts() function of tasks/deploy.py
    • labeler = _.sender.login
    • repo_name = _.repository.full_name
  • prepare_jobs() function of tasks/build.py
    • job_owner = _.sender.login
  • check_build_permission() function of tasks/build.py
    • build_labeler = _.sender.login
    • repo_name = _.repository.full_name
  • Different handle_ methods in EESSIBotSoftwareLayer class
    • issue_url = _.issue.url
    • action = _.action
    • sender = _.sender.login
    • owner = _.comment.user.login
    • repo_name = _.repository.full_name
    • pr_number = _.issue.number
    • comment_received = _.comment.body
    • label = _.label.name
      • GL has no "labeled" action - can be identified by checking for _.changes.labels
    • pr_number = _.pull_request.number
    • mergedOrClosed = _.pull_request.merged

Summary - Unique used fields in raw_request_body -> property name in EventInfo

  • Misc. fields
    • _.action -> action
    • _.repository.full_name -> repo_name
    • _.sender.login -> event_triggered_by
  • PR/issue-related fields
    • _.pull_request.number -> pr_number
    • _.pull_request.merged -> pr_merged_status
    • _.issue.number -> issue_number
    • _.issue.url -> issue_url
    • _.label.name -> label_name
  • Comment-related fields
    • _.comment.body -> comment_body
    • _.comment.id -> comment_id
    • _.comment.user.login -> comment_created_by

action (from body) -> action in EventInfo

  • handle_issue_comment_event() method of EESSIBotSoftwareLayer class
    • Comment is processed only if action is created
  • handle_installation_event() method of EESSIBotSoftwareLayer class
    • Logs user & action
  • handle_pull_request_event() method of EESSIBotSoftwareLayer class
    • Used to get handle_pull_request_{action}_event() method
      • Actions with methods:
        • labeled
        • opened
        • closed

id (from header) -> event_id in EventInfo

  • create_pr_dir() function of tasks/build.py
    • Used to create job directory (**/event_{id}/)

type (from header) -> event_type in EventInfo

  • handle_event() method of PyGHee class
    • Used to get handle_{type}_event() method
      • Installation (N/A for GL)
      • Issue comment
      • Pull request

@sondrebr sondrebr requested a review from trz42 May 13, 2026 08:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants