diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 00000000000..a58dceaa1e6 --- /dev/null +++ b/.github/workflows/labeler.yml @@ -0,0 +1,33 @@ +--- +# Copyright (C) 2023 Maxwell G +# SPDX-License-Identifier: GPL-3.0-or-later + +"on": + pull_request_target: + +name: "Triage PRs" + +permissions: + issues: write + pull-requests: write + +jobs: + label_prs: + runs-on: ubuntu-latest + name: "Label PRs" + steps: + - name: Checkout parent repository + uses: actions/checkout@v3 + - name: Install Python 3.11 + uses: actions/setup-python@v4 + with: + python-version: "3.11" + - name: Setup venv + run: | + python -m venv venv + ./venv/bin/pip install -r hacking/pr_labeler/requirements.txt + - name: Run the PR labeler + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + ./venv/bin/python hacking/pr_labeler/label.py ${{ github.event.number }} diff --git a/hacking/pr_labeler/label.py b/hacking/pr_labeler/label.py new file mode 100644 index 00000000000..2fd1179647e --- /dev/null +++ b/hacking/pr_labeler/label.py @@ -0,0 +1,53 @@ +# Copyright (C) 2023 Maxwell G +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import annotations + +import os +from pathlib import Path + +import github +import github.Auth +import github.PullRequest +import typer +from codeowners import CodeOwners, OwnerTuple + +OWNER = "ansible" +REPO = "ansible-documentation" +LABELS_BY_CODEOWNER: dict[OwnerTuple, list[str]] = { + ("TEAM", "@ansible/steering-committee"): ["sc_approval"], +} +HERE = Path(__file__).resolve().parent +ROOT = HERE.parent.parent +CODEOWNERS = (ROOT / ".github/CODEOWNERS").read_text("utf-8") + + +def handle_codeowner_labels(pr: github.PullRequest.PullRequest) -> None: + labels = LABELS_BY_CODEOWNER.copy() + owners = CodeOwners(CODEOWNERS) + files = pr.get_files() + for file in files: + for owner in owners.of(file.filename): + if labels_to_add := labels.pop(owner, None): + print("Adding labels to", f"{pr.id}:", *map(repr, labels_to_add)) + pr.add_to_labels(*labels_to_add) + if not labels: + return + + +APP = typer.Typer() + + +@APP.command() +def main(pr_number: int) -> None: + gclient = github.Github(auth=github.Auth.Token(os.environ["GITHUB_TOKEN"])) + repo = gclient.get_repo(f"{OWNER}/{REPO}") + pr = repo.get_pull(pr_number) + if pr.state != "open": + print("Refusing to process closed ticket") + return + handle_codeowner_labels(pr) + + +if __name__ == "__main__": + APP() diff --git a/hacking/pr_labeler/requirements.txt b/hacking/pr_labeler/requirements.txt new file mode 100644 index 00000000000..6765d031ea0 --- /dev/null +++ b/hacking/pr_labeler/requirements.txt @@ -0,0 +1,3 @@ +codeowners +pygithub +typer