Coverage for src / mafw / devtools / gitlab / api.py: 100%
33 statements
« prev ^ index » next coverage.py v7.14.0, created at 2026-06-28 13:34 +0000
« prev ^ index » next coverage.py v7.14.0, created at 2026-06-28 13:34 +0000
1# Copyright 2026 European Union
2# Author: Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)
3# SPDX-License-Identifier: EUPL-1.2
4"""
5GitLab API configuration and authentication helpers.
7:author: Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)
8"""
10from __future__ import annotations
12import os
13from dataclasses import dataclass
14from typing import Literal, MutableMapping
17@dataclass(frozen=True, slots=True)
18class GitlabAPIConfiguration:
19 """Configuration needed to communicate with the GitLab API.
21 :param api_url: Base GitLab API v4 URL.
22 :type api_url: str
23 :param on_ci: Whether the process runs on GitLab CI.
24 :type on_ci: bool
25 :param project_id: GitLab project numeric ID.
26 :type project_id: int
27 :param token: Authentication token value.
28 :type token: str
29 :param token_type: Token kind used for authentication.
30 :type token_type: Literal['job_token', 'api_token']
31 """
33 api_url: str
34 on_ci: bool
35 project_id: int
36 token: str
37 token_type: Literal['job_token', 'api_token']
40def build_gitlab_api_configuration(
41 api_url: str | None, project_id: int | None, token: str | None
42) -> GitlabAPIConfiguration:
43 """Build a GitLab API configuration from provided values and environment context.
45 :param api_url: Optional override for the GitLab API URL.
46 :type api_url: str | None
47 :param project_id: Optional override for the GitLab project ID.
48 :type project_id: int | None
49 :param token: Optional override for the authentication token.
50 :type token: str | None
51 :return: The validated GitLab API configuration.
52 :rtype: GitlabAPIConfiguration
53 :raises ValueError: If any required configuration value is missing.
54 """
55 if api_url is None:
56 api_url = os.environ.get('CI_API_V4_URL')
57 if project_id is None:
58 project_id_env = os.environ.get('CI_PROJECT_ID')
59 project_id = int(project_id_env) if project_id_env else None
60 if token is None:
61 token = os.environ.get('CI_JOB_TOKEN')
63 missing: list[str] = []
64 if not api_url:
65 missing.append('api_url')
66 if project_id is None:
67 missing.append('project_id')
68 if not token:
69 missing.append('token')
71 if missing or api_url is None or project_id is None or token is None:
72 raise ValueError(f'Missing GitLab configuration values: {", ".join(missing)}')
74 return GitlabAPIConfiguration(
75 api_url=api_url,
76 on_ci=bool(os.environ.get('CI')),
77 project_id=project_id,
78 token=token,
79 token_type='job_token' if bool(os.environ.get('CI')) else 'api_token',
80 )
83def build_gitlab_auth_headers(api_config: GitlabAPIConfiguration) -> MutableMapping[str, str | bytes]:
84 """Build authentication headers for GitLab API requests.
86 :param api_config: The GitLab API configuration.
87 :type api_config: GitlabAPIConfiguration
88 :return: A mutable mapping of HTTP headers.
89 :rtype: MutableMapping[str, str | bytes]
90 """
91 if api_config.on_ci:
92 return {'JOB-TOKEN': api_config.token}
93 return {'PRIVATE-TOKEN': api_config.token}