Skip to content

Share generated integration closure infrastructure - #19915

Open
David Negstad (danegsta) wants to merge 11 commits into
mainfrom
danegsta/shared-integration-closure-model
Open

Share generated integration closure infrastructure#19915
David Negstad (danegsta) wants to merge 11 commits into
mainfrom
danegsta/shared-integration-closure-model

Conversation

@danegsta

@danegsta David Negstad (danegsta) commented Sep 3, 2026

Copy link
Copy Markdown
Member

Description

Polyglot AppHost paths previously generated and interpreted integration projects independently, making their project shape, closure manifests, output paths, project-reference discovery, and runtime setup prone to drift.

This change introduces shared CSharpProjectFile, IntegrationClosureBuilder, and IntegrationClosureEnvironment infrastructure. The generated project paths now use the same closure contract and cache layout, including project-reference assembly discovery.

This is the foundational PR for #19763, which adds shared NuGet restore-source and configuration composition plus restore hardening on top.

Fixes # (issue)

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 2dd71101-249d-428b-81e7-9b247b9b3a2a
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d38799a7-a99c-48c5-b45b-9d6594dd1830
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: d38799a7-a99c-48c5-b45b-9d6594dd1830
Copilot AI balanced review requested due to automatic review settings September 3, 2026 20:53
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 19915

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 19915"

@danegsta David Negstad (danegsta) changed the title danegsta/shared integration closure model Share generated integration closure infrastructure Sep 3, 2026
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Filesystem-path deduplication can omit references, explicit hosting overrides can conflict, and credential-bearing restore metadata remains persisted.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Centralizes generated integration project, restore-source, closure-manifest, cache-path, and runtime-environment infrastructure.

Changes:

  • Adds shared project and closure generation models.
  • Consolidates restore-source resolution and cache handling.
  • Expands tests for closure generation, source handling, and path normalization.
File summaries
File Description
src/Aspire.Cli/Projects/CSharpProjectFile.cs Adds generated C# project model.
src/Aspire.Cli/Projects/IntegrationClosureBuilder.cs Centralizes closure generation and reading.
src/Aspire.Cli/Projects/IntegrationClosureEnvironment.cs Centralizes integration environment setup.
src/Aspire.Cli/Projects/IntegrationRestoreSourceResolver.cs Consolidates restore-source resolution.
src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs Adopts shared closure and restore infrastructure.
src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs Uses the shared project model.
src/Aspire.Cli/Utils/CliPathHelper.cs Adds shared cache-path helpers.
tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs Extends prebuilt-server coverage.
tests/Aspire.Cli.Tests/Projects/AppHostServerProjectTests.cs Covers explicit-channel source selection.
Review details
  • Files reviewed: 9/9 changed files
  • Comments generated: 3
  • Review effort level: Balanced

Comment thread src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs Outdated
Comment thread src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs Outdated
Comment thread src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 3, 2026 21:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It changes shared restore, cache, generated-project, and runtime setup paths that warrant final human validation despite no definite defect found.

Review details
  • Files reviewed: 9/9 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 3, 2026 21:47
@github-actions

This comment has been minimized.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Generated projects can fail with NETSDK1022 because appsettings.json is emitted as a duplicate None Include item.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 9/9 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread src/Aspire.Cli/Projects/CSharpProjectFile.cs Outdated
Copilot AI review requested due to automatic review settings September 3, 2026 21:56
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: f88e5112-114e-41f8-af5a-930b169bc353
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Cache ownership across symlinks and manifest path preservation have correctness issues.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 8/8 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment thread src/Aspire.Cli/Projects/IntegrationClosureBuilder.cs Outdated
Comment thread src/Aspire.Cli/Projects/IntegrationClosureBuilder.cs Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: f88e5112-114e-41f8-af5a-930b169bc353
Copilot AI review requested due to automatic review settings September 3, 2026 22:06
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The central generated MSBuild contract lacks a build-backed test that verifies its targets and redirected outputs actually execute correctly.

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

