gitlab-api 27.3.14__tar.gz → 27.3.15__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 (88) hide show
  1. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/PKG-INFO +1 -1
  2. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/ontology/certification.json +1 -1
  3. gitlab_api-27.3.15/gitlab_api/skills/gitlab-api-development/SKILL.md +132 -0
  4. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api.egg-info/PKG-INFO +1 -1
  5. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api.egg-info/SOURCES.txt +3 -0
  6. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/pyproject.toml +1 -1
  7. gitlab_api-27.3.15/tests/test_gitlab_api_development_skill.py +54 -0
  8. gitlab_api-27.3.15/tests/test_pages_workflow.py +52 -0
  9. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/LICENSE +0 -0
  10. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/README.md +0 -0
  11. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/__init__.py +0 -0
  12. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/__main__.py +0 -0
  13. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/api/__init__.py +0 -0
  14. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/api/api_client_base.py +0 -0
  15. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/api/api_client_environments.py +0 -0
  16. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/api/api_client_issues.py +0 -0
  17. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/api/api_client_merge_requests.py +0 -0
  18. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/api/api_client_other.py +0 -0
  19. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/api/api_client_pipelines.py +0 -0
  20. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/api/api_client_projects.py +0 -0
  21. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/api/api_client_repositories.py +0 -0
  22. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/api/api_client_system.py +0 -0
  23. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/api/api_client_users_groups.py +0 -0
  24. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/api/api_client_vulnerabilities.py +0 -0
  25. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/api_client.py +0 -0
  26. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/auth.py +0 -0
  27. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/connector_prep.py +0 -0
  28. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/connector_sources.py +0 -0
  29. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/gitlab_gql.py +0 -0
  30. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/gitlab_input_models.py +0 -0
  31. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/gitlab_response_models.py +0 -0
  32. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/instances.py +0 -0
  33. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/kg_ingest.py +0 -0
  34. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/mcp_config.json +0 -0
  35. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/mcp_server.py +0 -0
  36. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/ontology/__init__.py +0 -0
  37. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/ontology/access_contracts.ttl +0 -0
  38. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/ontology/fixtures/records.json +0 -0
  39. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/ontology/gitlab.ttl +0 -0
  40. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/ontology/mappings/source.yaml +0 -0
  41. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/ontology/migrations/manifest.json +0 -0
  42. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/ontology/shapes/connector.shacl.ttl +0 -0
  43. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/prompts/devops_specialist.json +0 -0
  44. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/skills/gitlab-api-operations/SKILL.md +0 -0
  45. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/skills/gitlab-api-operations/agents/openai.yaml +0 -0
  46. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/skills/gitlab-api-operations/references/catalog.md +0 -0
  47. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/skills/gitlab-issues/SKILL.md +0 -0
  48. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/skills/gitlab-issues/WORKFLOW.md +0 -0
  49. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/skills/gitlab-merge-request-create/SKILL.md +0 -0
  50. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/skills/gitlab-merge-request-create/WORKFLOW.md +0 -0
  51. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/skills/gitlab-merge-request-review/SKILL.md +0 -0
  52. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/skills/gitlab-merge-request-review/WORKFLOW.md +0 -0
  53. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/skills/gitlab-pipelines/SKILL.md +0 -0
  54. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/skills/gitlab-pipelines/WORKFLOW.md +0 -0
  55. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/skills/gitlab-vulnerabilities/SKILL.md +0 -0
  56. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api/skills/gitlab-vulnerabilities/WORKFLOW.md +0 -0
  57. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api.egg-info/dependency_links.txt +0 -0
  58. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api.egg-info/entry_points.txt +0 -0
  59. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api.egg-info/requires.txt +0 -0
  60. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/gitlab_api.egg-info/top_level.txt +0 -0
  61. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/scripts/check_import_safety.py +0 -0
  62. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/scripts/security_contract.py +0 -0
  63. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/setup.cfg +0 -0
  64. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/__init__.py +0 -0
  65. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/conftest.py +0 -0
  66. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_access_contracts.py +0 -0
  67. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_api_wrapper.py +0 -0
  68. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_auth.py +0 -0
  69. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_catalog_edges.py +0 -0
  70. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_connector_prep.py +0 -0
  71. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_cq_paths.py +0 -0
  72. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_fleet_name.py +0 -0
  73. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_gitlab_a2a_validation.py +0 -0
  74. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_gitlab_api_brute_force_coverage.py +0 -0
  75. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_gitlab_gql.py +0 -0
  76. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_gitlab_mcp_validation.py +0 -0
  77. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_gitlab_models.py +0 -0
  78. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_identity_context_scoping.py +0 -0
  79. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_ingest_sources.py +0 -0
  80. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_init_dynamics.py +0 -0
  81. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_instances.py +0 -0
  82. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_kg_ingest.py +0 -0
  83. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_mock_coverage.py +0 -0
  84. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_ontology_parent_link.py +0 -0
  85. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_startup.py +0 -0
  86. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_tool_modes.py +0 -0
  87. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/tests/test_verify_agent.py +0 -0
  88. {gitlab_api-27.3.14 → gitlab_api-27.3.15}/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.14
