committed by
GitHub
2 changed files with 63 additions and 1 deletions
@ -0,0 +1,60 @@ |
|||||
|
import logging |
||||
|
from typing import Literal |
||||
|
|
||||
|
from github import Github |
||||
|
from github.PullRequestReview import PullRequestReview |
||||
|
from pydantic import BaseModel, SecretStr |
||||
|
from pydantic_settings import BaseSettings |
||||
|
|
||||
|
|
||||
|
class LabelSettings(BaseModel): |
||||
|
await_label: str | None = None |
||||
|
number: int |
||||
|
|
||||
|
|
||||
|
default_config = {"approved-2": LabelSettings(await_label="awaiting-review", number=2)} |
||||
|
|
||||
|
|
||||
|
class Settings(BaseSettings): |
||||
|
github_repository: str |
||||
|
token: SecretStr |
||||
|
debug: bool | None = False |
||||
|
config: dict[str, LabelSettings] | Literal[""] = default_config |
||||
|
|
||||
|
|
||||
|
settings = Settings() |
||||
|
if settings.debug: |
||||
|
logging.basicConfig(level=logging.DEBUG) |
||||
|
else: |
||||
|
logging.basicConfig(level=logging.INFO) |
||||
|
logging.debug(f"Using config: {settings.json()}") |
||||
|
g = Github(settings.token.get_secret_value()) |
||||
|
repo = g.get_repo(settings.github_repository) |
||||
|
for pr in repo.get_pulls(state="open"): |
||||
|
logging.info(f"Checking PR: #{pr.number}") |
||||
|
pr_labels = list(pr.get_labels()) |
||||
|
pr_label_by_name = {label.name: label for label in pr_labels} |
||||
|
reviews = list(pr.get_reviews()) |
||||
|
review_by_user: dict[str, PullRequestReview] = {} |
||||
|
for review in reviews: |
||||
|
if review.user.login in review_by_user: |
||||
|
stored_review = review_by_user[review.user.login] |
||||
|
if review.submitted_at >= stored_review.submitted_at: |
||||
|
review_by_user[review.user.login] = review |
||||
|
else: |
||||
|
review_by_user[review.user.login] = review |
||||
|
approved_reviews = [ |
||||
|
review for review in review_by_user.values() if review.state == "APPROVED" |
||||
|
] |
||||
|
config = settings.config or default_config |
||||
|
for approved_label, conf in config.items(): |
||||
|
logging.debug(f"Processing config: {conf.json()}") |
||||
|
if conf.await_label is None or (conf.await_label in pr_label_by_name): |
||||
|
logging.debug(f"Processable PR: {pr.number}") |
||||
|
if len(approved_reviews) >= conf.number: |
||||
|
logging.info(f"Adding label to PR: {pr.number}") |
||||
|
pr.add_to_labels(approved_label) |
||||
|
if conf.await_label: |
||||
|
logging.info(f"Removing label from PR: {pr.number}") |
||||
|
pr.remove_from_labels(conf.await_label) |
||||
|
logging.info("Finished") |
Loading…
Reference in new issue