gitlab-api 27.3.5__tar.gz → 27.3.6__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.
Files changed (93) hide show
  1. {gitlab_api-27.3.5/gitlab_api.egg-info → gitlab_api-27.3.6}/PKG-INFO +2 -2
  2. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/README.md +1 -1
  3. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/mcp_server.py +1 -1
  4. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/ontology/gitlab.ttl +5 -0
  5. {gitlab_api-27.3.5 → gitlab_api-27.3.6/gitlab_api.egg-info}/PKG-INFO +2 -2
  6. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api.egg-info/SOURCES.txt +1 -0
  7. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/pyproject.toml +1 -1
  8. gitlab_api-27.3.6/tests/test_ontology_parent_link.py +115 -0
  9. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/LICENSE +0 -0
  10. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/MANIFEST.in +0 -0
  11. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/__init__.py +0 -0
  12. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/__main__.py +0 -0
  13. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/api/__init__.py +0 -0
  14. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/api/api_client_base.py +0 -0
  15. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/api/api_client_environments.py +0 -0
  16. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/api/api_client_issues.py +0 -0
  17. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/api/api_client_merge_requests.py +0 -0
  18. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/api/api_client_other.py +0 -0
  19. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/api/api_client_pipelines.py +0 -0
  20. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/api/api_client_projects.py +0 -0
  21. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/api/api_client_repositories.py +0 -0
  22. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/api/api_client_system.py +0 -0
  23. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/api/api_client_users_groups.py +0 -0
  24. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/api/api_client_vulnerabilities.py +0 -0
  25. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/api_client.py +0 -0
  26. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/auth.py +0 -0
  27. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/connector_manifest.yml +0 -0
  28. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/connector_prep.py +0 -0
  29. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/connectors/__init__.py +0 -0
  30. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/connectors/mcp_source_presets.json +0 -0
  31. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/connectors/tool_schema_fingerprints.json +0 -0
  32. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/gitlab_gql.py +0 -0
  33. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/gitlab_input_models.py +0 -0
  34. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/gitlab_response_models.py +0 -0
  35. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/instances.py +0 -0
  36. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/kg_ingest.py +0 -0
  37. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/mcp_config.json +0 -0
  38. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/ontology/__init__.py +0 -0
  39. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/ontology/certification.json +0 -0
  40. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/ontology/fixtures/records.json +0 -0
  41. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/ontology/ingest_sources.json +0 -0
  42. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/ontology/mappings/source.yaml +0 -0
  43. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/ontology/migrations/manifest.json +0 -0
  44. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/ontology/shapes/connector.shacl.ttl +0 -0
  45. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/prompts/__init__.py +0 -0
  46. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/prompts/devops_specialist.json +0 -0
  47. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/skills/__init__.py +0 -0
  48. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/skills/gitlab-api-operations/SKILL.md +0 -0
  49. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/skills/gitlab-api-operations/agents/openai.yaml +0 -0
  50. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/skills/gitlab-api-operations/references/catalog.md +0 -0
  51. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/skills/gitlab-issues/SKILL.md +0 -0
  52. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/skills/gitlab-issues/WORKFLOW.md +0 -0
  53. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/skills/gitlab-merge-request-create/SKILL.md +0 -0
  54. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/skills/gitlab-merge-request-create/WORKFLOW.md +0 -0
  55. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/skills/gitlab-merge-request-review/SKILL.md +0 -0
  56. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/skills/gitlab-merge-request-review/WORKFLOW.md +0 -0
  57. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/skills/gitlab-pipelines/SKILL.md +0 -0
  58. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/skills/gitlab-pipelines/WORKFLOW.md +0 -0
  59. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/skills/gitlab-vulnerabilities/SKILL.md +0 -0
  60. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api/skills/gitlab-vulnerabilities/WORKFLOW.md +0 -0
  61. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api.egg-info/dependency_links.txt +0 -0
  62. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api.egg-info/entry_points.txt +0 -0
  63. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api.egg-info/requires.txt +0 -0
  64. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/gitlab_api.egg-info/top_level.txt +0 -0
  65. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/requirements.txt +0 -0
  66. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/scripts/check_import_safety.py +0 -0
  67. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/scripts/security_contract.py +0 -0
  68. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/scripts/security_sanitizer.py +0 -0
  69. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/scripts/verify_api_integration.py +0 -0
  70. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/setup.cfg +0 -0
  71. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/__init__.py +0 -0
  72. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/conftest.py +0 -0
  73. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/test_api_wrapper.py +0 -0
  74. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/test_auth.py +0 -0
  75. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/test_connector_prep.py +0 -0
  76. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/test_default_content_surfaces.py +0 -0
  77. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/test_fleet_name.py +0 -0
  78. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/test_gitlab_a2a_validation.py +0 -0
  79. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/test_gitlab_api_brute_force_coverage.py +0 -0
  80. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/test_gitlab_gql.py +0 -0
  81. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/test_gitlab_mcp_validation.py +0 -0
  82. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/test_gitlab_models.py +0 -0
  83. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/test_identity_context_scoping.py +0 -0
  84. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/test_ingest_sources.py +0 -0
  85. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/test_init_dynamics.py +0 -0
  86. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/test_instances.py +0 -0
  87. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/test_kg_ingest.py +0 -0
  88. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/test_mock_coverage.py +0 -0
  89. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/test_security_sanitizer.py +0 -0
  90. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/test_startup.py +0 -0
  91. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/test_tool_modes.py +0 -0
  92. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/test_verify_agent.py +0 -0
  93. {gitlab_api-27.3.5 → gitlab_api-27.3.6}/tests/verify_a2a_queries.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitlab-api
3
- Version: 27.3.5
3
+ Version: 27.3.6
4
4
  Summary: GitLab API + MCP Server
5
5
  Author-email: Project Maintainers <maintainers@users.noreply.github.com>
6
6
  License: MIT
@@ -45,7 +45,7 @@ Dynamic: license-file
45
45
  ![PyPI - Wheel](https://img.shields.io/pypi/wheel/gitlab-api)
46
46
  ![PyPI - Implementation](https://img.shields.io/pypi/implementation/gitlab-api)
47
47
 
48
- *Version: 27.3.5*
48
+ *Version: 27.3.6*
49
49
 
50
50
  > **Documentation** — Installation, deployment, usage across the API, CLI, and MCP
51
51
  > backing GitLab instance are maintained in the
@@ -20,7 +20,7 @@
20
20
  ![PyPI - Wheel](https://img.shields.io/pypi/wheel/gitlab-api)
21
21
  ![PyPI - Implementation](https://img.shields.io/pypi/implementation/gitlab-api)
22
22
 
23
- *Version: 27.3.5*
23
+ *Version: 27.3.6*
24
24
 
25
25
  > **Documentation** — Installation, deployment, usage across the API, CLI, and MCP
26
26
  > backing GitLab instance are maintained in the
@@ -35,7 +35,7 @@ from agent_connector_sdk.mcp.tool_surface import register_tool_surface
35
35
  from gitlab_api.api_client import Api
36
36
  from gitlab_api.auth import get_client
37
37
 
38
- __version__ = "27.3.5"
38
+ __version__ = "27.3.6"
39
39
  print(f"Gitlab MCP v{__version__}", file=sys.stderr)
40
40
 
41
41
  logger = get_logger(name="mcp_server")
@@ -12,10 +12,12 @@
12
12
  # / gitlab_pipelines / gitlab_issues / …).
13
13
 
14
14
  :GitLabGroup a owl:Class ;
15
+ rdfs:subClassOf :IdentityGroup ;
15
16
  rdfs:label "GitLab Group" ;
16
17
  rdfs:comment "A namespace that owns projects and subgroups (gitlab_groups)." .
17
18
 
18
19
  :Project a owl:Class ;
20
+ rdfs:subClassOf :SoftwareProject ;
19
21
  rdfs:label "Project" ;
20
22
  rdfs:comment "A GitLab project / repository (gitlab_projects)." .
21
23
 
@@ -24,6 +26,7 @@
24
26
  rdfs:comment "A proposed change under review, from a source to a target branch (gitlab_merge_requests)." .
25
27
 
26
28
  :Pipeline a owl:Class ;
29
+ rdfs:subClassOf :PipelineRun ;
27
30
  rdfs:label "Pipeline" ;
28
31
  rdfs:comment "A CI/CD pipeline run for a commit/ref (gitlab_pipelines)." .
29
32
 
@@ -47,10 +50,12 @@
47
50
  owl:equivalentClass :Job .
48
51
 
49
52
  :Issue a owl:Class ;
53
+ rdfs:subClassOf :WorkItem ;
50
54
  rdfs:label "Issue" ;
51
55
  rdfs:comment "A tracked work item or defect (gitlab_issues)." .
52
56
 
53
57
  :Epic a owl:Class ;
58
+ rdfs:subClassOf :WorkItem ;
54
59
  rdfs:label "Epic" ;
55
60
  rdfs:comment "A group-level container aggregating related issues (gitlab_epics)." .
56
61
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitlab-api
3
- Version: 27.3.5
3
+ Version: 27.3.6
4
4
  Summary: GitLab API + MCP Server
5
5
  Author-email: Project Maintainers <maintainers@users.noreply.github.com>
6
6
  License: MIT
@@ -45,7 +45,7 @@ Dynamic: license-file
45
45
  ![PyPI - Wheel](https://img.shields.io/pypi/wheel/gitlab-api)
46
46
  ![PyPI - Implementation](https://img.shields.io/pypi/implementation/gitlab-api)
47
47
 
48
- *Version: 27.3.5*
48
+ *Version: 27.3.6*
49
49
 
50
50
  > **Documentation** — Installation, deployment, usage across the API, CLI, and MCP
51
51
  > backing GitLab instance are maintained in the
@@ -83,6 +83,7 @@ tests/test_init_dynamics.py
83
83
  tests/test_instances.py
84
84
  tests/test_kg_ingest.py
85
85
  tests/test_mock_coverage.py
86
+ tests/test_ontology_parent_link.py
86
87
  tests/test_security_sanitizer.py
87
88
  tests/test_startup.py
88
89
  tests/test_tool_modes.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "gitlab-api"
7
- version = "27.3.5"
7
+ version = "27.3.6"
8
8
  description = "GitLab API + MCP Server"
9
9
  readme = "README.md"
10
10
  classifiers = [ "Development Status :: 5 - Production/Stable", "License :: OSI Approved :: MIT License", "Environment :: Console", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3",]
@@ -0,0 +1,115 @@
1
+ """Every class of the packaged ontology reaches an epistemic-graph parent class (CONN-GITLAB-API-CONNECTOR-CONTENT-R002)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import re
6
+ from pathlib import Path
7
+
8
+ import pytest
9
+
10
+ pytestmark = pytest.mark.spec("CONN-GITLAB-API-CONNECTOR-CONTENT-R002")
11
+
12
+ PARENT_IRI = "http://knuckles.team/kg"
13
+ ONTOLOGIES = sorted(
14
+ (Path(__file__).resolve().parents[1] / "gitlab_api" / "ontology").glob("*.ttl")
15
+ )
16
+ OWL = "http://www.w3.org/2002/07/owl#"
17
+ RDF_TYPE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
18
+ SUBCLASS = "http://www.w3.org/2000/01/rdf-schema#subClassOf"
19
+ # Parent classes of the epistemic-graph ontology that this connector links to or redeclares.
20
+ PARENT_CLASSES = frozenset(
21
+ (
22
+ "http://knuckles.team/kg#Commit",
23
+ "http://knuckles.team/kg#IdentityGroup",
24
+ "http://knuckles.team/kg#MergeRequest",
25
+ "http://knuckles.team/kg#Person",
26
+ "http://knuckles.team/kg#PipelineRun",
27
+ "http://knuckles.team/kg#SoftwareProject",
28
+ "http://knuckles.team/kg#WorkItem",
29
+ )
30
+ )
31
+ # Classes for which the parent ontology has no fitting class yet. Each is a candidate for a new
32
+ # parent class (see the orphan mapping report); a class leaves this set when it gains a parent.
33
+ PENDING_NEW_PARENT: frozenset[str] = frozenset(
34
+ (
35
+ "http://knuckles.team/kg#Branch",
36
+ "http://knuckles.team/kg#CheckRun",
37
+ "http://knuckles.team/kg#Job",
38
+ "http://knuckles.team/kg#Milestone",
39
+ "http://knuckles.team/kg#Release",
40
+ "http://knuckles.team/kg#Runner",
41
+ )
42
+ )
43
+
44
+ _STRING = re.compile(r'"""(?:.|\n)*?"""|"(?:[^"\\\n]|\\.)*"')
45
+ _IRI = re.compile(r"<([^<>\s]*)>")
46
+ _PREFIX = re.compile(r"(?im)^\s*@?prefix\s+([A-Za-z][\w.-]*)?:\s+\x00(\d+)\s*\.?")
47
+ _END = re.compile(r"\s\.(?=\s|$)|(?<=[\]>)\w\"'])\.(?=\s|$)")
48
+
49
+
50
+ def _triples(text: str) -> list[tuple[str, str, str]]:
51
+ """Subject, predicate and object of a Turtle file; names are expanded, literals dropped."""
52
+ iris: list[str] = []
53
+
54
+ def keep(match: re.Match[str]) -> str:
55
+ iris.append(match.group(1))
56
+ return f" \x00{len(iris)} "
57
+
58
+ body = re.sub(r"(?m)#[^\n]*$", "", _IRI.sub(keep, _STRING.sub(' "" ', text)))
59
+ prefixes = {
60
+ m.group(1) or "": iris[int(m.group(2)) - 1] for m in _PREFIX.finditer(body)
61
+ }
62
+ body = re.sub(r"\[[^\[\]]*\]", " _:b ", _PREFIX.sub("", body))
63
+
64
+ def expand(token: str) -> str:
65
+ if token.startswith("\x00"):
66
+ return iris[int(token[1:]) - 1]
67
+ prefix, sep, local = token.partition(":")
68
+ return (
69
+ prefixes[prefix] + local
70
+ if sep and prefix in prefixes
71
+ else RDF_TYPE
72
+ if token == "a"
73
+ else token
74
+ )
75
+
76
+ triples: list[tuple[str, str, str]] = []
77
+ for statement in _END.split(body):
78
+ tokens = statement.replace(";", " ; ").replace(",", " , ").split()
79
+ subject, predicate, fresh = "", "", True
80
+ for index, token in enumerate(tokens):
81
+ if index == 0:
82
+ subject = expand(token)
83
+ elif token == ";":
84
+ fresh = True
85
+ elif token != ",":
86
+ if fresh:
87
+ predicate, fresh = expand(token), False
88
+ else:
89
+ triples.append((subject, predicate, expand(token)))
90
+ return triples
91
+
92
+
93
+ def _orphans(triples: list[tuple[str, str, str]]) -> set[str]:
94
+ declared = {s for s, p, o in triples if p == RDF_TYPE and o == OWL + "Class"}
95
+ linked: set[str] = set()
96
+ changed = True
97
+ while changed:
98
+ changed = False
99
+ for cls in declared - linked - PARENT_CLASSES:
100
+ ups = {o for s, p, o in triples if s == cls and p == SUBCLASS}
101
+ if ups & (PARENT_CLASSES | linked):
102
+ linked.add(cls)
103
+ changed = True
104
+ return declared - linked - PARENT_CLASSES
105
+
106
+
107
+ @pytest.mark.parametrize("path", ONTOLOGIES, ids=lambda p: p.name)
108
+ def test_ontology_joins_the_parent_graph(path: Path) -> None:
109
+ triples = _triples(path.read_text(encoding="utf-8"))
110
+ declared = {s for s, p, o in triples if p == RDF_TYPE and o == OWL + "Class"}
111
+ if not declared:
112
+ pytest.skip("declares no classes")
113
+ imports = {o for s, p, o in triples if p == OWL + "imports"}
114
+ assert any(i == PARENT_IRI or i.startswith(PARENT_IRI + "/") for i in imports)
115
+ assert _orphans(triples) == PENDING_NEW_PARENT & declared
File without changes
File without changes
File without changes