Skip to content

mozilla-conduit/reviewer-selector

Repository files navigation

Reviewer selector

Select reviewers based on a diff and a set of rules.

Setup

Requirements: uv.

$ uv venv
$ uv pip install -e .

Running

In its simplest form, the script accepts a diff on stdin. It processes the diff according to a rule file passed as an argument, and outputs a list of individual and groups of reviewers.

$ uv run reviewer-selector samples/herald_rules.sample.json < samples/sample.diff
#example-group shtrom

The group prefix can be changed with --group-prefix. The reviewer separator can be changed with --reviewer-separator. The --repo option allows the user to specify a specific repository (to be used when evaluating conditions in some rules.

WARNING: The rules format is a work in progress

The current rules files, as shown in the sample is not final and not normative. It is used as a bootstrapping stop-gap, and should not be expected to remain stable at this stage.

TaskCluster and GitHub authentication

To generate a GitHub application token based on a TaskCluster secret, use the gh-token-generator script. The secret should contain two values, named GITHUB_APP_ID and GITHUB_APP_PRIVKEY.

The generator relies on Standard TaskCluster Environment Variables to obtain the secret named with ID TC_SECRET_ID. Those variables can be set with the Taskcluster shell client, taskcluster signin.

Building the Taskcluster Client for Shell

Requirements: golang

$ git clone https://github.com/taskcluster/taskcluster
$ cd taskcluster/clients/client-shell
$ go build -o taskcluster .
$ eval $(/PATH/TO/taskcluster/clients/client-shell/taskcluster signin)  # follow the web prompts
$ export ORG_NAME=mozilla-firefox
$ export REPO_NAME=infra-testing
$ uv run gh-token-generator

then

$ GITHUB_TOKEN=$(uv run gh-token-generator)
$ gh ...

Development tasks

All the commands in this section rely on the development dependencies being installed.

$ uv pip install -e .[dev]

Tests

$ uv run pytest

Linting

Ruff has a linter and a formatter. We use both,

$ uv run ruff format
$ uv run ruff check --fix

or simply,

$ make format

Regenerating requirements.txt

Runtime dependencies only.

$ uv run pip-compile --quiet --generate-hashes --allow-unsafe -o requirements.txt

Include dev and testing dependencies.

$ uv run pip-compile --quiet --generate-hashes --extra=dev --allow-unsafe -o requirements-dev.txt

Containerised deployment

For use as part of a more complex pipeline, a docker image can be built. It is setup to take most of its arguments from environment variables, and will update a GitHub pull request directly if enough information is available.

Building the container image

Requirements: docker.

$ docker build -f docker/Dockerfile -t reviewer-selector .

Bundling herald_rules.

The default behaviour is to search the target repository/branch for a herald_rules.json file. If missing, a fallback from the container is used.

Herald rules can be extracted from Phabricator using the Herald Crawler.

$  herald-scraper --url https://phabricator.services.mozilla.com \
  --conduit-token $PHAB_TOKEN --pmo-cookie $PEOPLE_MOZILLA_COOKIE \
  --output herald_rules.json \

Get/create your $PHAB_TOKEN from https://phabricator.services.mozilla.com/settings/user//page/apitokens/. Get your $PEOPLE_MOZILLA_COOKIE from the pmo-access cookie after logging in to https://people.mozilla.org/

This file can then be bundled as default in the container image.

$ docker build -f docker/Dockerfile \
  --build-arg BUILTIN_HERALD_RULES=herald_rules.json \
  -t reviewer-selector \
  .

$ docker tag reviewer-selector omehani/moz-reviewer-selector
$ docker push omehani/moz-reviewer-selector

This is the image tag that the CI hook currently uses.

XXX: update this tag

Running in a container

For convenience, the sample rules are shipped with the container image. The reviewers string is formatted for use with GitHub's gh CLI.

$ docker run --rm -i reviewer-selector < samples/sample.diff
No REPO_URL in environment, using built-in rules ...
No DIFF_URL in environment, reading from stdin ...
No ORG_NAME in environment, using # as group prefix ...
No REPO_NAME or TARGET_BRANCH_NAME in environment, not matching repository-based rules ...
No PR_URL or GITHUB_TOKEN in environment, outputing to stdout ...
@example-group,shtrom

The warnings are output to stderr.

A more advanced example would mount a real ruleset into the container at /app/herald_rules.json. The diff data can be fetched from a pull request and piped into the container.

$ curl --silent --location https://github.com/mozilla-firefox/infra-testing/pull/30.diff \
   | docker run --rm -i \
     -v ./herald_rules.real.json:/app/herald_rules.json \
     reviewer-selector
No REPO_URL in environment, using built-in rules ...
No DIFF_URL in environment, reading from stdin ...
No ORG_NAME in environment, using # as group prefix ...
No REPO_NAME or TARGET_BRANCH_NAME in environment, not matching repository-based rules ...
No PR_URL or GITHUB_TOKEN in environment, outputing to stdout ...
@android-reviewers

The container's behaviour can be entirely parametrised via environment variables.

$ docker run --rm -i \
  -v ./herald_rules.real.json:/app/herald_rules.json \
  -e DIFF_URL=https://github.com/mozilla-firefox/infra-testing/pull/30.diff \
  -e PR_URL=https://github.com/mozilla-firefox/infra-testing/pull/30 \
  -e REPO_URL=https://github.com/mozilla-firefox/infra-testing \
  -e ORG_NAME=mozilla-firefox -e REPO_NAME=infra-testing \
  -e GITHUB_TOKEN=[REDACTED] \
  reviewer-selector
Adding reviewers to https://github.com/mozilla-firefox/infra-testing/pull/30 ...
  • If DIFF_URL is given, it will be fetched and passed into the selector's stdin.
  • If GITHUB_TOKEN and PR_URL are provided, the container will attempt to set the reviewers on the target PR.

Some other optional behaviours can be triggered by providing additional context in environment variables:

  • If ORG_NAME is passed, it will be used to scope reviewers groups to that org.
  • If REPO_NAME and TARGET_BRANCH_NAME are provided, rules that specifically match a given repository and/or branch will also be applied.
  • If REPO_URL is given, the script will attempt to fetch a rules file from the main branch of the repository. If it fails, it will fallback to built-in rules.
  • If TC_SECRET_ID is provided, it is expected to contain GITHUB_APP_ID and GITHUB_APP_PRIVKEY values. They will be used to generate a GITHUB_TOKEN (if unspecified) for ORG_NAME/REPO_NAME.

About

Select reviewers based on a diff and a set of rules

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Contributors