Commit 3ede0447 authored by Simon Chabot's avatar Simon Chabot
Browse files

feat(notification): add comment on “old” MR to notify the assignees there is pending work

Only old MR (for now 10 days without activity), which are not wip, not client
related, and with an assignee, add a friendly comment.

closes: cubicweb/cubicweb#101
parent 1a7141cb53b1
Pipeline #20618 failed with stage
in 26 seconds
......@@ -22,7 +22,7 @@
import os
from argparse import ArgumentParser
from random import choice, shuffle
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
import logging
import yaml
......@@ -39,6 +39,17 @@ CLIENT_PROJECT_TAG = "client-project"
STATE_FILENAME = "auto_assigned_reviewers.csv"
logging.basicConfig(level=os.getenv("AB_LOG_THRESHOLD", "INFO").upper())
PENDING_MR_MESSAGE = """\
Dear contributors,
It seems that there hasn't been any activity concerning this merge request for
some time.
Do you think it should still be merged?
Thank you for your time.
"""
class ReviewAssigner:
def __init__(self, gitlab_url, gitlab_token, users_preferences_filepath):
......@@ -145,13 +156,13 @@ class ReviewAssigner:
merge_request.title,
)
def all_reviews_to_do(self):
def _all_reviews(self, assignee_id="None"):
merge_requests = self.cnx.mergerequests.list(
labels=TO_REVIEW_LABEL,
state="opened",
wip="no",
scope="all",
assignee_id="None",
assignee_id=assignee_id,
all=True,
)
......@@ -161,7 +172,7 @@ class ReviewAssigner:
state="opened",
wip="no",
scope="all",
assignee_id="None",
assignee_id=assignee_id,
all=True,
)
)
......@@ -186,6 +197,18 @@ class ReviewAssigner:
continue
yield merge_request
def all_reviews_to_do(self):
return self._all_reviews(assignee_id="None")
def all_pending_reviews_older_than(self, older_than):
now = datetime.now(timezone.utc)
for mr in self._all_reviews(assignee_id="Any"):
mr_last_update = datetime.fromisoformat(
mr.updated_at.replace('Z', '+00:00')
)
if mr_last_update + older_than < now:
yield mr
def assign_reviews(self):
for mr in self.all_reviews_to_do():
try:
......@@ -199,6 +222,28 @@ class ReviewAssigner:
continue
self.assign_reviewer(mr, reviewer)
def notify_contributors_for_pending_reviews(
self, older_than=timedelta(days=10)
):
for mr in self.all_pending_reviews_older_than(older_than):
# we have a MergeRequest object,
# but discussion can only be done on ProjectMergeRequest,
# hence this gymnastic.
# XXX what's the difference between MergeRequest and
# ProjectMergeRequest ?
project = self.cnx.projects.get(mr.project_id)
project_mr = project.mergerequests.get(mr.iid)
logging.info(
"no activity on %s (%s) for a while, let's add a "
"friendly notification",
project_mr.title,
project_mr.web_url,
)
project_mr.discussions.create(
data={"body": PENDING_MR_MESSAGE}
)
def main():
parser = ArgumentParser()
......@@ -210,6 +255,7 @@ def main():
assigner = ReviewAssigner(
args.gitlab_url, args.gitlab_token, args.users_preferences_filepath
)
assigner.notify_contributors_for_pending_reviews()
assigner.assign_reviews()
assigner.save_review_states()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment