Webhook-based integration to add GitLab issue deadlines to Google Calendar
This application receives issue webhooks from GitLab and manages events in Google Calendar corresponding to those issues' deadlines.
No storage is required on the webhook server. All necessary state is stored in extended attributes of Google Calendar events.
You must define a mapping between GitLab repositories and calendars. Any calendars defined in the mapping will automatically be created.
A service account is utilized so that the application owns the calendars it creates. You can add the service's calendars to your own Google Calendar account via their IDs.
As-is, a G Suite domain is required for the purpose of access control, however you can also modify the ACL instantiation manually to authenticate at a level other than the domain.
Optionally, issue assignees can automatically be added as event attendees. If enabled, the assignee's email address is fetched from their GitLab profile. This allows Google Calendar to notify them of upcoming issue deadlines.
pip install -r requirements.txt
Tested on Python 3.5.2. May work on older versions, but not guaranteed.
google-api-python-client, available through
gitlabApi feature is desired, then
python-gitlab must also be
installed (also through
An example configuration file is provided in
config.json. The following
keys are defined:
logLevel: Logging detail level, choose from
timezone: Time zone for created calendars, in standard
googleSecretFile: Filename containing credentials for the Google service account.
gitlabSecret: Webhook authentication token for GitLab.
authorizedDomain: The G Suite domain name authorized to access calendars.
listenPort: Port to listen for on for incoming webhooks.
ssl: Configuration for TLS.
enable: Boolean indicating whether TLS should be used.
keyfile: Path to PEM file containing private key. Not required if
certfile: Path to PEM file containing certificate. Not required if
repoMap: Mapping between GitLab project names (keys) and calendars (values).
dropPrivileges: Configuration for dropping root privileges after necessary files and sockets are open.
enable: Boolean indicating whether to drop root privileges.
user: Name of user to switch to after initialization. Not required if
group: Name of group to switch to after initialization. Not required if
gitlabApi: Configures additional features accessed through the GitLab API.
enable: Boolean indicating whether or not to load the GitLab API module.
url: URL for your GitLab instance. Not required if
token: Impersonation token for the GitLab instance. Not required if
inviteAssignees: Boolean indicating whether to invite issue assignees to deadline events by fetching their email address from GitLab.
The Google credential file is obtained when you create a service account. A service account can be created at https://console.developers.google.com/iam-admin/serviceaccounts/.
Timezones and ACLs are set up at the time a calendar is created, so make sure
authorizedDomain values are set correctly before
repoMap and starting the daemon for the first time.
Note that in the
repoMap, only the actual project names are used -- not the
full namespaces. Multiple projects may be mapped to the same calendar.
dropPrivileges configuration allows root privileges to be dropped after
loading TLS keys, loading API credentials, and opening the listen socket. If you
must run this application as root in order to open these files, or you are
listening on a privileged port, then it is highly recommended to enable this
gitlabApi integration is entirely optional, and will only unlock the
ability to automatically add issue assignees to corresponding events as
attendees. If it is not enabled, then the
python-gitlab package need not be
python3 calendar_manager.py config.json. The process will persist in
the foreground by default, so run it in a screen or under a daemon manager if
you want to background it.
The first time you run this application, it will create all calendars listed
repoMap. The IDs of these calendars will be printed to the console.
Paste an ID in Google Calendar's "Add a coworker's calendar" box to synchronize
it with your account.
KeyboardInterrupt or SIGINT will cleanly stop the process.
docker build -t gitlab-calendar .
docker run -d --name gitlab-calendar -p 8080:8080 gitlab-calendar
- View logs:
docker logs gitlab-calendar
docker stop gitlab-calendar
docker rm gitlab-calendar
Issue deadlines will be inserted as events in the specified calendars. Each event description will include the URL of the issue, and the username of the assignee (if applicable). Modifications to issues (title changes, deadline changes, assignee changes) will automatically be synchronized to the calendar.
Closing an issue or removing its deadline will remove it from your calendar. Reopening the issue or resetting its deadline will add it back again.
This application does not load issues from GitLab -- it only listens for events pertaining to them in real time. Therefore, previously existing issues and issues created or modified while this service is inactive will not be reflected in your calendars.
Changing a repo's calendar in the
repoMap will break things. Don't do it.
inviteAssignees, then be warned that if an assignee changes their
email address on GitHub, that change will not be reflected in any calendar
entries unless the corresponding issue is updated.
As stated above,
authorizedDomain attributes of calendars
are set at the time they are created, so make sure they are correct before
you run the application for the first time.
This application consists of a webhook listener and an event processing thread.
The webhook listener is simple. It is based on Python's built-in
BaseHTTPRequestHandler class. When it receives a valid event from GitLab, it
adds it to the processing queue, where the processing thread will later service
On initialization, the processing thread instantiates a session with the Google Calendar API and fetches the IDs of mapped calendars. It then enters an event loop, wherein it receives events from the queue and asynchronously processes them. All contact with the Google calendar API occurs within this event thread.
If you can make this program better without breaking anything, I will gladly accept your pull request. If you find something that is already broken, submit a report and I'll get to it as soon as possible.
This software is provided as-is without warranty under the terms of the MIT
License, available in the
LICENSE file distributed alongside it.