diff --git a/src/Aspire.Hosting/ResourceBuilderExtensions.cs b/src/Aspire.Hosting/ResourceBuilderExtensions.cs index 364d0c793c9..13c148cc7e5 100644 --- a/src/Aspire.Hosting/ResourceBuilderExtensions.cs +++ b/src/Aspire.Hosting/ResourceBuilderExtensions.cs @@ -179,12 +179,14 @@ public static IResourceBuilder WithEnvironment(this IResourceBuilder bu { builder.WithEnvironment(async context => { - var url = await externalService.Resource.UrlParameter.GetValueAsync(context.CancellationToken).ConfigureAwait(false); - // In publish mode we can't validate the parameter value so we'll just use it without validating. - if (!context.ExecutionContext.IsPublishMode && !ExternalServiceResource.UrlIsValidForExternalService(url, out var _, out var message)) + if (!context.ExecutionContext.IsPublishMode) { - throw new DistributedApplicationException($"The URL parameter '{externalService.Resource.UrlParameter.Name}' for the external service '{externalService.Resource.Name}' is invalid: {message}"); + var url = await externalService.Resource.UrlParameter.GetValueAsync(context.CancellationToken).ConfigureAwait(false); + if (!ExternalServiceResource.UrlIsValidForExternalService(url, out var _, out var message)) + { + throw new DistributedApplicationException($"The URL parameter '{externalService.Resource.UrlParameter.Name}' for the external service '{externalService.Resource.Name}' is invalid: {message}"); + } } context.EnvironmentVariables[name] = externalService.Resource.UrlParameter; diff --git a/tests/Aspire.Hosting.Tests/ExternalServiceTests.cs b/tests/Aspire.Hosting.Tests/ExternalServiceTests.cs index 51933630ebf..a4c1acb6956 100644 --- a/tests/Aspire.Hosting.Tests/ExternalServiceTests.cs +++ b/tests/Aspire.Hosting.Tests/ExternalServiceTests.cs @@ -444,6 +444,36 @@ public async Task ExternalServiceWithParameterHttpHealthCheckResolvesUrlAsync() Assert.Contains(healthCheckKey, result.Entries.Keys); } + [Fact] + public async Task ExternalServiceWithParameterPublishManifest() + { + using var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + + var urlParam = builder.AddParameter("external-url"); + var externalService = builder.AddExternalService("external", urlParam); + + var project = builder.AddProject("project") + .WithReference(externalService) + .WithEnvironment("EXTERNAL_SERVICE", externalService); + + var manifest = await ManifestUtils.GetManifest(project.Resource); + + Assert.Equal( + """ + { + "type": "project.v0", + "path": "testproject", + "env": { + "OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES": "true", + "OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES": "true", + "OTEL_DOTNET_EXPERIMENTAL_OTLP_RETRY": "in_memory", + "services__external__default__0": "{external-url.value}", + "EXTERNAL_SERVICE": "{external-url.value}" + } + } + """, manifest.ToString()); + } + private sealed class TestProject : IProjectMetadata { public string ProjectPath => "testproject";