From 14583a32f12008728e189797d810a7c630d671f6 Mon Sep 17 00:00:00 2001 From: David Pine <7679720+IEvangelist@users.noreply.github.com> Date: Tue, 2 Jun 2026 13:14:41 -0500 Subject: [PATCH] Update Aspire samples for 13.3 APIs Add browser-log instrumentation to frontend samples, refresh selected JavaScript publishing patterns, bind deployable resources to compute environments, update the Azure Functions sample overload, refresh custom resource APIs, and remove redundant AppHost package references. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../MetricsApp.AppHost.csproj | 1 - .../AspireShop.AppHost.csproj | 1 - .../Directory.Packages.props | 1 - .../ImageGallery.AppHost/AppHost.cs | 6 +++-- .../ImageGallery.AppHost.csproj | 1 - .../AspireJavaScript.AppHost/AppHost.cs | 23 +++++++++++-------- .../AspireJavaScript.AppHost.csproj | 2 +- .../AspireWithNode.AppHost/AppHost.cs | 5 +++- .../AspireWithNode.AppHost.csproj | 2 +- samples/aspire-with-python/apphost.cs | 12 ++++++---- .../ClientAppsIntegration.AppHost.csproj | 1 - .../CustomResources.AppHost/AppHost.cs | 22 ++++++++++++++++++ .../CustomResources.AppHost.csproj | 1 - .../CustomResources.AppHost/TestResource.cs | 19 +++++++++++++++ .../DatabaseContainers.AppHost.csproj | 1 - .../DatabaseMigrations.AppHost.csproj | 1 - .../HealthChecksUI.AppHost/AppHost.cs | 8 +++++-- .../HealthChecksUI.AppHost.csproj | 1 - samples/image-gallery/README.md | 9 ++++---- samples/image-gallery/apphost.cs | 18 +++++++++------ samples/node-express-redis/apphost.mts | 8 +++++-- samples/node-express-redis/aspire.config.json | 1 + .../OrleansVoting.AppHost.csproj | 1 - samples/polyglot-task-queue/apphost.mts | 9 ++++++-- .../polyglot-task-queue/aspire.config.json | 1 + samples/rag-document-qa-svelte/apphost.mts | 3 ++- .../rag-document-qa-svelte/aspire.config.json | 1 + samples/vite-csharp-postgres/apphost.mts | 7 ++++-- .../vite-csharp-postgres/aspire.config.json | 1 + samples/vite-react-fastapi/apphost.mts | 7 ++++-- samples/vite-react-fastapi/aspire.config.json | 1 + samples/vite-yarp-static/apphost.mts | 6 +++-- samples/vite-yarp-static/aspire.config.json | 1 + .../VolumeMount.AppHost.csproj | 1 - .../DistributedApplicationExtensions.cs | 7 ++++++ 35 files changed, 137 insertions(+), 53 deletions(-) diff --git a/samples/Metrics/MetricsApp.AppHost/MetricsApp.AppHost.csproj b/samples/Metrics/MetricsApp.AppHost/MetricsApp.AppHost.csproj index 8bcd3fa64..35e4a9d7c 100644 --- a/samples/Metrics/MetricsApp.AppHost/MetricsApp.AppHost.csproj +++ b/samples/Metrics/MetricsApp.AppHost/MetricsApp.AppHost.csproj @@ -9,7 +9,6 @@ - diff --git a/samples/aspire-shop/AspireShop.AppHost/AspireShop.AppHost.csproj b/samples/aspire-shop/AspireShop.AppHost/AspireShop.AppHost.csproj index e1512f0a5..76d35b4ee 100644 --- a/samples/aspire-shop/AspireShop.AppHost/AspireShop.AppHost.csproj +++ b/samples/aspire-shop/AspireShop.AppHost/AspireShop.AppHost.csproj @@ -9,7 +9,6 @@ - diff --git a/samples/aspire-with-azure-functions/Directory.Packages.props b/samples/aspire-with-azure-functions/Directory.Packages.props index e2d0eb81d..7625da56f 100644 --- a/samples/aspire-with-azure-functions/Directory.Packages.props +++ b/samples/aspire-with-azure-functions/Directory.Packages.props @@ -3,7 +3,6 @@ true - diff --git a/samples/aspire-with-azure-functions/ImageGallery.AppHost/AppHost.cs b/samples/aspire-with-azure-functions/ImageGallery.AppHost/AppHost.cs index 1635d2dda..cc727fa38 100644 --- a/samples/aspire-with-azure-functions/ImageGallery.AppHost/AppHost.cs +++ b/samples/aspire-with-azure-functions/ImageGallery.AppHost/AppHost.cs @@ -2,7 +2,7 @@ var builder = DistributedApplication.CreateBuilder(args); -builder.AddAzureContainerAppEnvironment("env"); +var env = builder.AddAzureContainerAppEnvironment("env"); var storage = builder.AddAzureStorage("storage").RunAsEmulator() .ConfigureInfrastructure((infrastructure) => @@ -24,7 +24,8 @@ var blobs = storage.AddBlobs("blobs"); var queues = storage.AddQueues("queues"); -var functions = builder.AddAzureFunctionsProject("functions") +var functions = builder.AddAzureFunctionsProject("functions", "../ImageGallery.Functions/ImageGallery.Functions.csproj") + .WithComputeEnvironment(env) .WithReference(queues) .WithReference(blobs) .WaitFor(storage) @@ -37,6 +38,7 @@ .WithUrlForEndpoint("http", u => u.DisplayText = "Functions App"); builder.AddProject("frontend") + .WithComputeEnvironment(env) .WithReference(queues) .WithReference(blobs) .WaitFor(functions) diff --git a/samples/aspire-with-azure-functions/ImageGallery.AppHost/ImageGallery.AppHost.csproj b/samples/aspire-with-azure-functions/ImageGallery.AppHost/ImageGallery.AppHost.csproj index fc7b65a43..46a9cb0fe 100644 --- a/samples/aspire-with-azure-functions/ImageGallery.AppHost/ImageGallery.AppHost.csproj +++ b/samples/aspire-with-azure-functions/ImageGallery.AppHost/ImageGallery.AppHost.csproj @@ -15,7 +15,6 @@ - diff --git a/samples/aspire-with-javascript/AspireJavaScript.AppHost/AppHost.cs b/samples/aspire-with-javascript/AspireJavaScript.AppHost/AppHost.cs index dde2c2d52..d30b7b73e 100644 --- a/samples/aspire-with-javascript/AspireJavaScript.AppHost/AppHost.cs +++ b/samples/aspire-with-javascript/AspireJavaScript.AppHost/AppHost.cs @@ -1,4 +1,7 @@ -var builder = DistributedApplication.CreateBuilder(args); +#pragma warning disable ASPIREBROWSERLOGS001 +#pragma warning disable ASPIREJAVASCRIPT001 + +var builder = DistributedApplication.CreateBuilder(args); var weatherApi = builder.AddProject("weatherapi") .WithExternalHttpEndpoints(); @@ -9,7 +12,8 @@ .WaitFor(weatherApi) .WithHttpEndpoint(env: "PORT") .WithExternalHttpEndpoints() - .PublishAsDockerFile(); + .WithBrowserLogs() + .PublishAsStaticWebsite("/api", weatherApi, options => options.OutputPath = "dist/weather/browser"); builder.AddJavaScriptApp("react", "../AspireJavaScript.React", runScriptName: "start") .WithNpm(installCommand: "ci") @@ -18,7 +22,8 @@ .WithEnvironment("BROWSER", "none") // Disable opening browser on npm start .WithHttpEndpoint(env: "PORT") .WithExternalHttpEndpoints() - .PublishAsDockerFile(); + .WithBrowserLogs() + .PublishAsStaticWebsite("/api", weatherApi); builder.AddJavaScriptApp("vue", "../AspireJavaScript.Vue") .WithRunScript("start") @@ -27,14 +32,14 @@ .WaitFor(weatherApi) .WithHttpEndpoint(env: "PORT") .WithExternalHttpEndpoints() - .PublishAsDockerFile(); + .WithBrowserLogs() + .PublishAsStaticWebsite("/api", weatherApi); -var reactVite = builder.AddViteApp("reactvite", "../AspireJavaScript.Vite") +builder.AddViteApp("reactvite", "../AspireJavaScript.Vite") .WithNpm(installCommand: "ci") .WithReference(weatherApi) - .WithEnvironment("BROWSER", "none"); - -// Bundle the output of the Vite app into the wwwroot of the weather API -weatherApi.PublishWithContainerFiles(reactVite, "./wwwroot"); + .WithEnvironment("BROWSER", "none") + .WithBrowserLogs() + .PublishAsStaticWebsite("/api", weatherApi); builder.Build().Run(); diff --git a/samples/aspire-with-javascript/AspireJavaScript.AppHost/AspireJavaScript.AppHost.csproj b/samples/aspire-with-javascript/AspireJavaScript.AppHost/AspireJavaScript.AppHost.csproj index 465a038e4..8431ea3b6 100644 --- a/samples/aspire-with-javascript/AspireJavaScript.AppHost/AspireJavaScript.AppHost.csproj +++ b/samples/aspire-with-javascript/AspireJavaScript.AppHost/AspireJavaScript.AppHost.csproj @@ -9,9 +9,9 @@ - + diff --git a/samples/aspire-with-node/AspireWithNode.AppHost/AppHost.cs b/samples/aspire-with-node/AspireWithNode.AppHost/AppHost.cs index 109fdd6f4..8c940e2fd 100644 --- a/samples/aspire-with-node/AspireWithNode.AppHost/AppHost.cs +++ b/samples/aspire-with-node/AspireWithNode.AppHost/AppHost.cs @@ -1,4 +1,6 @@ -var builder = DistributedApplication.CreateBuilder(args); +#pragma warning disable ASPIREBROWSERLOGS001 + +var builder = DistributedApplication.CreateBuilder(args); var cache = builder.AddRedis("cache") .WithRedisInsight(); @@ -12,6 +14,7 @@ .WithHttpEndpoint(port: 5223, env: "PORT") .WithExternalHttpEndpoints() .WithHttpHealthCheck("/health") + .WithBrowserLogs() .WithReference(weatherapi).WaitFor(weatherapi) .WithReference(cache).WaitFor(cache); diff --git a/samples/aspire-with-node/AspireWithNode.AppHost/AspireWithNode.AppHost.csproj b/samples/aspire-with-node/AspireWithNode.AppHost/AspireWithNode.AppHost.csproj index 1ce9c84d2..cca2b0f6c 100644 --- a/samples/aspire-with-node/AspireWithNode.AppHost/AspireWithNode.AppHost.csproj +++ b/samples/aspire-with-node/AspireWithNode.AppHost/AspireWithNode.AppHost.csproj @@ -9,9 +9,9 @@ - + diff --git a/samples/aspire-with-python/apphost.cs b/samples/aspire-with-python/apphost.cs index fe88381fe..bbd21f8e0 100644 --- a/samples/aspire-with-python/apphost.cs +++ b/samples/aspire-with-python/apphost.cs @@ -1,5 +1,9 @@ +#pragma warning disable ASPIREBROWSERLOGS001 +#pragma warning disable ASPIREJAVASCRIPT001 + #:sdk Aspire.AppHost.Sdk@13.4.0 #:package Aspire.Hosting.JavaScript@13.4.0 +#:package Aspire.Hosting.Browsers@13.4.0-preview.1.26281.18 #:package Aspire.Hosting.Python@13.4.0 #:package Aspire.Hosting.Redis@13.4.0 @@ -14,10 +18,10 @@ .WaitFor(cache) .WithHttpHealthCheck("/health"); -var frontend = builder.AddViteApp("frontend", "./frontend") +builder.AddViteApp("frontend", "./frontend") .WithReference(app) - .WaitFor(app); - -app.PublishWithContainerFiles(frontend, "./static"); + .WaitFor(app) + .WithBrowserLogs() + .PublishAsStaticWebsite("/api", app); builder.Build().Run(); diff --git a/samples/client-apps-integration/ClientAppsIntegration.AppHost/ClientAppsIntegration.AppHost.csproj b/samples/client-apps-integration/ClientAppsIntegration.AppHost/ClientAppsIntegration.AppHost.csproj index 98315a08a..a7b8e8619 100644 --- a/samples/client-apps-integration/ClientAppsIntegration.AppHost/ClientAppsIntegration.AppHost.csproj +++ b/samples/client-apps-integration/ClientAppsIntegration.AppHost/ClientAppsIntegration.AppHost.csproj @@ -9,7 +9,6 @@ - diff --git a/samples/custom-resources/CustomResources.AppHost/AppHost.cs b/samples/custom-resources/CustomResources.AppHost/AppHost.cs index e66fa6723..eb8abc111 100644 --- a/samples/custom-resources/CustomResources.AppHost/AppHost.cs +++ b/samples/custom-resources/CustomResources.AppHost/AppHost.cs @@ -1,4 +1,6 @@ using CustomResources.AppHost; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; var builder = DistributedApplication.CreateBuilder(args); @@ -6,4 +8,24 @@ builder.AddTestResource("test"); +builder.OnBeforeStart(static (@event, cancellationToken) => +{ + var logger = @event.Services.GetRequiredService() + .CreateLogger("CustomResources.AppHost"); + + logger.LogInformation("Starting custom resources sample with {ResourceCount} resources.", @event.Model.Resources.Count); + + return Task.CompletedTask; +}); + +builder.Eventing.Subscribe(static (@event, cancellationToken) => +{ + var logger = @event.Services.GetRequiredService() + .CreateLogger("CustomResources.AppHost"); + + logger.LogInformation("Custom resources sample created {ResourceCount} resources.", @event.Model.Resources.Count); + + return Task.CompletedTask; +}); + builder.Build().Run(); diff --git a/samples/custom-resources/CustomResources.AppHost/CustomResources.AppHost.csproj b/samples/custom-resources/CustomResources.AppHost/CustomResources.AppHost.csproj index b38c7fcb4..cb88ffa3f 100644 --- a/samples/custom-resources/CustomResources.AppHost/CustomResources.AppHost.csproj +++ b/samples/custom-resources/CustomResources.AppHost/CustomResources.AppHost.csproj @@ -8,7 +8,6 @@ 00d08ee4-b2e0-4d12-827c-d131fda1c6f6 - diff --git a/samples/custom-resources/CustomResources.AppHost/TestResource.cs b/samples/custom-resources/CustomResources.AppHost/TestResource.cs index 917889567..6137c2669 100644 --- a/samples/custom-resources/CustomResources.AppHost/TestResource.cs +++ b/samples/custom-resources/CustomResources.AppHost/TestResource.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Globalization; +using System.Text.Json; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; @@ -23,6 +24,24 @@ public static IResourceBuilder AddTestResource(this IDistributedAp new(CustomResourceKnownProperties.Source, "Custom") ] }) + .WithCommand( + name: "inspect", + displayName: "Inspect resource", + executeCommand: context => + { + context.Logger.LogInformation("Inspect command executed for {ResourceName}.", context.ResourceName); + + var result = JsonSerializer.Serialize(new + { + resource = context.ResourceName, + generatedAt = DateTimeOffset.UtcNow + }); + + return Task.FromResult(CommandResults.Success( + message: "Resource inspection generated.", + result: result, + resultFormat: CommandResultFormat.Json)); + }) .ExcludeFromManifest(); rb.OnInitializeResource((resource, e, ct) => diff --git a/samples/database-containers/DatabaseContainers.AppHost/DatabaseContainers.AppHost.csproj b/samples/database-containers/DatabaseContainers.AppHost/DatabaseContainers.AppHost.csproj index 8bcf3e532..cb89a9490 100644 --- a/samples/database-containers/DatabaseContainers.AppHost/DatabaseContainers.AppHost.csproj +++ b/samples/database-containers/DatabaseContainers.AppHost/DatabaseContainers.AppHost.csproj @@ -17,7 +17,6 @@ - diff --git a/samples/database-migrations/DatabaseMigrations.AppHost/DatabaseMigrations.AppHost.csproj b/samples/database-migrations/DatabaseMigrations.AppHost/DatabaseMigrations.AppHost.csproj index e31d464ec..be971f186 100644 --- a/samples/database-migrations/DatabaseMigrations.AppHost/DatabaseMigrations.AppHost.csproj +++ b/samples/database-migrations/DatabaseMigrations.AppHost/DatabaseMigrations.AppHost.csproj @@ -13,7 +13,6 @@ - diff --git a/samples/health-checks-ui/HealthChecksUI.AppHost/AppHost.cs b/samples/health-checks-ui/HealthChecksUI.AppHost/AppHost.cs index 12e8e5ba4..922bf395d 100644 --- a/samples/health-checks-ui/HealthChecksUI.AppHost/AppHost.cs +++ b/samples/health-checks-ui/HealthChecksUI.AppHost/AppHost.cs @@ -1,15 +1,18 @@ var builder = DistributedApplication.CreateBuilder(args); -builder.AddDockerComposeEnvironment("compose"); +var compose = builder.AddDockerComposeEnvironment("compose"); -var cache = builder.AddRedis("cache"); +var cache = builder.AddRedis("cache") + .WithComputeEnvironment(compose); var apiService = builder.AddProject("apiservice") + .WithComputeEnvironment(compose) .WithHttpHealthCheck("/health") .WithHttpProbe(ProbeType.Liveness, "/alive") .WithFriendlyUrls(displayText: "API"); var webFrontend = builder.AddProject("webfrontend") + .WithComputeEnvironment(compose) .WithReference(cache) .WaitFor(cache) .WithReference(apiService) @@ -20,6 +23,7 @@ .WithExternalHttpEndpoints(); var healthChecksUI = builder.AddHealthChecksUI("healthchecksui") + .WithComputeEnvironment(compose) .WithReference(apiService) .WithReference(webFrontend) .WithFriendlyUrls("HealthChecksUI Dashboard", "http") diff --git a/samples/health-checks-ui/HealthChecksUI.AppHost/HealthChecksUI.AppHost.csproj b/samples/health-checks-ui/HealthChecksUI.AppHost/HealthChecksUI.AppHost.csproj index 97bd75ca6..a4ac8e682 100644 --- a/samples/health-checks-ui/HealthChecksUI.AppHost/HealthChecksUI.AppHost.csproj +++ b/samples/health-checks-ui/HealthChecksUI.AppHost/HealthChecksUI.AppHost.csproj @@ -14,7 +14,6 @@ - diff --git a/samples/image-gallery/README.md b/samples/image-gallery/README.md index 25b4107b6..ba53c0ef1 100644 --- a/samples/image-gallery/README.md +++ b/samples/image-gallery/README.md @@ -19,7 +19,8 @@ flowchart LR **Publish Mode:** ```mermaid flowchart LR - Browser --> API[C# API serving
Vite build output
'npm run build'] + Browser --> Frontend[Static website serving
Vite build output
'npm run build'] + Frontend -->|Proxy /api| API[C# API] API --> Blobs[Azure Blob Storage] API --> Queue[Azure Storage Queue] API --> SQL[Azure SQL] @@ -54,7 +55,7 @@ flowchart LR - **Dual-Mode Resources**: Azurite/SQL Server containers locally, Azure services in production (`.RunAsEmulator()`, `.RunAsContainer()`) - **Free Tier Deployment**: Azure SQL free tier with serverless auto-pause, Container Apps scale-to-zero - **Managed Identity**: Password-less authentication to all Azure resources (Storage, SQL, Queues) -- **Polyglot Stack**: Vite+React frontend embedded in C# API container, SkiaSharp for image processing +- **Polyglot Stack**: Vite+React frontend published as a static website, SkiaSharp for image processing - **OpenTelemetry**: Distributed tracing across upload → queue → worker pipeline ## Running Locally @@ -194,9 +195,9 @@ else } ``` -**Container Files Publishing** - Embed Vite build output in API container: +**Static Website Publishing** - Publish the Vite app as a static website with API proxying: ```csharp -api.PublishWithContainerFiles(frontend, "wwwroot"); +frontend.PublishAsStaticWebsite("/api", api); ``` ## Performance & Cost Characteristics diff --git a/samples/image-gallery/apphost.cs b/samples/image-gallery/apphost.cs index e52d032d0..c502b24d9 100644 --- a/samples/image-gallery/apphost.cs +++ b/samples/image-gallery/apphost.cs @@ -1,10 +1,13 @@ #pragma warning disable ASPIRECSHARPAPPS001 #pragma warning disable ASPIREAZURE002 +#pragma warning disable ASPIREBROWSERLOGS001 +#pragma warning disable ASPIREJAVASCRIPT001 #:sdk Aspire.AppHost.Sdk@13.4.0 #:package Aspire.Hosting.Azure.Storage@13.4.0 #:package Aspire.Hosting.Azure.Sql@13.4.0 #:package Aspire.Hosting.JavaScript@13.4.0 +#:package Aspire.Hosting.Browsers@13.4.0-preview.1.26281.18 #:package Aspire.Hosting.Azure.AppContainers@13.4.0 using Aspire.Hosting.Azure; @@ -13,7 +16,7 @@ var builder = DistributedApplication.CreateBuilder(args); -builder.AddAzureContainerAppEnvironment("env"); +var env = builder.AddAzureContainerAppEnvironment("env"); // Storage: Use Azurite emulator in run mode, real Azure in publish mode var storage = builder.AddAzureStorage("storage") @@ -29,6 +32,7 @@ // API: Upload images, queue thumbnail jobs, serve metadata var api = builder.AddCSharpApp("api", "./api") + .WithComputeEnvironment(env) .WithHttpHealthCheck("/health") .WithExternalHttpEndpoints() .WaitFor(sql) @@ -58,6 +62,7 @@ // Worker: Container Apps Job for queue-triggered thumbnail generation // Event-driven: starts when messages arrive, exits within ~5 seconds when queue is empty var worker = builder.AddCSharpApp("worker", "./worker") + .WithComputeEnvironment(env) .WithReference(blobs) .WithReference(queues) .WithReference(sql) @@ -99,13 +104,12 @@ } // Frontend: Vite+React for upload and gallery UI -var frontend = builder.AddViteApp("frontend", "./frontend") +builder.AddViteApp("frontend", "./frontend") .WithEndpoint("http", e => e.Port = 9080) .WithReference(api) - .WithUrl("", "Image Gallery"); - -// Publish: Embed frontend build output in API container -api.PublishWithContainerFiles(frontend, "wwwroot"); + .WithUrl("", "Image Gallery") + .WithBrowserLogs() + .WithComputeEnvironment(env) + .PublishAsStaticWebsite("/api", api); builder.Build().Run(); - diff --git a/samples/node-express-redis/apphost.mts b/samples/node-express-redis/apphost.mts index 9dfe288b1..7d857ba11 100644 --- a/samples/node-express-redis/apphost.mts +++ b/samples/node-express-redis/apphost.mts @@ -3,14 +3,16 @@ import { createBuilder } from "./.aspire/modules/aspire.mjs"; const builder = await createBuilder(); const executionContext = await builder.executionContext(); -await builder.addDockerComposeEnvironment("dc"); +const dc = await builder.addDockerComposeEnvironment("dc"); const redis = await builder.addRedis("redis") - .withRedisInsight(); + .withRedisInsight() + .withComputeEnvironment(dc); const api = await builder.addNodeApp("api", "./api", "index.js") .withHttpEndpoint({ env: "PORT" }) .withHttpHealthCheck({ path: "/health" }) + .withComputeEnvironment(dc) .waitFor(redis) .withReference(redis); @@ -31,7 +33,9 @@ await builder.addYarp("app") } }) .withExternalHttpEndpoints() + .withBrowserLogs() .publishWithStaticFiles(frontend) + .withComputeEnvironment(dc) .withExplicitStart(); await builder.build().run(); diff --git a/samples/node-express-redis/aspire.config.json b/samples/node-express-redis/aspire.config.json index 07b5d1229..06b6c9d55 100644 --- a/samples/node-express-redis/aspire.config.json +++ b/samples/node-express-redis/aspire.config.json @@ -16,6 +16,7 @@ } }, "packages": { + "Aspire.Hosting.Browsers": "13.4.0-preview.1.26281.18", "Aspire.Hosting.JavaScript": "13.4.0", "Aspire.Hosting.Redis": "13.4.0", "Aspire.Hosting.Yarp": "13.4.0", diff --git a/samples/orleans-voting/OrleansVoting.AppHost/OrleansVoting.AppHost.csproj b/samples/orleans-voting/OrleansVoting.AppHost/OrleansVoting.AppHost.csproj index aeb6690d1..5e768ed34 100644 --- a/samples/orleans-voting/OrleansVoting.AppHost/OrleansVoting.AppHost.csproj +++ b/samples/orleans-voting/OrleansVoting.AppHost/OrleansVoting.AppHost.csproj @@ -14,7 +14,6 @@
- diff --git a/samples/polyglot-task-queue/apphost.mts b/samples/polyglot-task-queue/apphost.mts index cfe8d1180..ff6ff84d2 100644 --- a/samples/polyglot-task-queue/apphost.mts +++ b/samples/polyglot-task-queue/apphost.mts @@ -2,10 +2,11 @@ import { ContainerLifetime, UrlDisplayLocation, createBuilder } from "./.aspire/ const builder = await createBuilder(); -await builder.addDockerComposeEnvironment("dc"); +const dc = await builder.addDockerComposeEnvironment("dc"); const rabbitmq = await builder.addRabbitMQ("messaging") .withManagementPlugin() + .withComputeEnvironment(dc) .withLifetime(ContainerLifetime.Persistent) .withUrlForEndpoint("tcp", async (url) => { @@ -19,19 +20,23 @@ const rabbitmq = await builder.addRabbitMQ("messaging") const api = await builder.addNodeApp("api", "./api", "index.js") .withHttpEndpoint({ env: "PORT" }) .withHttpHealthCheck({ path: "/health" }) + .withComputeEnvironment(dc) .waitFor(rabbitmq) .withReference(rabbitmq); const frontend = await builder.addViteApp("frontend", "./frontend") .withReference(api) - .withUrl("", { displayText: "Task Queue UI" }); + .withUrl("", { displayText: "Task Queue UI" }) + .withBrowserLogs(); await builder.addPythonApp("worker-python", "./worker-python", "main.py") .withUv() + .withComputeEnvironment(dc) .waitFor(rabbitmq) .withReference(rabbitmq); await builder.addCSharpApp("worker-csharp", "./worker-csharp") + .withComputeEnvironment(dc) .waitFor(rabbitmq) .withReference(rabbitmq); diff --git a/samples/polyglot-task-queue/aspire.config.json b/samples/polyglot-task-queue/aspire.config.json index a898069b6..436020c02 100644 --- a/samples/polyglot-task-queue/aspire.config.json +++ b/samples/polyglot-task-queue/aspire.config.json @@ -16,6 +16,7 @@ } }, "packages": { + "Aspire.Hosting.Browsers": "13.4.0-preview.1.26281.18", "Aspire.Hosting.RabbitMQ": "13.4.0", "Aspire.Hosting.Python": "13.4.0", "Aspire.Hosting.JavaScript": "13.4.0", diff --git a/samples/rag-document-qa-svelte/apphost.mts b/samples/rag-document-qa-svelte/apphost.mts index 8925b1bb1..7222f1479 100644 --- a/samples/rag-document-qa-svelte/apphost.mts +++ b/samples/rag-document-qa-svelte/apphost.mts @@ -19,7 +19,8 @@ const api = await builder.addUvicornApp("api", "./api", "main:app") const frontend = await builder.addViteApp("frontend", "./frontend") .withReference(api) - .withUrl("", { displayText: "RAG UI" }); + .withUrl("", { displayText: "RAG UI" }) + .withBrowserLogs(); await api.publishWithContainerFiles(frontend, "public"); diff --git a/samples/rag-document-qa-svelte/aspire.config.json b/samples/rag-document-qa-svelte/aspire.config.json index b9578b913..ce473e15b 100644 --- a/samples/rag-document-qa-svelte/aspire.config.json +++ b/samples/rag-document-qa-svelte/aspire.config.json @@ -16,6 +16,7 @@ } }, "packages": { + "Aspire.Hosting.Browsers": "13.4.0-preview.1.26281.18", "Aspire.Hosting.Python": "13.4.0", "Aspire.Hosting.JavaScript": "13.4.0", "Aspire.Hosting.Qdrant": "13.4.0", diff --git a/samples/vite-csharp-postgres/apphost.mts b/samples/vite-csharp-postgres/apphost.mts index e2b4017a3..0e30d9e70 100644 --- a/samples/vite-csharp-postgres/apphost.mts +++ b/samples/vite-csharp-postgres/apphost.mts @@ -2,9 +2,10 @@ import { ContainerLifetime, UrlDisplayLocation, createBuilder } from "./.aspire/ const builder = await createBuilder(); -await builder.addDockerComposeEnvironment("dc"); +const dc = await builder.addDockerComposeEnvironment("dc"); const postgres = await builder.addPostgres("postgres") + .withComputeEnvironment(dc) .withDataVolume() .withLifetime(ContainerLifetime.Persistent) .withPgAdmin({ @@ -19,6 +20,7 @@ const db = await postgres.addDatabase("db"); const api = await builder.addCSharpApp("api", "./api") .withHttpHealthCheck({ path: "/health" }) .withExternalHttpEndpoints() + .withComputeEnvironment(dc) .waitFor(db) .withReference(db) .withUrlForEndpoint("http", async (url) => @@ -42,7 +44,8 @@ const api = await builder.addCSharpApp("api", "./api") const frontend = await builder.addViteApp("frontend", "./frontend") .withReference(api) - .withUrl("", { displayText: "Todo UI" }); + .withUrl("", { displayText: "Todo UI" }) + .withBrowserLogs(); await api.publishWithContainerFiles(frontend, "wwwroot"); diff --git a/samples/vite-csharp-postgres/aspire.config.json b/samples/vite-csharp-postgres/aspire.config.json index c64e14d81..6698a49d9 100644 --- a/samples/vite-csharp-postgres/aspire.config.json +++ b/samples/vite-csharp-postgres/aspire.config.json @@ -16,6 +16,7 @@ } }, "packages": { + "Aspire.Hosting.Browsers": "13.4.0-preview.1.26281.18", "Aspire.Hosting.PostgreSQL": "13.4.0", "Aspire.Hosting.JavaScript": "13.4.0", "Aspire.Hosting.Docker": "13.4.0" diff --git a/samples/vite-react-fastapi/apphost.mts b/samples/vite-react-fastapi/apphost.mts index 16ee9f777..a1f447b36 100644 --- a/samples/vite-react-fastapi/apphost.mts +++ b/samples/vite-react-fastapi/apphost.mts @@ -3,10 +3,11 @@ import { createBuilder } from "./.aspire/modules/aspire.mjs"; const builder = await createBuilder(); const executionContext = await builder.executionContext(); -await builder.addDockerComposeEnvironment("dc"); +const dc = await builder.addDockerComposeEnvironment("dc"); const api = await builder.addUvicornApp("api", "./api", "main:app") - .withHttpHealthCheck({ path: "/health" }); + .withHttpHealthCheck({ path: "/health" }) + .withComputeEnvironment(dc); const frontend = await builder.addViteApp("frontend", "./frontend") .withReference(api); @@ -27,7 +28,9 @@ await builder.addYarp("app") }) .withReference(api) .withExternalHttpEndpoints() + .withBrowserLogs() .publishWithStaticFiles(frontend) + .withComputeEnvironment(dc) .withExplicitStart(); await builder.build().run(); diff --git a/samples/vite-react-fastapi/aspire.config.json b/samples/vite-react-fastapi/aspire.config.json index 15fa3051a..dcbfee6f3 100644 --- a/samples/vite-react-fastapi/aspire.config.json +++ b/samples/vite-react-fastapi/aspire.config.json @@ -16,6 +16,7 @@ } }, "packages": { + "Aspire.Hosting.Browsers": "13.4.0-preview.1.26281.18", "Aspire.Hosting.Python": "13.4.0", "Aspire.Hosting.JavaScript": "13.4.0", "Aspire.Hosting.Yarp": "13.4.0", diff --git a/samples/vite-yarp-static/apphost.mts b/samples/vite-yarp-static/apphost.mts index 9b2d0a329..02d412fa6 100644 --- a/samples/vite-yarp-static/apphost.mts +++ b/samples/vite-yarp-static/apphost.mts @@ -3,7 +3,7 @@ import { createBuilder } from "./.aspire/modules/aspire.mjs"; const builder = await createBuilder(); const executionContext = await builder.executionContext(); -await builder.addDockerComposeEnvironment("dc"); +const dc = await builder.addDockerComposeEnvironment("dc"); const frontend = await builder.addViteApp("frontend", "./frontend"); @@ -17,6 +17,8 @@ await builder.addYarp("app") } }) .withExternalHttpEndpoints() - .publishWithStaticFiles(frontend); + .withBrowserLogs() + .publishWithStaticFiles(frontend) + .withComputeEnvironment(dc); await builder.build().run(); diff --git a/samples/vite-yarp-static/aspire.config.json b/samples/vite-yarp-static/aspire.config.json index 786da4e9e..56be91db5 100644 --- a/samples/vite-yarp-static/aspire.config.json +++ b/samples/vite-yarp-static/aspire.config.json @@ -16,6 +16,7 @@ } }, "packages": { + "Aspire.Hosting.Browsers": "13.4.0-preview.1.26281.18", "Aspire.Hosting.JavaScript": "13.4.0", "Aspire.Hosting.Yarp": "13.4.0", "Aspire.Hosting.Docker": "13.4.0" diff --git a/samples/volume-mount/VolumeMount.AppHost/VolumeMount.AppHost.csproj b/samples/volume-mount/VolumeMount.AppHost/VolumeMount.AppHost.csproj index 529b179b5..431677498 100644 --- a/samples/volume-mount/VolumeMount.AppHost/VolumeMount.AppHost.csproj +++ b/samples/volume-mount/VolumeMount.AppHost/VolumeMount.AppHost.csproj @@ -15,7 +15,6 @@
- diff --git a/tests/SamplesIntegrationTests/Infrastructure/DistributedApplicationExtensions.cs b/tests/SamplesIntegrationTests/Infrastructure/DistributedApplicationExtensions.cs index 67a2731c1..01591b928 100644 --- a/tests/SamplesIntegrationTests/Infrastructure/DistributedApplicationExtensions.cs +++ b/tests/SamplesIntegrationTests/Infrastructure/DistributedApplicationExtensions.cs @@ -232,6 +232,13 @@ private static bool ShouldSkipResource(IResource resource) return true; } + // BrowserLogs resources are dashboard command resources; they do not have a + // service lifecycle to wait for during AppHost startup tests. + if (resource.GetType().FullName?.Contains("BrowserLogs", StringComparison.Ordinal) == true) + { + return true; + } + #pragma warning disable ASPIREAZURE001 // AzureEnvironmentResource is experimental. if (resource is AzureEnvironmentResource) {