feat: YAML pipeline template autocomplete (AzDO + GHA)
- 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
This commit is contained in:
@@ -24,6 +24,8 @@ from aiohttp import web
|
||||
from .python_lsp.catalog import PypiCatalog
|
||||
from .bicep_lsp.modules import BicepModuleCatalog
|
||||
from .bicep_lsp.proxy import serve_bicep
|
||||
from .yaml_lsp.catalog import PipelineTemplateCatalog
|
||||
from .yaml_lsp.proxy import yaml_ws_handler
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -131,17 +133,26 @@ async def _build_app() -> web.Application:
|
||||
"bicep_modules": len(BicepModuleCatalog._modules),
|
||||
"iac_source_modules": len(BicepModuleCatalog._iac),
|
||||
"yaml_lsp": bool(shutil.which("yaml-language-server")),
|
||||
"pipeline_templates": PipelineTemplateCatalog.template_count(),
|
||||
})
|
||||
|
||||
async def reload(_: web.Request) -> web.Response:
|
||||
before = len(BicepModuleCatalog._modules)
|
||||
before_bicep = len(BicepModuleCatalog._modules)
|
||||
before_tmpl = PipelineTemplateCatalog.template_count()
|
||||
BicepModuleCatalog.load()
|
||||
after = len(BicepModuleCatalog._modules)
|
||||
logger.info("Catalog reloaded: %d → %d modules", before, after)
|
||||
PipelineTemplateCatalog.load()
|
||||
after_bicep = len(BicepModuleCatalog._modules)
|
||||
after_tmpl = PipelineTemplateCatalog.template_count()
|
||||
logger.info(
|
||||
"Catalog reloaded: bicep %d→%d templates %d→%d",
|
||||
before_bicep, after_bicep, before_tmpl, after_tmpl,
|
||||
)
|
||||
return web.json_response({
|
||||
"status": "reloaded",
|
||||
"bicep_modules_before": before,
|
||||
"bicep_modules_after": after,
|
||||
"bicep_modules_before": before_bicep,
|
||||
"bicep_modules_after": after_bicep,
|
||||
"pipeline_templates_before": before_tmpl,
|
||||
"pipeline_templates_after": after_tmpl,
|
||||
})
|
||||
|
||||
async def python_ws(request: web.Request) -> web.WebSocketResponse:
|
||||
@@ -151,7 +162,7 @@ async def _build_app() -> web.Application:
|
||||
return await _ws_proxy(request, "127.0.0.1", BICEP_LSP_PORT)
|
||||
|
||||
async def yaml_ws(request: web.Request) -> web.WebSocketResponse:
|
||||
return await _ws_proxy(request, "127.0.0.1", YAML_LSP_PORT)
|
||||
return await yaml_ws_handler(request, YAML_LSP_PORT)
|
||||
|
||||
app.router.add_get("/health", health)
|
||||
app.router.add_post("/reload", reload)
|
||||
@@ -169,6 +180,7 @@ async def main_async() -> None:
|
||||
|
||||
logger.info("Pre-warming catalogs…")
|
||||
BicepModuleCatalog.load()
|
||||
PipelineTemplateCatalog.load()
|
||||
await PypiCatalog.start_background_refresh()
|
||||
|
||||
# LSP servers run internally on localhost — not exposed outside the container
|
||||
|
||||
Reference in New Issue
Block a user