Skip to content

Persist --source from aspire new aspire-empty into the scaffolded project #17239

@radical

Description

@radical

Persist the --source override from aspire new aspire-empty into the scaffolded project

Summary

aspire new aspire-empty --language <typescript|...> --source <X> consumes --source only during the initial scaffold restore. The scaffolded project records the version and channel in aspire.config.json but does not capture the explicit --source feed. As a result, a later aspire restore or aspire add in the same project resolves Aspire packages from the configured channel feeds — not from <X> — and silently produces a different package set (or fails outright) compared with what the scaffold restore used.

PR #17166 ships a warning at scaffold time so the user is told the override is one-shot. This issue tracks closing the gap so --source is honored across the full lifecycle of the project, or rejected up front when that's not possible.

Repro

# Hive lives outside the standard channel feeds; user wants Aspire packages from there.
aspire new aspire-empty --language typescript --name MyApp --output ./MyApp \
    --version 13.4.0-pr.NNNNN.gXXXXXXXX \
    --source /path/to/pr-hive/packages

# Scaffold succeeds.

cd MyApp
aspire add redis     # ← does NOT see /path/to/pr-hive/packages
aspire restore       # ← same: only the channel feeds in aspire.config.json

For the C# empty path the gap is even larger: --source is dropped before scaffolding runs at all (the C# template ignores inputs.Source), so the initial restore also misses the override.

Why it matters

--source is the primary lever a user has to point Aspire at a non-default package set (PR hive, local pack, internal mirror). Honoring it only on the very first command surprises anyone who runs a follow-up CLI command in the same project — the natural next step.

Options

(a) Generate nuget.config in the scaffolded project

Write a nuget.config next to aspire.config.json that:

  • Adds the explicit --source as a package source.
  • Adds the matching channel feeds as additional sources.
  • Emits package source mapping (PSM) that pins Aspire* to the explicit source.

Pros: subsequent aspire restore/aspire add resolve packages identically to the scaffold restore. The Aspire CLI already generates this exact shape today via TemporaryNuGetConfig — the same logic can be redirected at the project directory instead of a temp file.

Cons:

  • Has to interact correctly with an existing nuget.config in the parent directory tree (merge vs override).
  • Credentials in a private feed (--source https://user:pat@…) probably should not be committed; need a story for that (interactive prompt? sanitize?).
  • Adds a file to source control that needs to be kept in sync if the channel changes later.

(b) Warn at scaffold time (shipped in #17166)

Tell the user the override is one-shot so they can take action manually (add the feed to their own nuget.config, or move the packages to a channel feed). Lowest-friction, no design risk, but doesn't solve the underlying gap.

(c) Reject at scaffold time when the override is not also a registered channel

Fail aspire new --source <X> unless <X> matches one of the explicit channels. Highest correctness, lowest convenience — the common dogfood case (point me at this PR's hive) becomes a two-step setup.

(d) Also honor --source on the C# empty path

Today the C# empty template (WriteCSharpEmptyAppHostAsync) ignores inputs.Source entirely. Whichever direction (a)/(c) is chosen above, the C# path should match.

Suggested direction

Lean toward (a) + (d): emit nuget.config with PSM and apply it to both C# and non-C# empty templates. Pair with the existing TemplateNuGetConfigService path so the same prompt + merge behavior applies regardless of language. Handle credential-bearing source URIs by stripping userinfo from the persisted form and warning the user that auth has to be configured separately.

Out of scope

Refs

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-area-labelAn area label is needed to ensure this gets routed to the appropriate area ownerstriage:bot-seenAspire triage bot has seen this issue

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions