mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 03:00:11 +01:00
ci,marge_queue: objects to represent the queue
Enhancement of the module with two structures that can encapsulate functionalities and establish links between data collected. Signed-off-by: Sergi Blanch Torne <sergi.blanch.torne@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37395>
This commit is contained in:
parent
02af2a199b
commit
bf5626c82f
1 changed files with 87 additions and 2 deletions
|
|
@ -12,15 +12,18 @@ Monitors Marge-bot and return number of assigned MRs.
|
|||
import argparse
|
||||
import time
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from dateutil import parser
|
||||
from typing import Optional
|
||||
|
||||
import gitlab
|
||||
from gitlab.v4.objects import Project
|
||||
from gitlab.v4.objects import Project, ProjectMergeRequest
|
||||
from gitlab_common import read_token, pretty_duration
|
||||
|
||||
REFRESH_WAIT = 30
|
||||
MARGE_BOT_USER_ID = 9716
|
||||
ASSIGNED_TO_MARGE = "assigned to @marge-bot"
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
|
|
@ -39,6 +42,88 @@ def parse_args() -> argparse.Namespace:
|
|||
return parse.parse_args()
|
||||
|
||||
|
||||
@dataclass
|
||||
class MargeMergeRequest:
|
||||
"""Represent a Merge Request assigned to Marge"""
|
||||
id: int = field(init=False)
|
||||
mr: ProjectMergeRequest = field(repr=False)
|
||||
updated_at: datetime | None = field(init=False, repr=False)
|
||||
assigned_at: datetime | None = field(init=False, repr=False)
|
||||
|
||||
def __post_init__(self):
|
||||
self.id = self.mr.iid
|
||||
self.updated_at = parser.parse(self.mr.updated_at)
|
||||
self.assigned_at = self.__find_last_assign_to_marge()
|
||||
|
||||
def __find_last_assign_to_marge(self) -> Optional[datetime]:
|
||||
for note in self.mr.notes.list(
|
||||
iterator=True,
|
||||
order_by="updated_at",
|
||||
sort="desc"
|
||||
): # start with the most recent
|
||||
if note.body.startswith(ASSIGNED_TO_MARGE):
|
||||
return parser.parse(note.created_at)
|
||||
|
||||
def __eq__(self, other: "MargeMergeRequest") -> bool:
|
||||
return self.id == other.id
|
||||
|
||||
@property
|
||||
def time_enqueued(self) -> timedelta:
|
||||
if self.assigned_at is None:
|
||||
raise ValueError("Assign to marge timestamp not defined")
|
||||
return datetime.now(timezone.utc) - self.assigned_at
|
||||
|
||||
@property
|
||||
def web_url(self) -> str:
|
||||
return self.mr.web_url
|
||||
|
||||
@property
|
||||
def title(self) -> str:
|
||||
return self.mr.title
|
||||
|
||||
|
||||
@dataclass
|
||||
class MargeQueue:
|
||||
"""
|
||||
Collect and sort the merge requests assigned to marge
|
||||
"""
|
||||
elements_sorted: dict[datetime, MargeMergeRequest] = field(
|
||||
init=False, repr=False, default_factory=dict
|
||||
)
|
||||
undetermined: list[MargeMergeRequest] = field(
|
||||
init=False, repr=False, default_factory=list
|
||||
)
|
||||
|
||||
def append(self, mr: MargeMergeRequest) -> None:
|
||||
if mr.assigned_at is not None:
|
||||
self.elements_sorted[mr.assigned_at] = mr
|
||||
else:
|
||||
self.undetermined.append(mr)
|
||||
|
||||
@property
|
||||
def n_merge_requests_enqueued(self) -> int:
|
||||
return len(self.elements_sorted) + len(self.undetermined)
|
||||
|
||||
@property
|
||||
def sorted_queue(self) -> list[MargeMergeRequest]:
|
||||
"""
|
||||
Provide a list of the elements that can be sorted based on the
|
||||
assignment to Marge.
|
||||
"""
|
||||
return list(dict(sorted(self.elements_sorted.items())).values())
|
||||
|
||||
@property
|
||||
def all_assigned(
|
||||
self
|
||||
) -> list[MargeMergeRequest]:
|
||||
"""
|
||||
Provide a single list, but in sorted, of all the elements found
|
||||
assigned to Marge. This include the elements in elements_sorted
|
||||
and the ones undetermined (expected to be empty).
|
||||
"""
|
||||
return self.sorted_queue + self.undetermined
|
||||
|
||||
|
||||
def get_merge_queue(project: Project) -> int:
|
||||
mrs = project.mergerequests.list(
|
||||
assignee_id=MARGE_BOT_USER_ID,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue