Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/Aspire.Cli/Commands/PublishCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,8 @@ public static async Task<bool> ProcessPublishingActivitiesAsync(IAsyncEnumerable
if (lastActivityUpdateLookup.Any(kvp => kvp.Value.IsError) || lastActivityUpdateLookup.All(kvp => kvp.Value.IsComplete))
{
// If we have an error or all tasks are complete then we can stop
// processing the publishing activities.
return false;
// processing the publishing activities. Return true if there are no errors.
return lastActivityUpdateLookup.All(kvp => !kvp.Value.IsError);
}
}

Expand Down
87 changes: 35 additions & 52 deletions src/Aspire.Hosting/Publishing/ResourceContainerImageBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@

#pragma warning disable ASPIREPUBLISHERS001

using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using Aspire.Hosting.ApplicationModel;
using Aspire.Hosting.Dcp;
using Aspire.Hosting.Dcp.Process;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
Expand Down Expand Up @@ -71,7 +71,7 @@ await BuildContainerImageFromDockerfileAsync(
}
}

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

var startInfo = new ProcessStartInfo
var spec = new ProcessSpec("dotnet")
{
FileName = "dotnet",
RedirectStandardOutput = true,
RedirectStandardError = true
Arguments = $"publish {projectMetadata.ProjectPath} --configuration Release /t:PublishContainer /p:ContainerRepository={resource.Name}",
OnOutputData = output =>
{
logger.LogInformation("dotnet publish {ProjectPath} (stdout): {Output}", projectMetadata.ProjectPath, output);
},
OnErrorData = error =>
{
logger.LogError("dotnet publish {ProjectPath} (stderr): {Error}", projectMetadata.ProjectPath, error);
}
};

startInfo.ArgumentList.Add("publish");
startInfo.ArgumentList.Add(projectMetadata.ProjectPath);
startInfo.ArgumentList.Add("--configuration");
startInfo.ArgumentList.Add("Release");
startInfo.ArgumentList.Add("/t:PublishContainer");
startInfo.ArgumentList.Add($"/p:ContainerRepository={resource.Name}");

logger.LogInformation(
"Starting .NET CLI with arguments: {Arguments}",
string.Join(" ", startInfo.ArgumentList.ToArray())
string.Join(" ", spec.Arguments)
);

using var process = Process.Start(startInfo);

if (process is null)
{
throw new DistributedApplicationException("Failed to start .NET CLI.");
}

logger.LogInformation(
"Started .NET CLI with PID: {PID}",
process.Id
);

await process.WaitForExitAsync(cancellationToken).ConfigureAwait(false);

if (process.ExitCode != 0)
{
var stderr = process.StandardError.ReadToEnd();
var stdout = process.StandardOutput.ReadToEnd();

logger.LogError(
".NET CLI failed with exit code {ExitCode}. Output: {Stdout}, Error: {Stderr}",
process.ExitCode,
stdout,
stderr);

await activityReporter.UpdateActivityStatusAsync(
publishingActivity, (status) => status with { IsError = true },
cancellationToken).ConfigureAwait(false);
var (pendingProcessResult, processDisposable) = ProcessUtil.Run(spec);

throw new DistributedApplicationException($"Failed to build container image, stdout: {stdout}, stderr: {stderr}");
}
else
await using (processDisposable)
{
await activityReporter.UpdateActivityStatusAsync(
publishingActivity, (status) => status with { IsComplete = true },
cancellationToken).ConfigureAwait(false);
var processResult = await pendingProcessResult
.WaitAsync(cancellationToken)
.ConfigureAwait(false);

logger.LogDebug(
".NET CLI completed with exit code: {ExitCode}",
process.ExitCode);
if (processResult.ExitCode != 0)
{
logger.LogError("dotnet publish for project {ProjectPath} failed with exit code {ExitCode}.", projectMetadata.ProjectPath, processResult.ExitCode);
await activityReporter.UpdateActivityStatusAsync(
publishingActivity, (status) => status with { IsError = true },
cancellationToken).ConfigureAwait(false);
throw new DistributedApplicationException($"Failed to build container image.");
}
else
{
await activityReporter.UpdateActivityStatusAsync(
publishingActivity, (status) => status with { IsComplete = true },
cancellationToken).ConfigureAwait(false);

return $"{resource.Name}:latest";
logger.LogDebug(
".NET CLI completed with exit code: {ExitCode}",
processResult.ExitCode);
}
}
}

Expand Down
Loading