#1017·eShop

Aspire deployment skill recommends duplicate restore and JavaScript install/build work

Author: fowl2Created Aug 27, 2026Updated Aug 27, 2026

Summary

The Aspire deployment skill's CI/CD guidance recommends restoring/building the .NET workspace and installing/building JavaScript resources before invoking aspire deploy. For a C# AppHost containing an Aspire JavaScript resource, this can duplicate work that the Aspire deployment pipeline performs by default.

Source:

Conflicting guidance

The generic workflow guidance says:

C# AppHost or .NET project resources: Install .NET with actions/setup-dotnet, then use the repo's restore/build command.

and provides:

yaml
- name: Restore and build .NET workspace
  run: |
    dotnet restore
    dotnet build --no-restore

It similarly recommends npm ci and npm run build --if-present for JavaScript resources. For a mixed C#/JavaScript graph, it says to use both setup blocks.

However:

  1. The aspire deploy CLI reference documents --no-build as:

    Don’t build or restore the AppHost project before running the command. Use this when you’ve already built the AppHost (for example, in a CI step) and want to skip the implicit build.

    Therefore, running an explicit build and then aspire deploy without --no-build builds/restores the AppHost twice.

  2. The JavaScript AppHost documentation says package managers automatically install dependencies during publishing and that npm uses npm ci when a package-lock.json exists.

    Therefore, running npm ci before deploying a JavaScript resource can repeat dependency installation. An explicit frontend build may also repeat the JavaScript publish build.

  3. The checked-in C# Azure example already omits explicit dotnet restore/dotnet build and relies on aspire deploy, which is inconsistent with the generic setup table.

Real-world impact

Following the generic mixed-workspace guidance produced an Azure Pipelines deployment that ran:

npm ci
dotnet restore <AppHost.csproj>
aspire deploy <AppHost.csproj>

The AppHost used AddViteApp(...) and consumed its output with PublishWithContainerFiles(...). Aspire then installed and built the frontend as part of deployment, making the explicit preparation steps redundant and increasing deployment time.

Suggested improvement

Clarify the two supported patterns:

  1. Aspire-owned preparation: install only the required SDK/toolchains, then run aspire deploy and allow it to restore/build the AppHost and install/build JavaScript resources.
  2. CI-owned preparation: explicitly restore/build first, then invoke aspire deploy --no-build; clarify whether and how JavaScript resource installation/build should be disabled or reused to avoid duplicate work.

For C# AppHosts with JavaScript resources, the default example should preferably demonstrate the first pattern. The TypeScript AppHost case should be documented separately because installing the AppHost's own Node dependencies may still be required before the CLI can evaluate it.

Related caching guidance

It may also be useful for the CI/CD reference to link to deployment state caching and warn that --clear-cache clears environment-specific state and prevents saving it, so it should generally be reserved for deliberate cache resets rather than normal CI deployments.


Disclosure: This issue was researched, drafted, and submitted by GitHub Copilot through the VS Code coding-agent harness on the reporter's behalf.