feat(component-templates): initial draft of matrixed components#83
feat(component-templates): initial draft of matrixed components#83reubeno wants to merge 1 commit intomicrosoft:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds initial support for matrix-expanded component templates in the project config, allowing a single template definition to expand into multiple concrete components at load time.
Changes:
- Extend the config schema + ConfigFile model with a new top-level
component-templatessection. - Implement
ComponentTemplateConfig/MatrixAxisand template expansion (cartesian product + merge layering), wired into config loading. - Add unit + integration-style tests for validation and end-to-end config loading/expansion; update schema generation snapshots and user docs.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| schemas/azldev.schema.json | Adds schema definitions for component templates + matrix axes and exposes component-templates at the top level. |
| scenario/snapshots/TestSnapshotsContainer_config_generate-schema_stdout_1.snap | Updates schema-generation snapshot output for container scenario tests. |
| scenario/snapshots/TestSnapshots_config_generate-schema_stdout_1.snap | Updates schema-generation snapshot output for scenario tests. |
| internal/projectconfig/templateexpansion.go | Implements cartesian product expansion + config layering into concrete components. |
| internal/projectconfig/templateexpansion_test.go | Adds tests for expansion behavior and load-time integration. |
| internal/projectconfig/loader.go | Wires template expansion into config merge/load pipeline; adds a new duplicate-template error symbol. |
| internal/projectconfig/configfile.go | Adds ComponentTemplates field and validates template configs during ConfigFile.Validate(). |
| internal/projectconfig/componenttemplate.go | Introduces template/matrix config types, validation, and absolute-path resolution. |
| internal/projectconfig/componenttemplate_test.go | Adds validation and path-resolution tests for template configs. |
| docs/user/reference/config/config-file.md | Documents the new top-level component-templates section. |
| docs/user/reference/config/components.md | Adds a cross-link to the new component templates reference page. |
| docs/user/reference/config/component-templates.md | New reference page documenting template syntax, constraints, and examples. |
| // mergeComponentTemplates expands component template definitions from a loaded config file | ||
| // and merges the resulting components into the resolved config. Duplicate template names | ||
| // across config files are not allowed. Expanded component names must not collide with | ||
| // existing components. | ||
| func mergeComponentTemplates(resolvedCfg *ProjectConfig, loadedCfg *ConfigFile) error { |
There was a problem hiding this comment.
The function comment says duplicate template names across config files are not allowed, and ErrDuplicateComponentTemplates was added, but mergeComponentTemplates does not currently detect duplicate template names between loaded config files. As a result, the same template name can appear in multiple files without error as long as the expanded component names don’t collide. Track seen template names in the resolved config (or in mergeConfigFiles) and return ErrDuplicateComponentTemplates when a template name is encountered more than once.
| // Merge expanded components into the resolved config, checking for duplicates. | ||
| for componentName, component := range expandedComponents { | ||
| if _, ok := resolvedCfg.Components[componentName]; ok { | ||
| return fmt.Errorf( | ||
| "%w: component template %#q expands to %#q which already exists", | ||
| ErrDuplicateComponents, templateName, componentName, | ||
| ) | ||
| } | ||
|
|
||
| resolvedCfg.Components[componentName] = component | ||
| } |
There was a problem hiding this comment.
mergeComponentTemplates ranges over expandedComponents (a map), so the order of inserting expanded components (and which collision is reported first) is nondeterministic. This can lead to flaky/variable error messages when a template expansion collides with an existing component. Consider sorting the expanded component names before merging so expansion/validation is deterministic.
For details on this draft, see this doc page: https://github.com/reubeno/azure-linux-dev-tools/blob/ca2656807d7d98eb8a378cc9dd9809cfd440ec37/docs/user/reference/config/component-templates.md