-
Notifications
You must be signed in to change notification settings - Fork 887
Fail on JavaScript run script Dockerfile conflict #16969
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
e9dca1a
4ca0c7a
404e13b
02cec45
d182e0c
df796c4
64ea719
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,7 @@ | |
| using Aspire.Hosting.ApplicationModel.Docker; | ||
| using Aspire.Hosting.JavaScript; | ||
| using Aspire.Hosting.Pipelines; | ||
| using Aspire.Hosting.Publishing; | ||
| using Aspire.Hosting.Utils; | ||
| using Microsoft.Extensions.DependencyInjection; | ||
| using Microsoft.Extensions.Hosting; | ||
|
|
@@ -29,6 +30,7 @@ public static class JavaScriptHostingExtensions | |
| { | ||
| private const string BrowserCapability = "browser"; | ||
| private const string DefaultNodeVersion = "22"; | ||
| private const string DefaultJavaScriptRunScriptName = "dev"; | ||
| private const string DefaultYarpImage = Yarp.YarpContainerImageTags.Registry + "/" + Yarp.YarpContainerImageTags.Image + ":" + Yarp.YarpContainerImageTags.Tag; | ||
|
|
||
| // This is the order of config files that Vite will look for by default | ||
|
|
@@ -329,7 +331,7 @@ private static IResourceBuilder<TResource> WithNodeDefaults<TResource>(this IRes | |
| /// integration. | ||
| /// </remarks> | ||
| [AspireExport(Description = "Adds a JavaScript application resource")] | ||
| public static IResourceBuilder<JavaScriptAppResource> AddJavaScriptApp(this IDistributedApplicationBuilder builder, [ResourceName] string name, string appDirectory, string runScriptName = "dev") | ||
| public static IResourceBuilder<JavaScriptAppResource> AddJavaScriptApp(this IDistributedApplicationBuilder builder, [ResourceName] string name, string appDirectory, string runScriptName = DefaultJavaScriptRunScriptName) | ||
| { | ||
| ArgumentNullException.ThrowIfNull(builder); | ||
| ArgumentException.ThrowIfNullOrEmpty(name); | ||
|
|
@@ -873,6 +875,19 @@ private static IResourceBuilder<TResource> CreateDefaultJavaScriptAppBuilder<TRe | |
| .WithBuildScript("build") | ||
| .WithRunScript(runScriptName); | ||
|
|
||
| if (builder.ExecutionContext.IsPublishMode && | ||
| builder.TryCreateResourceBuilder<ContainerResource>(resource.Name, out var containerBuilder)) | ||
| { | ||
| Task WriteValidatedContainerAsync(ManifestPublishingContext context) | ||
| { | ||
| ValidateExistingDockerfileRunScript(resource, containerBuilder.Resource, runScriptName); | ||
| return context.WriteContainerAsync(containerBuilder.Resource); | ||
| } | ||
|
|
||
| resourceBuilder.WithManifestPublishingCallback(WriteValidatedContainerAsync); | ||
| containerBuilder.WithManifestPublishingCallback(WriteValidatedContainerAsync); | ||
| } | ||
|
|
||
| resourceBuilder.WithVSCodeDebugging(); | ||
|
|
||
| // ensure the package manager command is set before starting the resource | ||
|
|
@@ -892,6 +907,40 @@ private static IResourceBuilder<TResource> CreateDefaultJavaScriptAppBuilder<TRe | |
| return resourceBuilder; | ||
| } | ||
|
|
||
| private static void ValidateExistingDockerfileRunScript(JavaScriptAppResource resource, ContainerResource containerResource, string initialRunScriptName) | ||
| { | ||
| if (containerResource.Entrypoint is not null || | ||
| !containerResource.TryGetLastAnnotation<DockerfileBuildAnnotation>(out var dockerfileBuildAnnotation) || | ||
| dockerfileBuildAnnotation.DockerfileFactory is not null || | ||
| !containerResource.TryGetLastAnnotation<JavaScriptRunScriptAnnotation>(out var runScript)) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| var hasMultipleRunScriptAnnotations = | ||
| containerResource.TryGetAnnotationsOfType<JavaScriptRunScriptAnnotation>(out var runScriptAnnotations) && | ||
| runScriptAnnotations.Skip(1).Any(); | ||
|
|
||
| var hasExplicitRunScript = | ||
| !string.Equals(initialRunScriptName, DefaultJavaScriptRunScriptName, StringComparison.Ordinal) || | ||
| hasMultipleRunScriptAnnotations || | ||
| runScript.Args.Length > 0; | ||
|
|
||
| if (!hasExplicitRunScript) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| // Existing Dockerfiles are user-authored, so Aspire cannot safely assume that replacing | ||
| // their entrypoint with a package-manager script will work for the image shape. | ||
| // If the user provides an explicit container entrypoint above, honor it; otherwise fail | ||
| // instead of silently publishing an image that ignores the requested run script. | ||
| throw new InvalidOperationException( | ||
| $"JavaScript app resource '{resource.Name}' is configured to run script '{runScript.ScriptName}', but publish is using the existing Dockerfile '{dockerfileBuildAnnotation.DockerfilePath}'. " + | ||
| "An existing Dockerfile entrypoint cannot be changed automatically from runScriptName or WithRunScript. " + | ||
| "Remove or rename the Dockerfile so Aspire can generate one, or call PublishAsDockerFile(...) and set the container entrypoint explicitly."); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
builder.AddJavaScriptApp("js", appDir) // default script: "dev"
.WithBun()
.WithRunScript("dev", new[] { "--port", "8080" });fails with Suggested fix: when the trigger is |
||
| } | ||
|
|
||
| /// <summary> | ||
| /// Adds a Vite app to the distributed application builder. | ||
| /// </summary> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hasMultipleRunScriptAnnotationsistruewheneverWithRunScript(...)is called afterAddJavaScriptApp, becauseCreateDefaultJavaScriptAppBuilderitself already adds one annotation at line 876. As a result, this code throws even when the user's explicitWithRunScriptmatches the default:Repro (verified against this PR build with
dotnet run -- --publisher manifest): publish fails withJavaScript app resource 'js' is configured to run script 'dev', but publish is using the existing Dockerfile .... The user explicitly affirmed the default value, so the failure is surprising.Suggested fix: compare the last
JavaScriptRunScriptAnnotation'sScriptName(andArgs) against the default instead of treating annotation count alone as a proxy for "explicit".