Skip to content

Commit f8022b6

Browse files
[release/9.3] Use ProcessSpec for invoking dotnet publish (#9561)
* Move dotnet publish call over to ProcessSpec. * Update PublishCommand.cs --------- Co-authored-by: Mitch Denny <[email protected]>
1 parent e8c4fa9 commit f8022b6

File tree

2 files changed

+37
-54
lines changed

2 files changed

+37
-54
lines changed

src/Aspire.Cli/Commands/PublishCommand.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,8 @@ public static async Task<bool> ProcessPublishingActivitiesAsync(IAsyncEnumerable
228228
if (lastActivityUpdateLookup.Any(kvp => kvp.Value.IsError) || lastActivityUpdateLookup.All(kvp => kvp.Value.IsComplete))
229229
{
230230
// If we have an error or all tasks are complete then we can stop
231-
// processing the publishing activities.
232-
return false;
231+
// processing the publishing activities. Return true if there are no errors.
232+
return lastActivityUpdateLookup.All(kvp => !kvp.Value.IsError);
233233
}
234234
}
235235

src/Aspire.Hosting/Publishing/ResourceContainerImageBuilder.cs

Lines changed: 35 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33

44
#pragma warning disable ASPIREPUBLISHERS001
55

6-
using System.Diagnostics;
76
using System.Diagnostics.CodeAnalysis;
87
using Aspire.Hosting.ApplicationModel;
98
using Aspire.Hosting.Dcp;
9+
using Aspire.Hosting.Dcp.Process;
1010
using Microsoft.Extensions.DependencyInjection;
1111
using Microsoft.Extensions.Logging;
1212
using Microsoft.Extensions.Options;
@@ -71,7 +71,7 @@ await BuildContainerImageFromDockerfileAsync(
7171
}
7272
}
7373

74-
private async Task<string> BuildProjectContainerImageAsync(IResource resource, CancellationToken cancellationToken)
74+
private async Task BuildProjectContainerImageAsync(IResource resource, CancellationToken cancellationToken)
7575
{
7676
var publishingActivity = await activityReporter.CreateActivityAsync(
7777
$"{resource.Name}-build-image",
@@ -86,67 +86,50 @@ private async Task<string> BuildProjectContainerImageAsync(IResource resource, C
8686
throw new DistributedApplicationException($"The resource '{projectMetadata}' does not have a project metadata annotation.");
8787
}
8888

89-
var startInfo = new ProcessStartInfo
89+
var spec = new ProcessSpec("dotnet")
9090
{
91-
FileName = "dotnet",
92-
RedirectStandardOutput = true,
93-
RedirectStandardError = true
91+
Arguments = $"publish {projectMetadata.ProjectPath} --configuration Release /t:PublishContainer /p:ContainerRepository={resource.Name}",
92+
OnOutputData = output =>
93+
{
94+
logger.LogInformation("dotnet publish {ProjectPath} (stdout): {Output}", projectMetadata.ProjectPath, output);
95+
},
96+
OnErrorData = error =>
97+
{
98+
logger.LogError("dotnet publish {ProjectPath} (stderr): {Error}", projectMetadata.ProjectPath, error);
99+
}
94100
};
95101

96-
startInfo.ArgumentList.Add("publish");
97-
startInfo.ArgumentList.Add(projectMetadata.ProjectPath);
98-
startInfo.ArgumentList.Add("--configuration");
99-
startInfo.ArgumentList.Add("Release");
100-
startInfo.ArgumentList.Add("/t:PublishContainer");
101-
startInfo.ArgumentList.Add($"/p:ContainerRepository={resource.Name}");
102-
103102
logger.LogInformation(
104103
"Starting .NET CLI with arguments: {Arguments}",
105-
string.Join(" ", startInfo.ArgumentList.ToArray())
104+
string.Join(" ", spec.Arguments)
106105
);
107106

108-
using var process = Process.Start(startInfo);
109-
110-
if (process is null)
111-
{
112-
throw new DistributedApplicationException("Failed to start .NET CLI.");
113-
}
114-
115-
logger.LogInformation(
116-
"Started .NET CLI with PID: {PID}",
117-
process.Id
118-
);
119-
120-
await process.WaitForExitAsync(cancellationToken).ConfigureAwait(false);
121-
122-
if (process.ExitCode != 0)
123-
{
124-
var stderr = process.StandardError.ReadToEnd();
125-
var stdout = process.StandardOutput.ReadToEnd();
126-
127-
logger.LogError(
128-
".NET CLI failed with exit code {ExitCode}. Output: {Stdout}, Error: {Stderr}",
129-
process.ExitCode,
130-
stdout,
131-
stderr);
132-
133-
await activityReporter.UpdateActivityStatusAsync(
134-
publishingActivity, (status) => status with { IsError = true },
135-
cancellationToken).ConfigureAwait(false);
107+
var (pendingProcessResult, processDisposable) = ProcessUtil.Run(spec);
136108

137-
throw new DistributedApplicationException($"Failed to build container image, stdout: {stdout}, stderr: {stderr}");
138-
}
139-
else
109+
await using (processDisposable)
140110
{
141-
await activityReporter.UpdateActivityStatusAsync(
142-
publishingActivity, (status) => status with { IsComplete = true },
143-
cancellationToken).ConfigureAwait(false);
111+
var processResult = await pendingProcessResult
112+
.WaitAsync(cancellationToken)
113+
.ConfigureAwait(false);
144114

145-
logger.LogDebug(
146-
".NET CLI completed with exit code: {ExitCode}",
147-
process.ExitCode);
115+
if (processResult.ExitCode != 0)
116+
{
117+
logger.LogError("dotnet publish for project {ProjectPath} failed with exit code {ExitCode}.", projectMetadata.ProjectPath, processResult.ExitCode);
118+
await activityReporter.UpdateActivityStatusAsync(
119+
publishingActivity, (status) => status with { IsError = true },
120+
cancellationToken).ConfigureAwait(false);
121+
throw new DistributedApplicationException($"Failed to build container image.");
122+
}
123+
else
124+
{
125+
await activityReporter.UpdateActivityStatusAsync(
126+
publishingActivity, (status) => status with { IsComplete = true },
127+
cancellationToken).ConfigureAwait(false);
148128

149-
return $"{resource.Name}:latest";
129+
logger.LogDebug(
130+
".NET CLI completed with exit code: {ExitCode}",
131+
processResult.ExitCode);
132+
}
150133
}
151134
}
152135

0 commit comments

Comments
 (0)