3
+ Version: 27.3.15
4
4
  Summary: GitLab API + MCP Server
5
5
  Author-email: Repository Maintainers <maintainers@knuckles.team>
6
6
  License: MIT
@@ -29,5 +29,5 @@
29
29
  "signer": "UNSIGNED-PREVIEW",
30
30
  "signing_public_key": "",
31
31
  "status": "source-validated",
32
- "validated_at": "2026-10-25T22:08:01Z"
32
+ "validated_at": "2026-10-27T03:44:15Z"
33
33
  }
@@ -0,0 +1,132 @@
1
+ ---
2
+ name: gitlab-api-development
3
+ skill_type: skill
4
+ domain: development
5
+ description: >-
6
+ Develop, test, gate, and release the GitLab REST and GraphQL connector. Use
7
+ this skill when changing API mappings, governed MCP tools, authentication,
8
+ tenant selection, KG ingestion, packaged content, or repository gates.
9
+ license: MIT
10
+ tags: [gitlab, rest, graphql, mcp, development, connector, test, gates]
11
+ tier: repository
12
+ metadata:
13
+ author: Genius
14
+ version: '0.1.0'
15
+ ---
16
+
17
+ # gitlab-api development
18
+
19
+ This repository owns the GitLab REST and GraphQL API facades, tenant and
20
+ authentication boundary, action-routed MCP tools, GitLab ontology and KG
21
+ ingestion mappings, and packaged connector content. Shared connector
22
+ contracts, transports, TLS profiles, and credential helpers belong to
23
+ `agent-connector-sdk`; admission, serving, and durable graph state belong to
24
+ their owning repositories. Read `AGENTS.md` before changing code and keep
25
+ credentials, private endpoints, tenant data, and customer records out of
26
+ source, logs, fixtures, and skill content.
27
+
28
+ ## Rapid delivery: the 5-minute contract
29
+
30
+ Specs are already designed. Deliver small, reviewable slices and cite the
31
+ owning spec row in the commit trailer.
32
+
33
+ - Find the owning row first with `git grep -n "<term>" -- specs` and extend the
34
+ existing spec before adding requirement text.
35
+ - Reuse the single `Connector` in `gitlab_api/__init__.py`, the `Api` facade in
36
+ `gitlab_api/api_client.py`, the modular clients under `gitlab_api/api/`, and
37
+ the action dispatch tables in `gitlab_api/mcp_server.py`. Keep GraphQL
38
+ operations in `gitlab_api/gitlab_gql.py`; do not create a second API, MCP,
39
+ authentication, or transport plane.
40
+ - Preserve the multi-tenant resolution in `gitlab_api/instances.py`. A named
41
+ instance, bare URL, or default selection must retain caller entitlement
42
+ checks and the `GITLAB_INSTANCES` shared setting. The legacy
43
+ `GITLAB_URL`/`GITLAB_TOKEN` fallback remains supported.
44
+ - Preserve `GITLAB_URL`, `GITLAB_TOKEN`, `GITLAB_TLS_PROFILE`, and
45
+ `ENABLE_DELEGATION` handling in `gitlab_api/auth.py`. Delegated RFC 8693
46
+ token exchange and fixed credentials stay behind the SDK identity/TLS
47
+ helpers. Never print tokens or add a TLS verification bypass.
48
+ - Keep the REST resource paths, GraphQL typed-operation boundary, action names,
49
+ pagination, and response models stable. Use `run_blocking` for blocking API
50
+ calls from MCP tools and return typed refusal/error envelopes instead of
51
+ bypassing the shared dispatcher. Keep `MCP_TOOL_MODE` (`condensed`,
52
+ `verbose`, or `both`) and each action group's toggle behavior aligned with
53
+ the generated tool surface.
54
+ - Preserve typed KG ingestion through `gitlab_api/kg_ingest.py`, source
55
+ declarations in `gitlab_api/connector_sources.py`, and neutral ontology
56
+ mappings. Project, issue, merge-request, pipeline, job, runner, group, and
57
+ person records use the existing stable IDs and relationship names.
58
+ - Mock HTTP, GraphQL, and authentication responses in local tests; never call a
59
+ live GitLab instance or use live credentials in a gate. Every delivered
60
+ requirement needs a bound focused test. Generated `specs/*/status.json` files
61
+ come from shared hooks; never hand-edit them.
62
+ - Keep `skills/**`, `ontology/**`, `connectors/**`, prompts, and
63
+ `mcp_config.json` coherent with package data and the
64
+ `agent_connector_sdk.connector` entry point (`gitlab-mcp =
65
+ gitlab_api:connector`). Do not add a second publisher or runtime plane.
66
+
67
+ ## Setup and gates
68
+
69
+ Use the pinned environment from `uv sync --locked`, then run the shared gates:
70
+
71
+ ```bash
72
+ uv sync --locked
73
+ uvx pre-commit run --all-files
74
+ uvx pre-commit run --all-files --hook-stage pre-push
75
+ ```
76
+
77
+ For focused feedback, run the smallest affected tests with the locked
78
+ environment, for example:
79
+
80
+ ```bash
81
+ uv run --locked --extra test pytest -q tests/test_gitlab_api_development_skill.py
82
+ uv run --locked --extra test pytest -q tests/test_pages_workflow.py
83
+ uv run --locked --extra test pytest -q tests/test_auth.py tests/test_gitlab_mcp_validation.py
84
+ ```
85
+
86
+ The canonical `.pre-commit-config.yaml` delegates connector-standard, secrets,
87
+ spec, tests-fast, and dependency-readiness to `Knuckles-Team/pipelines`. Do not
88
+ copy those hooks locally or bypass a failing check.
89
+
90
+ ## Connector-specific checks
91
+
92
+ - Keep REST resource paths, GraphQL operation names, action selectors,
93
+ pagination, and Pydantic response normalization stable. Add focused mocked
94
+ request tests for a changed provider path.
95
+ - Keep OIDC token exchange and fixed-token fallback at the existing
96
+ authentication boundary. Resolve TLS policy through the SDK and never bake
97
+ static bearer tokens into the client.
98
+ - Preserve identity-scoped tenant discovery and refusal of an instance the
99
+ caller is not entitled to use. Discovery returns names, URLs, and profile
100
+ state only; it never returns tokens.
101
+ - Keep projects, issues, merge requests, pipelines, jobs, runners, groups, and
102
+ people as the typed records already mapped by `gitlab_api/kg_ingest.py`.
103
+ Ingestion stays best-effort when the graph engine is unavailable.
104
+ - Keep `gitlab_api/skills/`, `gitlab_api/ontology/`,
105
+ `gitlab_api/connectors/`, prompts, and `gitlab_api/mcp_config.json` in package
106
+ data. Keep source metadata tenant-neutral.
107
+ - Documentation is published by the existing Pages workflow and checked-in
108
+ dashboard configuration; source status records under `specs/` are generated
109
+ by shared hooks.
110
+
111
+ ## Packaging and publication
112
+
113
+ `pyproject.toml` declares the `agent_connector_sdk.connector` entry point
114
+ `gitlab-mcp = "gitlab_api:connector"` and packages `skills/**`, `ontology/**`,
115
+ `connectors/**`, prompts, and `mcp_config.json`. When packaged content changes,
116
+ use `uv version --bump patch` and let the lockfile update with the project; add
117
+ the release note to `CHANGELOG.md`. Inspect `uv build` output for
118
+ `gitlab_api/skills/gitlab-api-development/SKILL.md`.
119
+
120
+ The canonical release caller delegates publication and connector rendering to
121
+ the shared pipelines. Do not commit generated Docker artifacts or claim
122
+ package, container, or Pages publication from a local build; require exact
123
+ source hosted evidence and the public artifact.
124
+
125
+ ## Delivery discipline
126
+
127
+ Work in a real Git worktree based on `origin/main`. Inspect the complete diff,
128
+ stage only reviewed paths, and verify `git status --short` after every gate. Do
129
+ not use `git stash`, `git add -A`, or `git add .`; preserve unrelated working
130
+ tree changes. Keep runtime, ontology, status, and generated artifacts outside
131
+ this bounded skill slice unless the owning requirement explicitly requires
132
+ them.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gitlab-api
3
- Version: 27.3.14
3
+ Version: 27.3.15
4
4
  Summary: GitLab API + MCP Server
