gitlab_mr_check 1.4.2__tar.gz → 1.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitlab_mr_check
3
- Version: 1.4.2
3
+ Version: 1.5.0
4
4
  Summary: GitLab Merge Request 4-Eyes Approval Audit Tool
5
5
  Author: Yorick Hoorneman
6
6
  Author-email: Yorick Hoorneman <yhoorneman@schubergphilis.com>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "gitlab_mr_check"
3
- version = "1.4.2"
3
+ version = "1.5.0"
4
4
  description = "GitLab Merge Request 4-Eyes Approval Audit Tool"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -63,13 +63,13 @@ test = [
63
63
  # Pin uv to match [tool.uv] required-version — tox-uv depends on the uv
64
64
  # Python package, which installs a uv binary into .venv/bin that would
65
65
  # otherwise shadow the image's /usr/local/bin/uv and break the check.
66
- "uv==0.11.7",
66
+ "uv==0.11.16",
67
67
  "tox>=4.21",
68
68
  "tox-uv>=1.16",
69
69
  ]
70
70
 
71
71
  [build-system]
72
- requires = ["uv_build>=0.8.15,<=0.11.7"]
72
+ requires = ["uv_build>=0.8.15,<=0.11.16"]
73
73
  build-backend = "uv_build"
74
74
 
75
75
  [tool.pyscn.complexity]
@@ -274,7 +274,7 @@ directory = "reports/coverage"
274
274
 
275
275
 
276
276
  [tool.uv]
277
- required-version = "==0.11.7"
277
+ required-version = "==0.11.16"
278
278
  exclude-newer = "1 week"
279
279
 
280
280
  [tool.tox]
@@ -294,6 +294,6 @@ commands = [["pytest", { replace = "posargs", default = [], extend = true }]]
294
294
  # strings below are kept consistent with that version by hand (uv is mentioned in each).
295
295
  # `alpine-image` is mirrored literally in .gitlab-ci.yml's variables: block — GitLab
296
296
  # cannot evaluate `image:` from pyproject at pipeline-creation time.
297
- base-image = "ghcr.io/astral-sh/uv:0.11.7-python3.13-trixie-slim"
298
- uv-image = "ghcr.io/astral-sh/uv:0.11.7"
299
- alpine-image = "ghcr.io/astral-sh/uv:0.11.7-alpine3.22"
297
+ base-image = "ghcr.io/astral-sh/uv:0.11.16-python3.13-trixie-slim"
298
+ uv-image = "ghcr.io/astral-sh/uv:0.11.16"
299
+ alpine-image = "ghcr.io/astral-sh/uv:0.11.16-alpine3.22"
@@ -18,7 +18,6 @@
18
18
  import logging
19
19
  from dataclasses import asdict, dataclass, field
20
20
  from datetime import datetime
21
- from functools import partial
22
21
  from typing import Any
23
22
 
24
23
  import gitlab
@@ -138,14 +137,14 @@ def mr_updated_in_years(mr: gitlab.v4.objects.ProjectMergeRequest, years: list[i
138
137
  return datetime.fromisoformat(mr.updated_at).year in years
139
138
 
140
139
 
141
- def get_mrs_by_project(project: gitlab.v4.objects.Project, filters: list[Any]) -> list[Any]:
142
- """Return all MRs from a project that pass every filter predicate."""
143
- return [mr for mr in project.mergerequests.list(all=True) if all(f(mr) for f in filters)]
140
+ def get_mrs_by_project(project: gitlab.v4.objects.Project, **list_kwargs: Any) -> list[Any]: # noqa: ANN401
141
+ """Return all MRs from a project matching the given server-side list filters."""
142
+ return list(project.mergerequests.list(**list_kwargs))
144
143
 
145
144
 
146
- def get_mrs_by_projects(projects: list[tuple[str, Any]], filters: list[Any]) -> dict[str, list[Any]]:
147
- """Return a mapping of project name to filtered MR list for each (name, project) pair."""
148
- return {name: get_mrs_by_project(project, filters) for name, project in projects}
145
+ def get_mrs_by_projects(projects: list[tuple[str, Any]], **list_kwargs: Any) -> dict[str, list[Any]]: # noqa: ANN401
146
+ """Return a mapping of project name to MR list using the given server-side list filters."""
147
+ return {name: get_mrs_by_project(project, **list_kwargs) for name, project in projects}
149
148
 
150
149
 
151
150
  def evaluate_mrs_4eyes_per_project(project_mrs: dict[str, list[Any]]) -> list[ProjectMRAuditResult]:
@@ -178,7 +177,7 @@ def audit(url: str, token: str, config: Config) -> list[ProjectMRAuditResult]:
178
177
  List of per-project audit results, sorted by pass status, with empty projects excluded.
179
178
  """
180
179
  LOGGER.info('Starting audit validation for GitLab Merge Requests 4-eyes approval')
181
- gl = gitlab.Gitlab(url, token)
180
+ gl = gitlab.Gitlab(url, token, retry_transient_errors=True, timeout=60)
182
181
 
183
182
  LOGGER.info('Getting the groups recursively')
184
183
  gl_groups = []
@@ -198,9 +197,14 @@ def audit(url: str, token: str, config: Config) -> list[ProjectMRAuditResult]:
198
197
  LOGGER.info('Found %d project(s)', len(gl_projects))
199
198
 
200
199
  LOGGER.info('Getting the merge requests under the projects')
200
+ years = config.gitlab.audit.years
201
201
  gl_project_mrs = get_mrs_by_projects(
202
202
  projects=gl_projects,
203
- filters=[mr_is_merged, partial(mr_updated_in_years, years=config.gitlab.audit.years)],
203
+ state='merged',
204
+ updated_after=f'{min(years)}-01-01T00:00:00Z',
205
+ updated_before=f'{max(years) + 1}-01-01T00:00:00Z',
206
+ iterator=True,
207
+ per_page=50,
204
208
  )
205
209
 
206
210
  LOGGER.info('Evaluating merge requests for 4-eyes approval')
File without changes