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 sync
$ 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 sync --group dev

Tests

$ make test

You can also run the tests within the built docker image.

$ make build
$ make test-docker

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

$ make requirements

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.

$ make build

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 --phab-cookie $PHABRICATOR_SESSION_COOKIE \
  --pmo-cookie $PMO_COOKIE \
  --input herald_rules.json --output herald_rules.new.json \
$ mv herald_rules.new.json herald_rules.json

Get/create your $PHAB_TOKEN from https://phabricator.services.mozilla.com/settings/user//page/apitokens/, where you can also get the phsid cookie as $PHABRICATOR_SESSION_COOKIE. Get your $PMO_COOKIE from the pmo-access cookie after logging in to https://people.mozilla.org/

Those rules should be placed at the root of the source tree, and committed to git so they are built as part of the image. make build takes care of using configuring the image adequately.

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