|
| 1 | +from functools import cache |
| 2 | +from urllib.parse import quote as urlquote |
| 3 | +import logging |
| 4 | +import os |
| 5 | +from typing import Any |
| 6 | + |
| 7 | +from .http_utils import requests_session |
| 8 | +from .supervisor_types import MergeRequest, MergeRequestState |
| 9 | + |
| 10 | +logger = logging.getLogger(__name__) |
| 11 | + |
| 12 | +GITLAB_URL = "https://gitlab.com" |
| 13 | + |
| 14 | + |
| 15 | +@cache |
| 16 | +def gitlab_headers() -> dict[str, str]: |
| 17 | + gitlab_token = os.environ["GITLAB_TOKEN"] |
| 18 | + |
| 19 | + return { |
| 20 | + "Authorization": f"Bearer {gitlab_token}", |
| 21 | + "Content-Type": "application/json", |
| 22 | + } |
| 23 | + |
| 24 | + |
| 25 | +def gitlab_api_get(path: str, *, params: dict | None = None) -> Any: |
| 26 | + url = f"{GITLAB_URL}/api/v4/{path}" |
| 27 | + response = requests_session().get(url, headers=gitlab_headers(), params=params) |
| 28 | + response.raise_for_status() |
| 29 | + return response.json() |
| 30 | + |
| 31 | + |
| 32 | +def search_gitlab_project_mrs( |
| 33 | + project: str, |
| 34 | + issue_key: str, |
| 35 | + *, |
| 36 | + state: MergeRequestState | None = None, |
| 37 | +): |
| 38 | + """ |
| 39 | + Searches for merge requests in a GitLab project related to an issue key. |
| 40 | +
|
| 41 | + This function queries the GitLab API and yields MergeRequest objects |
| 42 | + for each MR found that matches the search criteria. |
| 43 | +
|
| 44 | + Args: |
| 45 | + project (str): The path of the GitLab project (e.g., 'redhat/centos-stream/rpms/podman'). |
| 46 | + issue_key (str): The issue key to search for (e.g., 'RHEL-12345'). |
| 47 | + state (MergeRequestState | None, optional): If provided, filters MRs |
| 48 | + by their state (e.g., 'opened', 'merged'). Defaults to None. |
| 49 | +
|
| 50 | + Yields: |
| 51 | + MergeRequest: A data object for each matching merge request. |
| 52 | + """ |
| 53 | + logger.debug("Searching for MRs for %s in %s", issue_key, project) |
| 54 | + path = f"projects/{urlquote(project, safe='')}/merge_requests" |
| 55 | + |
| 56 | + params = {"search": issue_key, "view": "simple"} |
| 57 | + if state is not None: |
| 58 | + params["state"] = state |
| 59 | + |
| 60 | + result = gitlab_api_get(path, params=params) |
| 61 | + |
| 62 | + for mr in result: |
| 63 | + yield MergeRequest( |
| 64 | + project=project, |
| 65 | + iid=mr["iid"], |
| 66 | + url=mr["web_url"], |
| 67 | + title=mr["title"], |
| 68 | + state=mr["state"], |
| 69 | + description=mr["description"], |
| 70 | + ) |
0 commit comments