Repository navigation
DotnetProjectResource publishing - #19997
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 19997Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 19997" |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
🟡 Changes recommended
Two critical and four moderate unresolved issues affect core publishing and runtime behavior.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Makes DotnetProjectResource publishable through the shared .NET SDK pipeline across supported deployment and framework integrations.
Changes:
- Adds shared .NET program publishing contracts and container/archive handling.
- Extends deployment, EF Core, and Blazor support to Project V2 resources.
- Adds publishing and polyglot SDK coverage.
Review findings:
- Critical (2 votes):
DotnetProgramPublishing.cs:55unnecessarily requires a container runtime for archive-only publishing. - Critical (1 vote):
DotnetProgramResourceBuilderExtensions.cs:28exposes replicas, but only one process is rendered. - Moderate (1 vote):
EFMigrationResourceBuilderExtensions.cs:284permits unsupported file-based migration projects. - Moderate (1 vote):
DotnetProgramPublishing.cs:280misclassifies dotted output directories as archive files. - Moderate (1 vote):
ResourceContainerImageManager.cs:728queries the container working directory withoutConfiguration=Release. - Moderate (1 vote):
ResourceContainerImageManager.cs:579can incorrectly attribute unrelated publishing failures to Native AOT.
File summaries
| File | Description |
|---|---|
tests/PolyglotAppHosts/Aspire.Hosting.EntityFrameworkCore/TypeScript/aspire.config.json |
Adds the Dotnet package. |
tests/PolyglotAppHosts/Aspire.Hosting.EntityFrameworkCore/TypeScript/apphost.mts |
Exercises Project V2 migrations. |
tests/PolyglotAppHosts/Aspire.Hosting.EntityFrameworkCore/Python/aspire.config.json |
Adds the Dotnet package. |
tests/PolyglotAppHosts/Aspire.Hosting.EntityFrameworkCore/Python/apphost.py |
Exercises Project V2 migrations. |
tests/PolyglotAppHosts/Aspire.Hosting.EntityFrameworkCore/Java/aspire.config.json |
Adds the Dotnet package. |
tests/PolyglotAppHosts/Aspire.Hosting.EntityFrameworkCore/Java/AppHost.java |
Exercises Project V2 migrations. |
tests/PolyglotAppHosts/Aspire.Hosting.Dotnet/TypeScript/apphost.mts |
Exercises new fluent APIs. |
tests/PolyglotAppHosts/Aspire.Hosting.Dotnet/Python/apphost.py |
Exercises new fluent APIs. |
tests/PolyglotAppHosts/Aspire.Hosting.Dotnet/Java/AppHost.java |
Exercises new fluent APIs. |
tests/PolyglotAppHosts/Aspire.Hosting.Dotnet/Go/apphost.go |
Exercises new fluent APIs. |
tests/Aspire.Hosting.Tests/Publishing/ResourceContainerImageManagerTests.cs |
Tests archive publishing, layering, and diagnostics. |
tests/Aspire.Hosting.Tests/ProjectResourceTests.cs |
Updates shared publishing tests. |
tests/Aspire.Hosting.Tests/DotnetProgramPublishingTests.cs |
Tests shared publishing contracts. |
tests/Aspire.Hosting.Radius.Tests/RadiusExtensionsTests.cs |
Tests Project V2 image association. |
tests/Aspire.Hosting.Radius.Tests/Publishing/BicepGenerationSimpleTests.cs |
Tests Radius validation. |
tests/Aspire.Hosting.Radius.Tests/Aspire.Hosting.Radius.Tests.csproj |
References Dotnet integration. |
tests/Aspire.Hosting.Kubernetes.Tests/KubernetesPublisherTests.cs |
Tests Project V2 Kubernetes publishing. |
tests/Aspire.Hosting.Kubernetes.Tests/Aspire.Hosting.Kubernetes.Tests.csproj |
References Dotnet integration. |
tests/Aspire.Hosting.Foundry.Tests/HostedAgentExtensionTests.cs |
Tests hosted-agent publishing. |
tests/Aspire.Hosting.Foundry.Tests/Aspire.Hosting.Foundry.Tests.csproj |
References Dotnet integration. |
tests/Aspire.Hosting.EntityFrameworkCore.Tests/Aspire.Hosting.EntityFrameworkCore.Tests.csproj |
References Dotnet integration. |
tests/Aspire.Hosting.EntityFrameworkCore.Tests/AddEFMigrationsTests.cs |
Tests generalized migration resources. |
tests/Aspire.Hosting.Dotnet.Tests/DotnetProjectResourceTests.cs |
Tests manifests and archive builds. |
tests/Aspire.Hosting.Dotnet.Tests/DotnetProjectPublicApiTests.cs |
Verifies publishing interfaces. |
tests/Aspire.Hosting.Dotnet.Tests/DotnetProjectBuildEnvironmentTests.cs |
Verifies build-environment providers. |
tests/Aspire.Hosting.Docker.Tests/DockerComposePublisherTests.cs |
Tests Compose Project V2 output. |
tests/Aspire.Hosting.Docker.Tests/Aspire.Hosting.Docker.Tests.csproj |
References Dotnet integration. |
tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts |
Updates the generated TypeScript snapshot. |
tests/Aspire.Hosting.CodeGeneration.Rust.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.rs |
Updates the generated Rust snapshot. |
tests/Aspire.Hosting.CodeGeneration.Python.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.py |
Updates the generated Python snapshot. |
tests/Aspire.Hosting.CodeGeneration.Java.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.java |
Updates the generated Java snapshot. |
tests/Aspire.Hosting.CodeGeneration.Go.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.go |
Updates the generated Go snapshot. |
tests/Aspire.Hosting.Blazor.Tests/BlazorHostedExtensionsTests.cs |
Tests Project V2 proxying. |
tests/Aspire.Hosting.Blazor.Tests/AddDotnetProjectBlazorGatewayTests.cs |
Tests gateway publishing support. |
tests/Aspire.Hosting.Azure.Tests/AzureSandboxesTests.cs |
Tests sandbox endpoint handling. |
tests/Aspire.Hosting.Azure.Tests/AzureContainerAppsTests.cs |
Tests Container Apps targeting. |
tests/Aspire.Hosting.Azure.Tests/AzureAppServiceTests.cs |
Tests App Service targeting. |
tests/Aspire.Hosting.Azure.Tests/Aspire.Hosting.Azure.Tests.csproj |
References Dotnet integration. |
src/Shared/MsBuildResponseFile.cs |
Extracts shared response-file support. |
src/Aspire.Hosting/Publishing/ResourceContainerImageManager.cs |
Generalizes SDK image building. |
src/Aspire.Hosting/Publishing/ManifestPublishingContext.cs |
Emits generalized project manifests. |
src/Aspire.Hosting/ExecutableResourceBuilderExtensions.cs |
Adjusts Dockerfile project defaults. |
src/Aspire.Hosting/DotnetProgramResourceBuilderExtensions.cs |
Adds common fluent APIs. |
src/Aspire.Hosting/Dcp/DcpNameGenerator.cs |
Adds .NET program replica names. |
src/Aspire.Hosting/Ats/CoreExports.cs |
Enables the experimental contract. |
src/Aspire.Hosting/Ats/AtsTypeMappings.cs |
Exports the shared ATS contract. |
src/Aspire.Hosting/Aspire.Hosting.csproj |
Includes shared response-file code. |
src/Aspire.Hosting/ApplicationModel/ResourceExtensions.cs |
Generalizes endpoint and build checks. |
src/Aspire.Hosting/ApplicationModel/ProjectResourceExtensions.cs |
Adds shared metadata helpers. |
src/Aspire.Hosting/ApplicationModel/ProjectResource.cs |
Adopts shared publishing support. |
src/Aspire.Hosting/ApplicationModel/IDotnetProgramResource.cs |
Defines the common .NET resource contract. |
src/Aspire.Hosting/ApplicationModel/IDotnetProgramBuildEnvironmentProvider.cs |
Defines build-environment providers. |
src/Aspire.Hosting/ApplicationModel/DotnetProgramPublishingAnnotation.cs |
Marks configured publishers. |
src/Aspire.Hosting/ApplicationModel/DotnetProgramPublishing.cs |
Implements the shared publishing pipeline. |
src/Aspire.Hosting/ApplicationModel/DistributedApplicationModelExtensions.cs |
Generalizes compute selection. |
src/Aspire.Hosting/ApplicationModel/ContainerImageReference.cs |
Supports explicit archive paths. |
src/Aspire.Hosting/ApplicationModel/ArgumentsExecutionConfigurationGatherer.cs |
Omits launch-tool arguments during publishing. |
src/Aspire.Hosting.Radius/ResourceMapping/ResourceTypeMapper.cs |
Maps .NET programs as projects. |
src/Aspire.Hosting.Radius/RadiusExtensions.cs |
Generalizes image association. |
src/Aspire.Hosting.Radius/Publishing/RadiusInfrastructureBuilder.cs |
Handles .NET program resources. |
src/Aspire.Hosting.Kubernetes/KubernetesResource.cs |
Uses generalized build detection. |
src/Aspire.Hosting.Foundry/HostedAgent/HostedAgentBuilderExtension.cs |
Preserves SDK publishing targets. |
src/Aspire.Hosting.EntityFrameworkCore/README.md |
Documents Project V2 migrations. |
src/Aspire.Hosting.EntityFrameworkCore/EFResourceBuilderExtensions.cs |
Generalizes migration startup resources. |
src/Aspire.Hosting.EntityFrameworkCore/EFMigrationResourceBuilderExtensions.cs |
Generalizes migration-project dispatch. |
src/Aspire.Hosting.EntityFrameworkCore/EFMigrationResource.cs |
Adds the common startup-project property. |
src/Aspire.Hosting.EntityFrameworkCore/EFCoreOperationExecutor.cs |
Accepts common .NET programs. |
src/Aspire.Hosting.Dotnet/README.md |
Documents publishing behavior. |
src/Aspire.Hosting.Dotnet/DotnetProjectResource.cs |
Implements publishing contracts. |
src/Aspire.Hosting.Dotnet/DotnetProjectHostingExtensions.cs |
Configures publishing and polyglot APIs. |
src/Aspire.Hosting.Dotnet/DotnetProjectBuildEnvironmentCallbackAnnotation.cs |
Adopts the shared environment provider. |
src/Aspire.Hosting.Dotnet/DotnetProjectBuildCoordinator.cs |
Enables the shared experimental contract. |
src/Aspire.Hosting.Dotnet/Aspire.Hosting.Dotnet.csproj |
Includes shared response-file code. |
src/Aspire.Hosting.Docker/DockerComposeServiceResource.cs |
Recognizes publishable .NET programs. |
src/Aspire.Hosting.Blazor/BlazorHostedExtensions.cs |
Generalizes hosted Blazor APIs. |
src/Aspire.Hosting.Blazor/BlazorGatewayExtensions.cs |
Enables Project V2 gateway publishing. |
src/Aspire.Hosting.Azure.Sandboxes/AzureSandboxContainerDeployment.cs |
Generalizes .NET endpoint handling. |
src/Aspire.Hosting.Azure.AppService/AzureAppServiceEnvironmentResource.cs |
Targets publishable .NET programs. |
src/Aspire.Hosting.Azure.AppContainers/ContainerAppContext.cs |
Applies .NET deployment defaults. |
docs/plans/project-v2-csharpprogram-watch.md |
Updates the Project V2 plan. |
Review details
- Files reviewed: 80/80 changed files
- Comments generated: 6
- Review effort level: Balanced
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
🟡 Changes recommended
Explicit non-gzip archive output can fail when staging and destination paths reside on different filesystems.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 93/93 changed files
- Comments generated: 1
- Review effort level: Balanced
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
Karol Zadora-Przylecki (karolz-ms)
left a comment
There was a problem hiding this comment.
Review of the shared .NET SDK publishing pipeline and the DotnetProjectResource publish enablement.
Issues found: 1 correctness regression, 2 test-coverage gaps, 2 test-convention problems.
| # | Severity | Location | Problem |
|---|---|---|---|
| 1 | Blocking | ResourceContainerImageManager.cs:768 |
Multi-RID RuntimeIdentifiers broken by the Arguments -> ArgumentList refactor (MSB1006) |
| 2 | Coverage | ResourceContainerImageManagerTests.cs:1072 |
No multi-platform regression test, so #1 passes CI |
| 3 | Coverage | DistributedApplicationModelExtensions.cs:29 |
New deployment routing has no deployment E2E coverage |
| 4 | Convention | DockerComposePublisherTests.cs:166 |
Generated YAML asserted with Assert.Contains instead of Verify; assertion is near-vacuous |
| 5 | Convention | KubernetesPublisherTests.cs:761 |
Generated Helm output asserted with Assert.Contains instead of Verify |
Item 1 was reproduced locally against SDK 10.0.303; details are in the inline comment. The previously reported File.Move cross-device issue in DotnetProgramPublishing.MoveArchiveAsync still appears unaddressed, but I have not duplicated it here.
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
Karol Zadora-Przylecki (karolz-ms)
left a comment
There was a problem hiding this comment.
Two correctness issues in the Project V2 EF Core integration: startup migrations can bypass the coordinated build, and EF commands do not receive the startup project's build-only properties.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
🟡 Changes recommended
Radius prebuilt-image resources still execute the shared SDK build and push pipeline, contradicting the API contract and potentially failing deployments.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 121/121 changed files
- Comments generated: 1
- Review effort level: Balanced
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
Karol Zadora-Przylecki (karolz-ms)
left a comment
There was a problem hiding this comment.
Review of the shared .NET SDK publishing pipeline at 45970e9, focused on what the earlier rounds left open.
Issues found: 2 (1 correctness gap in MSBuild argument construction, 1 latent cancellation defect).
| # | Severity | Location | Problem |
|---|---|---|---|
| 1 | Moderate | ResourceContainerImageManager.cs:489 |
/p: switches other than RuntimeIdentifiers are still raw interpolations, so ; or % in a user-supplied ContainerArchiveOutputPath is re-split/unescaped by MSBuild |
| 2 | Low | ContainerRuntimeReadiness.cs:28 |
The cached readiness check captures the first caller's token, so that caller's cancellation propagates to every other waiter |
Verified as not problems while reviewing, recording them so they don't get re-raised:
AddDotnetProject(...).PublishAsDockerFile()does not double-build.PublishAsDockerFileremoves the resource from the model, and becauseExecutableContainerResourceshares the original annotation collection,EnsureBuildAndPushPipelineAnnotationsusesResourceAnnotationMutationBehavior.Replaceand displaces the SDK-publishingPipelineStepAnnotation.- Staged archive filenames agree between
LayerContainerFilesAsyncand both container runtimes: the runtimes receivename:tag, whichFlattenContainerImageNamecollapses to the samename-tag.tarthe staging path computes. No double gzip either, sinceGetContainerImageArchivePathalways yields.tar. - The newly publishable
AddDotnetProjectBlazorGatewaywill not hit cross-OS Native AOT:Scripts/Gateway.cs.inalready declares#:property PublishAot=false. ResourceTypeMapper's newIDotnetProgramResourcefallback is reachable, becauseExecutableResourceis absent froms_typeMappingsand the hierarchy walk falls through.
Copilot's Radius finding (WithContainerImage leaving DotnetProgramPublishingAnnotation in place, so RequiresImageBuild() still dispatches prebuilt-image resources into the SDK build/push pipeline) still appears unaddressed.
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
Karol Zadora-Przylecki (karolz-ms)
left a comment
There was a problem hiding this comment.
One correctness issue: publish-time EF migration-script generation can use missing or stale assemblies for path-based .NET projects.
Preserve the Verify snapshot ending while resolving the stack rebase conflict. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
🟡 Changes recommended
OCI local-image publishing can skip required container-runtime readiness when no archive output path is configured.
Get a fresh assessment by requesting another Copilot review.
Review details
- Files reviewed: 146/146 changed files
- Comments generated: 1
- Review effort level: Balanced
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
Karol Zadora-Przylecki (karolz-ms)
left a comment
There was a problem hiding this comment.
Reviewed the full change set at 098487ae against main (merge-base 9f2d9f7f), with the PR branch checked out locally.
Four findings, all in new code paths — no blocking correctness or security issues found in the core publishing pipeline, archive rewriter, or app-model changes:
- Compatibility (2):
docker image save --platformraises the effective Docker Engine floor to 28+; multi-platform targets combined with container-file layering lose the actionable error that the OCI case gets. - Documentation accuracy (1): both READMEs still say only bundle generation drops
--no-build, but publish-time script generation now builds too. - Cleanup consistency (1): the temporary Dockerfile is deleted on failed archive builds, making the "left for debugging" branch unreachable.
I also replied on the one open Copilot thread (ResourceContainerImageManager.cs:913) — that one reads like a false positive; options.OutputPath is null makes the method return true for OCI without an output path.
Separately verified and found no problems with: the OCI/Docker/legacy archive naming rewriter and its alias handling, MSBuild response-file escaping, DCP replica instance naming for IDotnetProgramResource, the RequiresImageBuild/HasPrebuiltContainerImage refactor across Compose/Kubernetes/ACA/App Service/Radius/Foundry, the EF BeforeStartEvent path (fire-and-forget, so the new build barrier can't deadlock), and the test-trigger-map.yml routing for the new runtime package consumers.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
🟡 Changes recommended
Prebuilt .NET images combined with container-file publishing silently omit the requested files.
Get a fresh assessment by requesting another Copilot review.
Review details
- Files reviewed: 146/146 changed files
- Comments generated: 1
- Review effort level: Balanced
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
🔵 Needs a closer look
The generated EF polyglot contract still excludes DotnetProjectResource from the migrations-project parameter.
Review details
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
src/Aspire.Hosting.EntityFrameworkCore/EFMigrationResourceBuilderExtensions.cs:278
- The exported union still does not admit Project V2 resources. The generated ATS snapshot at
src/Aspire.Hosting.EntityFrameworkCore/api/Aspire.Hosting.EntityFrameworkCore.ats.txt:34resolves this parameter tostring|ProjectResource, so generated TypeScript/Python/Java/etc. callers cannot pass aDotnetProjectResourcehere despite the CLR switch acceptingIDotnetProgramResource. Please expose an ATS-compatible cross-package capability/adapter and add a fixture that passesdotnetApias the migrations project.
- Files reviewed: 147/147 changed files
- Comments generated: 0 new
- Review effort level: Balanced
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Regarding the finding in #19997 (review): This finding is invalid, so no production change was made for it. The cited The live PR source exports Commit 9a45d17 fixes the separate PR-caused CI test-state leak; it does not alter the EF/ATS implementation because that implementation is already correct. |
Tests selector57 / 99 PR test projects · 4 PR jobs, from 143 changed files. Selected PR test projects (57 / 99)
Selected PR jobs (4)
How these were chosen — grouped by what changed
🧪 show 27
🧪 🔧 🔧 🔧 🧪 📦 affected project 📄 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 Job reasons
Selection computed for commit |
There was a problem hiding this comment.
🔵 Needs a closer look
The cross-cutting publishing and deployment changes span 147 files and multiple production backends, warranting final human sign-off despite extensive coverage.
Review details
- Files reviewed: 147/147 changed files
- Comments generated: 0 new
- Review effort level: Balanced
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
Description
AddDotnetProject()resources currently fail when an AppHost is published, even though equivalent C# projects modeled withAddProject()are publishable. This change makesDotnetProjectResourcepublishable across the same SDK-container and deployment scenarios while preserving the Project V2 build, launch, and debugging model introduced by #19678.The implementation:
IDotnetProgramResourcecross-package contract and shared .NET SDK publishing pipeline used by bothProjectResourceandDotnetProjectResource.EFMigrationResource.StartupProjectResourceis the new common contract; the legacyProjectResourceproperty remains available for legacy resources and is marked obsolete.User-facing usage
C# AppHost:
TypeScript AppHost:
These resources now participate in
aspire publishand deployment publishers without requiring conversion back to the legacyAddProject()model.Validation
Aspire.Hosting.Tests: 3,525 total, 3,520 passed, 5 platform skips, with MTP hang-dump protection.13.6.0-devpackages.Fixes # (issue)
Checklist
<remarks />and<code />elements on your triple slash comments?