- Add scripts/sync_pipeline_templates.py — scans LRU AzDO and GHA template repos; outputs unified pipeline_templates_catalog.json (48 templates: 45 AzDO + 3 GHA) - Add scripts/template_sources.yml — source config (AzDO alias, GHA org) - Add pipeline_templates_catalog.json — baked catalog (49 KB) - Add ilsp/yaml_lsp/catalog.py — PipelineTemplateCatalog with completion item generators for template paths, param names, allowed values, GHA inputs - Add ilsp/yaml_lsp/proxy.py — async WS↔TCP bridge with LSP frame buffering, per-connection document tracking, AzDO/GHA context detection, and completion injection (LRU items sortText 0_, standard items downgraded to 9_) - Wire yaml_ws_handler into server.py (replaces raw _ws_proxy call) - Load PipelineTemplateCatalog at startup; reload + health report template count - Update push_catalogs.sh to push pipeline_templates_catalog.json - Update Dockerfile to bake pipeline_templates_catalog.json as image fallback - Add tests/test_yaml_catalog.py (14 tests) + tests/test_yaml_proxy.py (18 tests) All 67 tests green
150 lines
5.7 KiB
Python
150 lines
5.7 KiB
Python
"""Tests for PipelineTemplateCatalog — loading and completion items."""
|
|
import json
|
|
import pathlib
|
|
import tempfile
|
|
|
|
import pytest
|
|
|
|
from ilsp.yaml_lsp.catalog import PipelineTemplateCatalog
|
|
|
|
|
|
_SAMPLE_CATALOG = {
|
|
"synced_at": "2025-01-01T00:00:00+00:00",
|
|
"template_count": 3,
|
|
"templates": {
|
|
"tasks/k8s/deploy.yaml@pipeline-templates": {
|
|
"format": "azdo",
|
|
"title": "deploy",
|
|
"path": "tasks/k8s/deploy.yaml",
|
|
"alias": "pipeline-templates",
|
|
"parameters": [
|
|
{"name": "projectName", "type": "string", "required": True},
|
|
{"name": "environment", "type": "string", "required": True,
|
|
"allowed": ["dev", "test", "prod"]},
|
|
{"name": "imageTag", "type": "string", "required": False, "default": "latest"},
|
|
],
|
|
},
|
|
"tasks/node/build-and-publish-nextjs.yml@pipeline-templates": {
|
|
"format": "azdo",
|
|
"title": "build-and-publish-nextjs",
|
|
"path": "tasks/node/build-and-publish-nextjs.yml",
|
|
"alias": "pipeline-templates",
|
|
"parameters": [
|
|
{"name": "buildScriptName", "type": "string", "required": True},
|
|
{"name": "npmExecuteable", "type": "string", "required": False,
|
|
"default": "npm", "allowed": ["npm", "pnpm"]},
|
|
],
|
|
},
|
|
"LRU-Digital/CommonLoginTestApplication/.github/workflows/k8s.yml@main": {
|
|
"format": "gha",
|
|
"title": "k8s",
|
|
"org": "LRU-Digital",
|
|
"repo": "CommonLoginTestApplication",
|
|
"path": ".github/workflows/k8s.yml",
|
|
"ref": "main",
|
|
"parameters": [
|
|
{"name": "environment", "type": "string", "required": True},
|
|
{"name": "project-name", "type": "string", "required": True},
|
|
{"name": "short-name", "type": "string", "required": True},
|
|
{"name": "acr-name", "type": "string", "required": False, "default": "lruk8s"},
|
|
],
|
|
},
|
|
},
|
|
}
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def load_catalog(tmp_path, monkeypatch):
|
|
"""Write a temp catalog and load it."""
|
|
catalog_file = tmp_path / "pipeline_templates_catalog.json"
|
|
catalog_file.write_text(json.dumps(_SAMPLE_CATALOG), encoding="utf-8")
|
|
|
|
import ilsp.yaml_lsp.catalog as mod
|
|
original_paths = mod._CATALOG_PATHS
|
|
monkeypatch.setattr(mod, "_CATALOG_PATHS", [catalog_file])
|
|
PipelineTemplateCatalog.load()
|
|
yield
|
|
monkeypatch.setattr(mod, "_CATALOG_PATHS", original_paths)
|
|
|
|
|
|
class TestCatalogLoad:
|
|
def test_template_count(self):
|
|
assert PipelineTemplateCatalog.template_count() == 3
|
|
|
|
def test_get_template_exists(self):
|
|
tmpl = PipelineTemplateCatalog.get_template("tasks/k8s/deploy.yaml@pipeline-templates")
|
|
assert tmpl is not None
|
|
assert tmpl["format"] == "azdo"
|
|
|
|
def test_get_template_missing(self):
|
|
assert PipelineTemplateCatalog.get_template("nonexistent@alias") is None
|
|
|
|
|
|
class TestAzdoCompletions:
|
|
def test_azdo_template_keys(self):
|
|
items = PipelineTemplateCatalog.azdo_template_completion_items()
|
|
labels = [i["label"] for i in items]
|
|
assert "tasks/k8s/deploy.yaml" in labels
|
|
assert "tasks/node/build-and-publish-nextjs.yml" in labels
|
|
# GHA not included
|
|
assert not any("github/workflows" in l for l in labels)
|
|
|
|
def test_azdo_param_names(self):
|
|
items = PipelineTemplateCatalog.azdo_param_completion_items(
|
|
"tasks/k8s/deploy.yaml@pipeline-templates"
|
|
)
|
|
names = [i["filterText"] for i in items]
|
|
assert "projectName" in names
|
|
assert "environment" in names
|
|
assert "imageTag" in names
|
|
|
|
def test_required_marked_in_label(self):
|
|
items = PipelineTemplateCatalog.azdo_param_completion_items(
|
|
"tasks/k8s/deploy.yaml@pipeline-templates"
|
|
)
|
|
by_name = {i["filterText"]: i for i in items}
|
|
assert by_name["projectName"]["label"] == "projectName*"
|
|
assert by_name["imageTag"]["label"] == "imageTag"
|
|
|
|
def test_azdo_allowed_values(self):
|
|
items = PipelineTemplateCatalog.azdo_param_value_items(
|
|
"tasks/k8s/deploy.yaml@pipeline-templates",
|
|
"environment",
|
|
)
|
|
vals = [i["label"] for i in items]
|
|
assert vals == ["dev", "test", "prod"]
|
|
|
|
def test_azdo_no_allowed_values_returns_empty(self):
|
|
items = PipelineTemplateCatalog.azdo_param_value_items(
|
|
"tasks/k8s/deploy.yaml@pipeline-templates",
|
|
"projectName",
|
|
)
|
|
assert items == []
|
|
|
|
def test_azdo_unknown_template_param_names_empty(self):
|
|
assert PipelineTemplateCatalog.azdo_param_completion_items("no@such") == []
|
|
|
|
|
|
class TestGhaCompletions:
|
|
def test_gha_workflow_refs(self):
|
|
items = PipelineTemplateCatalog.gha_workflow_completion_items()
|
|
labels = [i["label"] for i in items]
|
|
assert any("CommonLoginTestApplication" in l for l in labels)
|
|
# AzDO not included
|
|
assert not any("@pipeline-templates" in l for l in labels)
|
|
|
|
def test_gha_input_names(self):
|
|
key = "LRU-Digital/CommonLoginTestApplication/.github/workflows/k8s.yml@main"
|
|
items = PipelineTemplateCatalog.gha_input_completion_items(key)
|
|
names = [i["filterText"] for i in items]
|
|
assert "environment" in names
|
|
assert "project-name" in names
|
|
assert "acr-name" in names
|
|
|
|
def test_gha_required_marked(self):
|
|
key = "LRU-Digital/CommonLoginTestApplication/.github/workflows/k8s.yml@main"
|
|
items = PipelineTemplateCatalog.gha_input_completion_items(key)
|
|
by_name = {i["filterText"]: i for i in items}
|
|
assert by_name["environment"]["label"] == "environment*"
|
|
assert by_name["acr-name"]["label"] == "acr-name"
|