runspec-gitlab-core 0.3.0__tar.gz → 0.4.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.
- {runspec_gitlab_core-0.3.0 → runspec_gitlab_core-0.4.0}/.gitignore +3 -0
- {runspec_gitlab_core-0.3.0 → runspec_gitlab_core-0.4.0}/CHANGELOG.md +8 -0
- {runspec_gitlab_core-0.3.0 → runspec_gitlab_core-0.4.0}/PKG-INFO +1 -1
- {runspec_gitlab_core-0.3.0 → runspec_gitlab_core-0.4.0}/pyproject.toml +1 -1
- {runspec_gitlab_core-0.3.0 → runspec_gitlab_core-0.4.0}/runspec_gitlab_core/client.py +12 -9
- {runspec_gitlab_core-0.3.0 → runspec_gitlab_core-0.4.0}/tests/conftest.py +1 -1
- {runspec_gitlab_core-0.3.0 → runspec_gitlab_core-0.4.0}/tests/test_client.py +24 -0
- {runspec_gitlab_core-0.3.0 → runspec_gitlab_core-0.4.0}/runspec_gitlab_core/__init__.py +0 -0
- {runspec_gitlab_core-0.3.0 → runspec_gitlab_core-0.4.0}/runspec_gitlab_core/issues.py +0 -0
- {runspec_gitlab_core-0.3.0 → runspec_gitlab_core-0.4.0}/runspec_gitlab_core/merge_requests.py +0 -0
- {runspec_gitlab_core-0.3.0 → runspec_gitlab_core-0.4.0}/runspec_gitlab_core/pipelines.py +0 -0
- {runspec_gitlab_core-0.3.0 → runspec_gitlab_core-0.4.0}/runspec_gitlab_core/projects.py +0 -0
- {runspec_gitlab_core-0.3.0 → runspec_gitlab_core-0.4.0}/runspec_gitlab_core/repository.py +0 -0
- {runspec_gitlab_core-0.3.0 → runspec_gitlab_core-0.4.0}/tests/__init__.py +0 -0
- {runspec_gitlab_core-0.3.0 → runspec_gitlab_core-0.4.0}/tests/test_api.py +0 -0
- {runspec_gitlab_core-0.3.0 → runspec_gitlab_core-0.4.0}/tests/test_writes.py +0 -0
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `runspec-gitlab-core` are documented here.
|
|
4
4
|
|
|
5
|
+
## [0.4.0] — 2026-10-25
|
|
6
|
+
|
|
7
|
+
- `config_from_env` reads the token from `GITLAB_TOKEN` or `GITLAB_PAT` (each
|
|
8
|
+
also under the `GITLAB_<ENV>_` prefix) — the two names a runspec-console token
|
|
9
|
+
credential labelled `GitLab` sets — and takes `url` / `token` keyword
|
|
10
|
+
overrides that win over the environment.
|
|
11
|
+
- The "No token configured" error also names the console credential route.
|
|
12
|
+
|
|
5
13
|
## [0.3.0]
|
|
6
14
|
|
|
7
15
|
Write helpers, each taking a `GitlabConfig` first like the reads.
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "runspec-gitlab-core"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.4.0"
|
|
8
8
|
requires-python = ">=3.10"
|
|
9
9
|
description = "Pure-Python GitLab REST helpers — the importable core behind runspec-gitlab (no runspec dependency, no runnables)"
|
|
10
10
|
dependencies = [
|
|
@@ -7,7 +7,7 @@ credentials and call the same functions the CLI runnable's verbs call.
|
|
|
7
7
|
|
|
8
8
|
Auth is environment-variable driven (see :func:`config_from_env`) but a caller is
|
|
9
9
|
free to build a :class:`GitlabConfig` by hand. A single personal-access token
|
|
10
|
-
(``GITLAB_TOKEN``) is sent as the ``PRIVATE-TOKEN`` header; the instance URL
|
|
10
|
+
(``GITLAB_TOKEN`` or ``GITLAB_PAT``) is sent as the ``PRIVATE-TOKEN`` header; the instance URL
|
|
11
11
|
(``GITLAB_URL``) defaults to ``https://gitlab.com`` for the SaaS case.
|
|
12
12
|
|
|
13
13
|
This mirrors the read tools of GitLab's own (hosted) MCP server, but ports them
|
|
@@ -65,13 +65,16 @@ def _env_first(names: list[str]) -> str | None:
|
|
|
65
65
|
return None
|
|
66
66
|
|
|
67
67
|
|
|
68
|
-
def config_from_env(env: str | None = None) -> GitlabConfig:
|
|
68
|
+
def config_from_env(env: str | None = None, *, url: str | None = None, token: str | None = None) -> GitlabConfig:
|
|
69
69
|
"""Build a :class:`GitlabConfig` from environment variables.
|
|
70
70
|
|
|
71
71
|
When ``env`` (or the ``GITLAB_ENV`` variable) selects dev/uat/prod, the
|
|
72
72
|
environment-prefixed variables are read first (e.g. ``GITLAB_UAT_TOKEN``),
|
|
73
73
|
falling back to the unprefixed ``GITLAB_*`` family for single-instance
|
|
74
|
-
setups. ``
|
|
74
|
+
setups. The token is read from ``GITLAB_TOKEN`` or ``GITLAB_PAT`` (the two
|
|
75
|
+
names a runspec-console token credential labelled ``GitLab`` sets).
|
|
76
|
+
``GITLAB_URL`` defaults to ``https://gitlab.com`` when unset. Explicit
|
|
77
|
+
``url`` / ``token`` arguments win over the environment. Raises
|
|
75
78
|
:class:`GitlabError` with an actionable message when the env label is invalid
|
|
76
79
|
or the token is missing.
|
|
77
80
|
"""
|
|
@@ -81,19 +84,19 @@ def config_from_env(env: str | None = None) -> GitlabConfig:
|
|
|
81
84
|
if env not in VALID_ENVS:
|
|
82
85
|
raise GitlabError(f"Invalid env {env!r} — expected one of {', '.join(VALID_ENVS)}")
|
|
83
86
|
|
|
84
|
-
def lookup(
|
|
87
|
+
def lookup(*suffixes: str) -> str | None:
|
|
85
88
|
names = []
|
|
86
89
|
if env:
|
|
87
|
-
names
|
|
88
|
-
names
|
|
90
|
+
names += [f"GITLAB_{env.upper()}_{suffix}" for suffix in suffixes]
|
|
91
|
+
names += [f"GITLAB_{suffix}" for suffix in suffixes]
|
|
89
92
|
return _env_first(names)
|
|
90
93
|
|
|
91
|
-
token = lookup("TOKEN")
|
|
94
|
+
token = token or lookup("TOKEN", "PAT")
|
|
92
95
|
if not token:
|
|
93
96
|
hint = f"GITLAB_{env.upper()}_TOKEN" if env else "GITLAB_TOKEN"
|
|
94
|
-
raise GitlabError(f"No token configured — set {hint} (a GitLab personal access token)")
|
|
97
|
+
raise GitlabError(f"No token configured — set {hint} (a GitLab personal access token), or add a runspec-console token credential labelled GitLab")
|
|
95
98
|
|
|
96
|
-
base_url = lookup("URL") or DEFAULT_URL
|
|
99
|
+
base_url = url or lookup("URL") or DEFAULT_URL
|
|
97
100
|
|
|
98
101
|
return GitlabConfig(
|
|
99
102
|
base_url=base_url.rstrip("/"),
|
|
@@ -9,7 +9,7 @@ import pytest
|
|
|
9
9
|
|
|
10
10
|
from runspec_gitlab_core import client as client_mod
|
|
11
11
|
|
|
12
|
-
_SUFFIXES = ("URL", "TOKEN", "PROJECT")
|
|
12
|
+
_SUFFIXES = ("URL", "TOKEN", "PAT", "PROJECT")
|
|
13
13
|
_ALL_VARS = ["GITLAB_ENV"] + [f"GITLAB_{s}" for s in _SUFFIXES]
|
|
14
14
|
for _env in ("DEV", "UAT", "PROD"):
|
|
15
15
|
_ALL_VARS += [f"GITLAB_{_env}_{s}" for s in _SUFFIXES]
|
|
@@ -68,6 +68,30 @@ def test_missing_token_raises(monkeypatch):
|
|
|
68
68
|
# ── encode_project ──────────────────────────────────────────────────────────
|
|
69
69
|
|
|
70
70
|
|
|
71
|
+
def test_token_read_from_gitlab_pat(monkeypatch):
|
|
72
|
+
# A runspec-console token credential labelled "GitLab" sets GITLAB_TOKEN and GITLAB_PAT.
|
|
73
|
+
monkeypatch.setenv("GITLAB_PAT", "pat-tok")
|
|
74
|
+
assert config_from_env().token == "pat-tok"
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def test_env_prefixed_pat_beats_unprefixed_token(monkeypatch):
|
|
78
|
+
monkeypatch.setenv("GITLAB_TOKEN", "shared")
|
|
79
|
+
monkeypatch.setenv("GITLAB_UAT_PAT", "uat-pat")
|
|
80
|
+
assert config_from_env(env="uat").token == "uat-pat"
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def test_explicit_url_and_token_win(monkeypatch):
|
|
84
|
+
monkeypatch.setenv("GITLAB_TOKEN", "env-tok")
|
|
85
|
+
monkeypatch.setenv("GITLAB_URL", "https://env.example.com")
|
|
86
|
+
cfg = config_from_env(url="https://cli.example.com/", token="cli-tok")
|
|
87
|
+
assert (cfg.base_url, cfg.token) == ("https://cli.example.com", "cli-tok")
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def test_missing_token_names_the_console_credential(monkeypatch):
|
|
91
|
+
with pytest.raises(GitlabError, match="credential labelled GitLab"):
|
|
92
|
+
config_from_env()
|
|
93
|
+
|
|
94
|
+
|
|
71
95
|
def test_encode_project_path():
|
|
72
96
|
assert encode_project("group/sub/app") == "group%2Fsub%2Fapp"
|
|
73
97
|
|
|
File without changes
|
|
File without changes
|
{runspec_gitlab_core-0.3.0 → runspec_gitlab_core-0.4.0}/runspec_gitlab_core/merge_requests.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|