src/Aspire.Cli/Projects/IntegrationClosureBuilder.cs:83

  • The new shared MSBuild contract is only checked as serialized XML. The project-reference tests stub BuildAsync and write the closure files directly (PrebuiltAppHostServerTests.cs:2867-2873, 2919-2955), so they cannot catch regressions in _ResolvedProjectReferencePaths, target execution, or the redirected obj/bin paths. Add a test that builds a minimal generated project with a local ProjectReference and verifies the emitted closure and project-reference files under the configured restore directory.
  • Files reviewed: 8/8 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: f88e5112-114e-41f8-af5a-930b169bc353
Copilot AI review requested due to automatic review settings September 3, 2026 22:35
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: f88e5112-114e-41f8-af5a-930b169bc353
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Cache ownership is incorrect when a workspace AppHost path is a symlink to an external directory.

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

src/Aspire.Cli/Projects/IntegrationClosureBuilder.cs:143

  • Canonicalizing appHostDirectory before workspace discovery changes cache ownership for symlinked AppHosts. If <workspace>/apphost points to a directory outside the workspace, GetIntegrationCacheDirectory starts from the external target, misses the workspace's aspire.config.json, and places the cache outside <workspace>/.aspire. Discover the cache root from the lexical path, canonicalize that root separately, and use the canonical AppHost path only for the hash.
  • Files reviewed: 8/8 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

Copilot AI review requested due to automatic review settings September 3, 2026 22:42
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The cross-platform cache and generated-MSBuild changes warrant final human validation despite no confirmed defects found.

Review details
  • Files reviewed: 8/8 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: f88e5112-114e-41f8-af5a-930b169bc353
Copilot AI review requested due to automatic review settings September 3, 2026 22:57
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Tests selector

2 / 99 PR test projects · 4 PR jobs · 1 advisory-only target, from 8 changed files.

Selected PR test projects (2 / 99)

Aspire.Cli.EndToEnd.Tests, Aspire.Cli.Tests

Selected PR jobs (4)

cli-starter-validation, extension-e2e, polyglot, typescript-api-compat

Advisory workflow impact (1)

  • deployment-e2e (schedule/dispatch-only)

How these were chosen — grouped by what changed

📦 affected project Aspire.Cli
1 test: Aspire.Cli.EndToEnd.Tests

🧪 tests/Aspire.Cli.Tests/Projects/AppHostServerProjectTests.cs (changed test)
1 directly: Aspire.Cli.Tests

🧪 tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs (changed test)
1 directly: Aspire.Cli.Tests

Job reasons

Job Triggered by
cli-starter-validation affected project Aspire.Cli
deployment-e2e affected project Aspire.Cli
extension-e2e src/Aspire.Cli/Projects/CSharpProjectFile.cs, src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs, src/Aspire.Cli/Projects/IntegrationClosureBuilder.cs, src/Aspire.Cli/Projects/IntegrationClosureEnvironment.cs, src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs, src/Aspire.Cli/Utils/CliPathHelper.cs, tests/Aspire.Cli.Tests/Projects/AppHostServerProjectTests.cs, tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs
• affected project Aspire.Cli
polyglot affected project Aspire.Cli
typescript-api-compat affected project Aspire.Cli

Selection computed for commit f8c1cc2.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The shared behavior is consistently integrated and covered by focused regression and build-contract tests.

Review details
  • Files reviewed: 8/8 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@danegsta

Copy link
Copy Markdown
Member Author

PR Testing Report

PR Information

Artifact Version Verification

  • Expected Commit: f8c1cc2353e7ec8c95b410bc4bd7772742d7b0a3
  • Installed CLI: 13.6.0-pr.19915.gf8c1cc23
  • Status: Verified

Changes Analyzed

Files Changed

  • src/Aspire.Cli/Projects/CSharpProjectFile.cs
  • src/Aspire.Cli/Projects/DotNetBasedAppHostServerProject.cs
  • src/Aspire.Cli/Projects/IntegrationClosureBuilder.cs
  • src/Aspire.Cli/Projects/IntegrationClosureEnvironment.cs
  • src/Aspire.Cli/Projects/PrebuiltAppHostServer.cs
  • src/Aspire.Cli/Utils/CliPathHelper.cs
  • tests/Aspire.Cli.Tests/Projects/AppHostServerProjectTests.cs
  • tests/Aspire.Cli.Tests/Projects/PrebuiltAppHostServerTests.cs