5
5
  Author-email: Repository Maintainers <maintainers@knuckles.team>
6
6
  License: MIT
@@ -41,6 +41,7 @@ gitlab_api/ontology/mappings/source.yaml
41
41
  gitlab_api/ontology/migrations/manifest.json
42
42
  gitlab_api/ontology/shapes/connector.shacl.ttl
43
43
  gitlab_api/prompts/devops_specialist.json
44
+ gitlab_api/skills/gitlab-api-development/SKILL.md
44
45
  gitlab_api/skills/gitlab-api-operations/SKILL.md
45
46
  gitlab_api/skills/gitlab-api-operations/agents/openai.yaml
46
47
  gitlab_api/skills/gitlab-api-operations/references/catalog.md
@@ -67,6 +68,7 @@ tests/test_cq_paths.py
67
68
  tests/test_fleet_name.py
68
69
  tests/test_gitlab_a2a_validation.py
69
70
  tests/test_gitlab_api_brute_force_coverage.py
71
+ tests/test_gitlab_api_development_skill.py
70
72
  tests/test_gitlab_gql.py
71
73
  tests/test_gitlab_mcp_validation.py
72
74
  tests/test_gitlab_models.py
@@ -77,6 +79,7 @@ tests/test_instances.py
77
79
  tests/test_kg_ingest.py
