A flask web application that handles webhook notifications for pull request changes and sends out notifications when there are changes to files matched by the configured patterns for each repository
Python 3.11 or newer
- The application has to be run on a internet-accessible URL in production. During development, a tool like
ngrokcan be used to expose the local development server on the internet. - Create a webhook on the repository to be watched by following these instructions. This requires administrator-level access to the repository.
- Use the
<Internet-accessible URL of the app>/pull-requestsas the payload URL and set theContent Typetoapplication/json. - Remember to set a secret and to select only the 'Pull request' event.
- Create a GitHub access token. No particular permissions are required for a public repository. The
reposcope permissions are needed for private repositories.
- Clone this repository and navigate into the cloned directory.
- Create a virtualenv environment and install the requirements.
$ python3 -m venv venv
$ source venv/bin/activate
$ make requirements- Verify that the unit tests run without errors and pass.
$ make test- Configure the environment variables used in the
settings.pyfile. - Setup the watch configuration YAML file and configure the
WATCH_CONFIG_FILEenvironment variable to point to it. The file format is documented inwatch_config.yml.sample. - Set the
FLASK_APPenvironment variable to point to therun.pyfile. - Set the
FLASK_DEBUGenvironment variable to1and run the development server.
$ export FLASK_APP=run.py
$ export FLASK_DEBUG=1
$ flask runThe development server should now be available at http://127.0.0.1:5000 and listening for the webhook notifications.
To modify the IP address or the port used by the development server, use the -h and -p flags of the flask run
command respectively.
$ flask run -h 0.0.0.0 -p 8000The app gets its configuration settings from the following environment variables.
-
GITHUB_ACCESS_TOKEN- The GitHub access token which has the appropriate permissions to access the repositories the app will be configured to watch. Get this from https://github.com/settings/tokens. -
GITHUB_WEBHOOK_SECRET- The webhook secret token used to create the GitHub webhook. This is a random string you make up, and will use when configuring the webhook.uuid.uuid4()could be a good source. -
WATCH_CONFIG_FILE- The file containing the watch configuration to be used by the app. -
CUSTOM_CONFIG_REPO- Optional. Required only when deploying to Heroku. URL of a git repository containing the watch configuration file, which must be named config.yml. More details in the section about deploying to Heroku. -
LOG_LEVEL- the log level to use: "debug", "info", "warning", or "error".
The following settings related to email accept values as documented in the Flask-Mail documentation.
MAIL_DEFAULT_SENDERMAIL_SERVERMAIL_PORTMAIL_USE_TLSMAIL_USERNAMEMAIL_PASSWORD
An example Procfile which deploys this app to Heroku using gunicorn is provided. Since Heroku doesn't provide an easy
way to deploy custom configuration files, the do_pre_release_steps.sh script is run before starting the app.
The script downloads the watch configuration file named config.yml from an external git repository specified in
the CUSTOM_CONFIG_REPO environment variable to the location specified in the WATCH_CONFIG_FILE environment variable.
If the repository also contains a templates sub-directory containing the custom email templates, those are copied to
the app templates directory and can be used in the watch configuration file.
Here is an example repo that can be used as the CUSTOM_CONFIG_REPO.
To use this as a GitHub webhook, you configure either a per-repo or per-organization webhook:
- For payload URL, use https:///pull-requests .
- For Content type, use application/json .
- For Secret, use whatever you set for
GITHUB_WEBHOOK_SECRETabove. - For Events, choose Pull requests.
Dropped support for Python 3.8 and added support for Python 3.12.
Resolved pylint warnings in make test.quality.
The format of the "subject" key changed from a str.format() format string to a Jinja template to match the format for the "body" template, and to give access to more information.
First version in production