runspec-gitlab-core 0.4.0__tar.gz → 0.6.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.4.0 → runspec_gitlab_core-0.6.0}/CHANGELOG.md +18 -0
- {runspec_gitlab_core-0.4.0 → runspec_gitlab_core-0.6.0}/PKG-INFO +1 -1
- {runspec_gitlab_core-0.4.0 → runspec_gitlab_core-0.6.0}/pyproject.toml +1 -1
- {runspec_gitlab_core-0.4.0 → runspec_gitlab_core-0.6.0}/runspec_gitlab_core/__init__.py +9 -1
- {runspec_gitlab_core-0.4.0 → runspec_gitlab_core-0.6.0}/runspec_gitlab_core/projects.py +49 -14
- {runspec_gitlab_core-0.4.0 → runspec_gitlab_core-0.6.0}/tests/test_api.py +36 -0
- {runspec_gitlab_core-0.4.0 → runspec_gitlab_core-0.6.0}/.gitignore +0 -0
- {runspec_gitlab_core-0.4.0 → runspec_gitlab_core-0.6.0}/runspec_gitlab_core/client.py +0 -0
- {runspec_gitlab_core-0.4.0 → runspec_gitlab_core-0.6.0}/runspec_gitlab_core/issues.py +0 -0
- {runspec_gitlab_core-0.4.0 → runspec_gitlab_core-0.6.0}/runspec_gitlab_core/merge_requests.py +0 -0
- {runspec_gitlab_core-0.4.0 → runspec_gitlab_core-0.6.0}/runspec_gitlab_core/pipelines.py +0 -0
- {runspec_gitlab_core-0.4.0 → runspec_gitlab_core-0.6.0}/runspec_gitlab_core/repository.py +0 -0
- {runspec_gitlab_core-0.4.0 → runspec_gitlab_core-0.6.0}/tests/__init__.py +0 -0
- {runspec_gitlab_core-0.4.0 → runspec_gitlab_core-0.6.0}/tests/conftest.py +0 -0
- {runspec_gitlab_core-0.4.0 → runspec_gitlab_core-0.6.0}/tests/test_client.py +0 -0
- {runspec_gitlab_core-0.4.0 → runspec_gitlab_core-0.6.0}/tests/test_writes.py +0 -0
|
@@ -2,6 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `runspec-gitlab-core` are documented here.
|
|
4
4
|
|
|
5
|
+
## [0.6.0] — 2026-10-25
|
|
6
|
+
|
|
7
|
+
- New `list_projects`: the token user's member (or owned) projects, optionally
|
|
8
|
+
filtered by a term that also matches the namespace path, in GitLab's short
|
|
9
|
+
form unless `full`.
|
|
10
|
+
- `search_projects` adds the namespace match (`search_namespaces`) only within
|
|
11
|
+
the user's own projects. Across every visible project it made gitlab.com
|
|
12
|
+
time out with a 500 after about 16 seconds (0.5.0 regression). New `simple`
|
|
13
|
+
parameter.
|
|
14
|
+
|
|
15
|
+
## [0.5.0] — 2026-10-25
|
|
16
|
+
|
|
17
|
+
- `search_projects` can list the token user's projects: `search` is now
|
|
18
|
+
optional, and with no term the call asks for member projects only (listing
|
|
19
|
+
every visible project on gitlab.com is no use). A term also matches the
|
|
20
|
+
group/namespace path (`search_namespaces`), so a username or group name finds
|
|
21
|
+
the projects under it. New `owned` parameter limits results to owned projects.
|
|
22
|
+
|
|
5
23
|
## [0.4.0] — 2026-10-25
|
|
6
24
|
|
|
7
25
|
- `config_from_env` reads the token from `GITLAB_TOKEN` or `GITLAB_PAT` (each
|
|
@@ -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.6.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 = [
|
|
@@ -56,7 +56,14 @@ from runspec_gitlab_core.pipelines import (
|
|
|
56
56
|
retry_job,
|
|
57
57
|
retry_pipeline,
|
|
58
58
|
)
|
|
59
|
-
from runspec_gitlab_core.projects import
|
|
59
|
+
from runspec_gitlab_core.projects import (
|
|
60
|
+
get_project,
|
|
61
|
+
list_projects,
|
|
62
|
+
resolve_project_path,
|
|
63
|
+
resolve_user_ids,
|
|
64
|
+
search_projects,
|
|
65
|
+
whoami,
|
|
66
|
+
)
|
|
60
67
|
from runspec_gitlab_core.repository import (
|
|
61
68
|
create_branch,
|
|
62
69
|
delete_branch,
|
|
@@ -80,6 +87,7 @@ __all__ = [
|
|
|
80
87
|
# identity / projects
|
|
81
88
|
"whoami",
|
|
82
89
|
"get_project",
|
|
90
|
+
"list_projects",
|
|
83
91
|
"search_projects",
|
|
84
92
|
# issues
|
|
85
93
|
"list_issues",
|
|
@@ -47,26 +47,61 @@ def get_project(config: GitlabConfig, project: str | None = None) -> dict[str, A
|
|
|
47
47
|
|
|
48
48
|
def search_projects(
|
|
49
49
|
config: GitlabConfig,
|
|
50
|
-
search: str,
|
|
50
|
+
search: str | None = None,
|
|
51
51
|
membership: bool = False,
|
|
52
52
|
per_page: int = 20,
|
|
53
53
|
page: int = 1,
|
|
54
|
+
owned: bool = False,
|
|
55
|
+
simple: bool = False,
|
|
54
56
|
) -> list[dict[str, Any]]:
|
|
55
|
-
"""Search
|
|
57
|
+
"""Search or list projects, most recently active first.
|
|
58
|
+
|
|
59
|
+
``search`` matches the project name or path. GitLab matches a term shorter
|
|
60
|
+
than 3 characters only as an exact name. With no ``search`` the call lists
|
|
61
|
+
the token user's projects: ``membership`` is implied, since listing every
|
|
62
|
+
visible project on a public instance is useless. ``owned`` limits results
|
|
63
|
+
to projects the user owns. Within the user's own projects (``membership``
|
|
64
|
+
or ``owned``) a term also matches the group/namespace path; across every
|
|
65
|
+
visible project that match times out on gitlab.com, so it is left off.
|
|
66
|
+
``simple`` asks GitLab for its short project representation.
|
|
67
|
+
"""
|
|
68
|
+
mine = membership or owned or not search
|
|
69
|
+
params: dict[str, Any] = {
|
|
70
|
+
"membership": mine or None,
|
|
71
|
+
"owned": owned or None,
|
|
72
|
+
"simple": simple or None,
|
|
73
|
+
"order_by": "last_activity_at",
|
|
74
|
+
"per_page": per_page,
|
|
75
|
+
"page": page,
|
|
76
|
+
}
|
|
77
|
+
if search:
|
|
78
|
+
params["search"] = search
|
|
79
|
+
if mine:
|
|
80
|
+
params["search_namespaces"] = True
|
|
81
|
+
return gitlab_request("GET", "/projects", config=config, params=params)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def list_projects(
|
|
85
|
+
config: GitlabConfig,
|
|
86
|
+
search: str | None = None,
|
|
87
|
+
owned: bool = False,
|
|
88
|
+
per_page: int = 20,
|
|
89
|
+
page: int = 1,
|
|
90
|
+
full: bool = False,
|
|
91
|
+
) -> list[dict[str, Any]]:
|
|
92
|
+
"""List the projects the token user is a member of (or owns), most recently
|
|
93
|
+
active first, optionally filtered by ``search`` (name, path or namespace).
|
|
56
94
|
|
|
57
|
-
|
|
95
|
+
Returns GitLab's short project representation unless ``full``.
|
|
58
96
|
"""
|
|
59
|
-
return
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
"per_page": per_page,
|
|
68
|
-
"page": page,
|
|
69
|
-
},
|
|
97
|
+
return search_projects(
|
|
98
|
+
config,
|
|
99
|
+
search=search,
|
|
100
|
+
membership=True,
|
|
101
|
+
per_page=per_page,
|
|
102
|
+
page=page,
|
|
103
|
+
owned=owned,
|
|
104
|
+
simple=not full,
|
|
70
105
|
)
|
|
71
106
|
|
|
72
107
|
|
|
@@ -19,6 +19,7 @@ from runspec_gitlab_core import (
|
|
|
19
19
|
get_merge_request_pipelines,
|
|
20
20
|
list_issues,
|
|
21
21
|
list_pipelines,
|
|
22
|
+
list_projects,
|
|
22
23
|
list_tree,
|
|
23
24
|
search_projects,
|
|
24
25
|
whoami,
|
|
@@ -53,6 +54,41 @@ def test_search_projects_encodes_membership(monkeypatch):
|
|
|
53
54
|
assert seen["path"] == "/api/v4/projects"
|
|
54
55
|
assert seen["query"]["search"] == "runspec"
|
|
55
56
|
assert seen["query"]["membership"] == "true"
|
|
57
|
+
assert seen["query"]["search_namespaces"] == "true"
|
|
58
|
+
assert "owned" not in seen["query"]
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def test_search_projects_without_term_lists_member_projects(monkeypatch):
|
|
62
|
+
seen = _capture(monkeypatch, httpx.Response(200, json=[]))
|
|
63
|
+
search_projects(CFG)
|
|
64
|
+
assert seen["query"]["membership"] == "true"
|
|
65
|
+
assert "search" not in seen["query"]
|
|
66
|
+
assert "search_namespaces" not in seen["query"]
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def test_search_projects_plain_term_searches_everything_by_name(monkeypatch):
|
|
70
|
+
# search_namespaces across every public gitlab.com project times out (500)
|
|
71
|
+
seen = _capture(monkeypatch, httpx.Response(200, json=[]))
|
|
72
|
+
search_projects(CFG, "runspec")
|
|
73
|
+
assert seen["query"]["search"] == "runspec"
|
|
74
|
+
assert "membership" not in seen["query"]
|
|
75
|
+
assert "search_namespaces" not in seen["query"]
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def test_list_projects_is_mine_and_short(monkeypatch):
|
|
79
|
+
seen = _capture(monkeypatch, httpx.Response(200, json=[]))
|
|
80
|
+
list_projects(CFG, "cli", owned=True)
|
|
81
|
+
assert seen["query"]["membership"] == "true"
|
|
82
|
+
assert seen["query"]["owned"] == "true"
|
|
83
|
+
assert seen["query"]["simple"] == "true"
|
|
84
|
+
assert seen["query"]["search_namespaces"] == "true"
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def test_list_projects_full(monkeypatch):
|
|
88
|
+
seen = _capture(monkeypatch, httpx.Response(200, json=[]))
|
|
89
|
+
list_projects(CFG, full=True)
|
|
90
|
+
assert "simple" not in seen["query"]
|
|
91
|
+
assert "search" not in seen["query"]
|
|
56
92
|
|
|
57
93
|
|
|
58
94
|
def test_list_issues_uses_default_project_and_filters(monkeypatch):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{runspec_gitlab_core-0.4.0 → runspec_gitlab_core-0.6.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
|