78
80
  tests/test_mock_coverage.py
79
81
  tests/test_ontology_parent_link.py
82
+ tests/test_pages_workflow.py
80
83
  tests/test_startup.py
81
84
  tests/test_tool_modes.py
82
85
  tests/test_verify_agent.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "gitlab-api"
7
- version = "27.3.14"
7
+ version = "27.3.15"
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,54 @@
1
+ """PIPE-CONNSPEC-R125.4: the GitLab API development skill is packaged."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import re
6
+ import tomllib
7
+ from pathlib import Path
8
+
9
+ import pytest
10
+
11
+ ROOT = Path(__file__).resolve().parents[1]
12
+ SKILL = ROOT / "gitlab_api" / "skills" / "gitlab-api-development" / "SKILL.md"
13
+
14
+ pytestmark = pytest.mark.spec("PIPE-CONNSPEC-R125.4")
15
+
16
+
17
+ def test_development_skill_has_rapid_contract_and_package_binding() -> None:
18
+ text = SKILL.read_text(encoding="utf-8")
19
+ frontmatter = text.split("---", 2)[1]
20
+ project = tomllib.loads((ROOT / "pyproject.toml").read_text(encoding="utf-8"))
21
+
22
+ assert SKILL.is_file()
23
+ assert re.search(r"^name:\s*gitlab-api-development\s*$", frontmatter, re.M)
24
+ assert re.search(r"^skill_type:\s*skill\s*$", frontmatter, re.M)
25
+ assert "## Rapid delivery: the 5-minute contract" in text
26
+ for term in (
27
+ "gitlab_api/__init__.py",
28
+ "gitlab_api/api_client.py",
29
+ "gitlab_api/api/",
30
+ "gitlab_api/auth.py",
31
+ "gitlab_api/instances.py",
32
+ "gitlab_api/mcp_server.py",
33
+ "gitlab_api/gitlab_gql.py",
34
+ "gitlab_api/kg_ingest.py",
35
+ "gitlab_api/connector_sources.py",
36
+ "GITLAB_URL",
37
+ "GITLAB_TOKEN",
38
+ "GITLAB_TLS_PROFILE",
39
+ "GITLAB_INSTANCES",
40
+ "ENABLE_DELEGATION",
41
+ "MCP_TOOL_MODE",
42
+ "skills/**",
43
+ "ontology/**",
44
+ "uv run --locked --extra test pytest",
45
+ ):
46
+ assert term in text
47
+
48
+ assert "verify=False" not in text
49
+ assert "--no-verify" not in text
50
+ package_data = project["tool"]["setuptools"]["package-data"]["gitlab_api"]
51
+ assert "skills/**" in package_data
52
+ assert project["project"]["entry-points"]["agent_connector_sdk.connector"] == {
53
+ "gitlab-mcp": "gitlab_api:connector"
54
+ }
@@ -0,0 +1,52 @@
1
+ """PIPE-CONNSPEC-R125.3: GitLab API Pages and spec-dashboard contract."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import re
7
+ from pathlib import Path
8
+
9
+ import pytest
10
+
11
+ ROOT = Path(__file__).resolve().parents[1]
12
+ WORKFLOW = ROOT / ".github/workflows/pages.yml"
13
+ DASHBOARD = ROOT / ".github/spec-dashboard.json"
14
+
15
+ pytestmark = pytest.mark.spec("PIPE-CONNSPEC-R125.3")
16
+
17
+
18
+ def test_pages_caller_enables_dashboard_and_rebuilds_for_spec_changes() -> None:
19
+ assert not (ROOT / ".github/workflows/docs.yml").exists()
20
+
21
+ workflow = WORKFLOW.read_text(encoding="utf-8")
22
+
23
+ assert "uses: Knuckles-Team/pipelines/.github/workflows/pages_pipeline.yml@main" in workflow
24
+ assert re.search(r"^ content_source: docs$", workflow, re.MULTILINE)
25
+ assert re.search(r"^ spec_dashboard_enabled: true$", workflow, re.MULTILINE)
26
+ assert re.search(
27
+ r"^ spec_dashboard_config: \.github/spec-dashboard\.json$",
28
+ workflow,
29
+ re.MULTILINE,
30
+ )
31
+ assert re.search(r"^ workflow_dispatch: \{\}$", workflow, re.MULTILINE)
32
+ for path in (
33
+ "'docs/**'",
34
+ "'mkdocs.yml'",
35
+ "'README.md'",
36
+ "'specs/**'",
37
+ "'.github/spec-dashboard.json'",
38
+ "'.github/workflows/pages.yml'",
39
+ ):
40
+ assert path in workflow
41
+
42
+ assert re.search(r"(?m)^ pages: write$", workflow)
43
+ assert re.search(r"(?m)^ id-token: write$", workflow)
44
+
45
+
46
+ def test_dashboard_reads_only_canonical_spec_status_files() -> None:
47
+ config = json.loads(DASHBOARD.read_text(encoding="utf-8"))
48
+
49
+ assert config == {
50
+ "version": 1,
51
+ "sources": [{"glob": "specs/*/status.json", "kind": "spec"}],
52
+ }
File without changes
File without changes
File without changes