Change Categories

  • CLI project-generation and integration-closure changes
  • CLI unit and build-contract test changes
  • Hosting integration package changes
  • Dashboard changes
  • Template changes
  • VS Code extension changes
  • CI infrastructure changes

Test Scenarios Executed

Scenario 1: TypeScript AppHost with local C# integration

Objective: Verify that the PR CLI builds a local C# hosting integration through the shared generated closure, generates its TypeScript API, and starts a resource that uses the exported API.

Coverage Type: Happy path

Status: Passed

Steps:

  1. Initialized a TypeScript AppHost.
  2. Added a local MyIntegration.csproj project with an [AspireExport] extension method.
  3. Referenced the project from aspire.config.json.
  4. Started the AppHost with the PR CLI.
  5. Verified addMyParameter in .aspire/modules/aspire.mts.
  6. Described the resulting custom-param resource and verified it was healthy with value v1.

Evidence:

  • scenario-project-ref/start-v1.log
  • scenario-project-ref/generated-export-v1.txt
  • scenario-project-ref/describe-v1.json
  • scenario-project-ref/stop-v1.log
  • Generated closure under scenario-project-ref/.aspire/integrations/apphosts/39e239eb4955/integration-restore

Observations:

  • The generated integration project built successfully.
  • Redirected closure output contained MyIntegration.dll, MyIntegration.pdb, closure manifests, and project-ref-assemblies.txt.
  • TypeScript code generation exposed the exported method.
  • The AppHost started and the generated API produced a healthy parameter resource.

Scenario 2: Referenced integration refresh

Objective: Verify that changing the local integration invalidates and rebuilds the closure instead of retaining stale generated APIs.

Coverage Type: Boundary

Status: Passed

Steps:

  1. Added a new exported AddSecondParameter method to the same referenced project.
  2. Changed the AppHost to invoke addSecondParameter.
  3. Started the AppHost again.
  4. Verified addSecondParameter in the regenerated TypeScript module.
  5. Described refreshed-param and verified value v2.

Evidence:

  • scenario-project-ref/start-v2.log
  • scenario-project-ref/generated-export-v2.txt
  • scenario-project-ref/describe-v2.json

Observations:

  • The changed referenced project rebuilt successfully.
  • The generated API reflected the newly exported method.
  • The running resource model reflected the new implementation.

Scenario 3: Invalid referenced integration

Objective: Verify that a compile failure in the referenced project stops AppHost preparation and is not masked by the previously valid closure.

Coverage Type: Unhappy path

Status: Passed

Steps:

  1. Replaced the second method implementation with an unresolved DoesNotCompile() call.
  2. Started the AppHost.
  3. Verified a non-zero exit code.
  4. Captured the referenced-project compiler diagnostic.

Expected Outcome: AppHost preparation fails safely with the integration build diagnostic and does not start from stale generated output.

Evidence:

  • scenario-project-ref/start-invalid.log
  • scenario-project-ref/start-invalid.exitcode
  • scenario-project-ref/start-invalid-diagnostic.txt

Observations:

  • aspire start exited with code 2.
  • The AppHost did not start.
  • The detailed log reported CS0103 for DoesNotCompile in MyIntegration.csproj.

Environment Observation

The initial online npm install during aspire init took more than five minutes, and the first AppHost start timed out while a second npm install was waiting on the registry. This matches the NPM stalls observed in the PR CI run and a contemporaneous main run. After the already-installed dependency tree was reused with npm offline mode, all PR-specific closure, generation, startup, refresh, and failure-path checks completed. No failure was attributable to the PR.

Summary

Scenario Status Notes
Local C# integration happy path Passed Closure built, API generated, resource healthy
Referenced integration refresh Passed New export and implementation observed
Invalid referenced integration Passed Exit code 2 with expected CS0103; no stale startup

Overall Result

PR VERIFIED

The artifact matched the current PR head and all targeted shared-closure scenarios passed. The only delay was an external NPM registry stall also reproduced on main.

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants