Adjust TypeScript AppHost package scaffolding#16895
Conversation
Remove generated ESLint configuration and lint scripts from TypeScript AppHost scaffolding so brownfield projects do not get new lint behavior injected by aspire init. Move vscode-jsonrpc to devDependencies with the rest of the AppHost tooling. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 16895Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 16895" |
There was a problem hiding this comment.
Pull request overview
Adjusts the TypeScript AppHost scaffolding output so aspire init doesn’t inject ESLint/linting behavior into existing JS/TS repositories, and aligns the generated package.json dependency shape with “tooling-only” expectations.
Changes:
- Removed generation of
eslint.config.mjs, removedaspire:lint(and relatedlint/pre*) scripts, and stopped scaffoldingeslint/typescript-eslint. - Moved
vscode-jsonrpcfromdependenciestodevDependenciesin the scaffoldedpackage.jsonoutput. - Updated scaffold and package merge tests to reflect the new package shape and script set.
Show a summary per file
| File | Description |
|---|---|
| src/Aspire.Hosting.CodeGeneration.TypeScript/TypeScriptLanguageSupport.cs | Updates TypeScript AppHost scaffold output to remove ESLint config/scripts and move vscode-jsonrpc to devDependencies. |
| src/Aspire.Cli/Scaffolding/PackageJsonMerger.cs | Updates comments describing Node engines enforcement rationale (now focused on TS AppHost tooling). |
| tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/TypeScriptLanguageSupportTests.cs | Updates scaffold expectations: no ESLint files/scripts/deps; dependencies omitted; vscode-jsonrpc in devDependencies. |
| tests/Aspire.Cli.Tests/Scaffolding/PackageJsonMergerTests.cs | Updates merge tests to expect vscode-jsonrpc under devDependencies and no aspire:lint in relevant scaffolds. |
Copilot's findings
- Files reviewed: 4/4 changed files
- Comments generated: 1
Preserve existing package dependency placement when scaffolded devDependencies already exist under dependencies, upgrading in place instead of adding a duplicate entry. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
4cf6f27 to
41ba145
Compare
Pass an open scaffold options bag through the CLI/RPC scaffolding path and let TypeScript project it into typed options. Disable linting for init while keeping it enabled for greenfield TypeScript empty AppHost creation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
41ba145 to
67d4274
Compare
Create TypeScript AppHosts for existing package.json projects in a nested aspire-apphost package and add root scripts that delegate to it. Remove the scaffold options RPC plumbing that only toggled linting because the isolated package now owns AppHost package semantics. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use pnpm install --ignore-workspace for generated TypeScript AppHost dependency installation so nested brownfield AppHost packages do not depend on being listed in a parent pnpm workspace. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Re-running the failed jobs in the CI workflow for this pull request because 1 job was identified as retry-safe transient failures in the CI run attempt.
|
|
Re-running the failed jobs in the CI workflow for this pull request because 1 job was identified as retry-safe transient failures in the CI run attempt.
|
Brownfield TypeScript monorepo smoke resultsI tested
The main brownfield issue this PR avoids is package-scope leakage. The generated TypeScript AppHost currently uses top-level await, so if The pnpm-specific wrinkle is that One product question remains separate from this PR shape: generated |
IEvangelist
left a comment
There was a problem hiding this comment.
Reviewed the changes for isolating the brownfield TypeScript AppHost into a nested aspire-apphost/ package. Core design is solid — the package-boundary approach cleanly fixes the JS/TS leakage problem, the merger dedup logic correctly handles vscode-jsonrpc moving from dependencies to devDependencies, and the test coverage (including the new DevDependencyAlreadyInDependencies_IsNotDuplicated regression test and the ScaffoldingService directory-selection tests) is good.
Approving with 2 minor follow-up suggestions inline — both are minor and non-blocking.
Show the nested AppHost path in init success output and give generated brownfield AppHost packages a distinct package name to avoid workspace name collisions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@IEvangelist thanks for the review. I accepted both follow-up suggestions and pushed fixes for the nested init success path and distinct brownfield AppHost package name in 214f4fb. |
Accept the nested AppHost creation message in the brownfield TypeScript CLI E2E test while keeping compatibility with the older root-level message used by released CLI runs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Wait directly for the nested AppHost creation message now that brownfield TypeScript init reports the generated relative path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🎬 CLI E2E Test Recordings — 78 recordings uploaded (commit View all recordings
📹 Recordings uploaded automatically from CI run #25715542248 |
|
End-to-end test of this PR against 1. Trailing newline stripped from root
|
|
Attempting to solve it while introducing .mts files in this PR |
Summary
This updates TypeScript AppHost scaffolding so brownfield
aspire init --language typescriptno longer turns the existing app package into the AppHost package.aspire-apphost/package that ownsapphost.ts,.modules/,tsconfig.apphost.json, AppHost dependencies, ESM metadata, and ESLint configuration.package.jsonkeeps the user's app semantics and only getsaspire:*delegate scripts, e.g.npm --prefix aspire-apphost run aspire:start.pnpmAppHost installs run with--ignore-workspaceso a nestedaspire-apphost/package can install its own dependencies even when the user'spnpm-workspace.yamldoes not include it.aspire-apphostto avoid duplicate package names if it is later included in a workspace.aspire initnow reports the nested AppHost path in success output, e.g.Created aspire-apphost/apphost.ts.dependenciesanddevDependencies.Validation
./restore.sh./dotnet.sh test --project tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.csproj --no-launch-profile -- --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"./dotnet.sh test --project tests/Aspire.Cli.Tests/Aspire.Cli.Tests.csproj --no-launch-profile -- --filter-class "*.ScaffoldingServiceTests" --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"./dotnet.sh test --project tests/Aspire.Cli.Tests/Aspire.Cli.Tests.csproj --no-launch-profile -- --filter-class "*.PackageJsonMergerTests" --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"./dotnet.sh test --project tests/Aspire.Cli.Tests/Aspire.Cli.Tests.csproj --no-launch-profile -- --filter-class "*.TypeScriptAppHostToolchainResolverTests" --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"./dotnet.sh test --project tests/Aspire.Cli.Tests/Aspire.Cli.Tests.csproj --no-launch-profile -- --filter-method "*.InitCommand_WhenTypeScriptSelected_CreatesAppHostAndAspireConfig" --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"./dotnet.sh test --project tests/Aspire.Cli.Tests/Aspire.Cli.Tests.csproj --no-launch-profile -- --filter-method "*.InitCommand_WhenTypeScriptSelected_CreatesAppHostAndAspireConfig" --filter-method "*.InitCommand_WhenBrownfieldTypeScriptSelected_DisplaysNestedAppHostPath" --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"./dotnet.sh test --project tests/Aspire.Cli.Tests/Aspire.Cli.Tests.csproj --no-launch-profile -- --filter-method "*.NewCommandWithoutTemplateCanCreateTypeScriptEmptyTemplate" --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"./dotnet.sh test --project tests/Aspire.Cli.EndToEnd.Tests/Aspire.Cli.EndToEnd.Tests.csproj --no-launch-profile -- --filter-method "*.InitTypeScriptAppHost_AugmentsExistingViteRepoAtRoot" --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true" --hangdump --hangdump-timeout 8mLocalHive manual smoke matrix with the rebuilt CLI archive: CommonJS npm turborepo, ESM npm turborepo, and CommonJS pnpm turborepo.
./dotnet.sh build tests/Aspire.Cli.EndToEnd.Tests/Aspire.Cli.EndToEnd.Tests.csproj --no-restore