microsoft / microsoft/aspire

Git-based template system: implement Phases 2-6 (catalog client, list/search/refresh/new, polyglot engine)

Open
#16,998 2 comments 0 reactions 1 assignee Claimed by @mitchdenny View on GitHub
area-templates
Dominant language
C#
Stars
6.3k
Forks
991
Avg merge
2d 15h
Merged PRs (30d)
196

Description

## Background

PR #16927 landed Phase 1 of the git-based template system: spec, `gitTemplatesEnabled` feature flag, and four stub subcommands behind it (`aspire template list`, `search`, `refresh`, `new`). This issue tracks the remaining phases needed to make the feature actually usable.

This work resumes the spike from PR #14763, but with a key architectural change: **template discovery is delegated to a single `aspire.dev` HTTP endpoint** instead of a federated walk of `aspire-template-index.json` files. That removes per-repo index files, `includes` federation, `gh`-based personal/org auto-discovery, and the `aspire template new-index` command. CLI configuration collapses to `templates.serviceUrl` + `templates.cacheTtlMinutes`.

The full architecture is in [`docs/specs/git-templates.md`](https://github.com/microsoft/aspire/blob/main/docs/specs/git-templates.md). The phased plan is in §15 of that spec.

## Current state (shipped in #16927)

- `KnownFeatures.GitTemplatesEnabled` (default `false`).
- `aspire template` command group wired into `RootCommand` behind the flag.
- 4 stub subcommands that print "not yet implemented" and return `Success`.
- 15 parse / feature-flag-gating tests, all passing.
- No real implementation behind any of the commands yet.

Enable for local smoke testing:

```
aspire config set features.gitTemplatesEnabled true
aspire template --help
```

## Remaining phases

Each phase below should ship as its own PR so reviews stay focused.

### Phase 2: Catalog client + caching primitives

- HTTP client for `GET {templates.serviceUrl}/templates/index.json?q=&language=&limit=&cursor=` with response shape per spec §3.
- Disk cache layout under `~/.aspire/templates/`:
- `index/` — HTTP-cached catalog responses keyed by full URL, honoring `templates.cacheTtlMinutes` (default TBD; see §13).
- `repos///` — content-addressed git checkouts (no writes after phase 2).
- `templates.serviceUrl` + `templates.cacheTtlMinutes` config keys with sensible defaults.
- Decide cache size budget and eviction policy (open question in spec §13).
- Tests: catalog client (with a fake `HttpMessageHandler`), TTL behavior, malformed payload handling, cursor pagination.

### Phase 3: `aspire template list` + `aspire template search `

- Wire the catalog client into the `list` and `search` stubs.
- Render results as a Spectre table (name, description, language, tags, publisher, verified badge).
- Honor `--language`, `--limit`, paging via `--cursor` or auto-page-on-demand (decide which).
- Tests: end-to-end with a faked catalog response; verify rendering, filtering, and pagination.

### Phase 4: `aspire template refresh`

- Force-refresh both the index cache and (optionally) any pre-fetched repo checkouts.
- Decide whether refresh is global or accepts a `--template ` filter.
- Tests: confirm cache invalidation observable in subsequent `list` calls.

### Phase 5: `aspire template new [path]` (single-template, .NET only)

- Resolve `` against the catalog → `(repo, ref, path)`.
- Clone or fetch into the content-addressed `repos/` cache; checkout the resolved sha.
- Apply the template via the existing dotnet template engine path (per-template manifest in spec §4 and §7).
- Stay .NET-only for this phase; defer polyglot to phase 6.
- Tests: full flow against a local fake git server (or git file:// remote in a temp dir); verify content lands on disk and engine variables are wired.

### Phase 6: Polyglot engine support

- Implement the language-agnostic template engine described in spec §11 (token replacement, file renaming, conditional inclusion).
- Honor per-template manifest opting into the polyglot engine instead of the dotnet template engine.
- Tests: end-to-end with a representative non-.NET template (Node, Python, etc.).

## Cross-cutting open questions (spec §13)

These need answers before / alongside the phases above:

- Final shape of the `aspire.dev/templates/index.json` response. Current schema in spec §3 is a placeholder.
- Catalog governance: who decides what gets listed, how malicious entries are removed, signing strategy (security review TBD; spec §10 currently has a `TODO`).
- Cache size budget + eviction policy.
- Whether the catalog host is literally `aspire.dev` or some other domain.
- Telemetry: what events to emit on list/search/new for catalog feedback.

## References

- Spec: [`docs/specs/git-templates.md`](https://github.com/microsoft/aspire/blob/main/docs/specs/git-templates.md)
- Phase 1 PR: #16927
- Original spike: #14763

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.