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
3 changes: 2 additions & 1 deletion docs/compatibility/13.0/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Breaking changes in Aspire 13.0
titleSuffix: ""
description: Navigate to the breaking changes in Aspire 13.0.
ms.date: 10/17/2025
ms.date: 10/20/2025
---

# Breaking changes in Aspire 13.0
Expand All @@ -18,4 +18,5 @@ If you're migrating an app to Aspire 13.0, the breaking changes listed here migh

| Title | Type of change | Introduced version |
|--|--|--|
| [Activity reporter and pipeline context renamed](pipeline-activity-reporter-renamed.md) | Binary incompatible, source incompatible | 13.0 |
| [DefaultAzureCredential defaults to ManagedIdentityCredential on ACA and App Service](defaultazurecredential-managedidentity-default.md) | Behavioral change | 13.0 |
142 changes: 142 additions & 0 deletions docs/compatibility/13.0/pipeline-activity-reporter-renamed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
---
title: "Breaking change - Activity reporter and pipeline context renamed"
description: "Learn about the breaking change in Aspire 13.0 where publishing activity reporter APIs and context types were renamed to reflect pipeline architecture."
ms.date: 10/20/2025
ai-usage: ai-assisted
ms.custom: https://github.com/dotnet/aspire/pull/12137
---

# Activity reporter and pipeline context renamed

In Aspire 13.0, the publishing activity reporter APIs and context types have been renamed to better reflect the pipeline architecture. The publishing step creation process has been simplified, with steps now automatically created during pipeline execution rather than requiring explicit creation within step actions.

## Version introduced

Aspire 13.0 Preview 1

## Previous behavior

The previous API used publishing-specific names and required explicit step creation within pipeline actions:

```csharp
builder.Pipeline.AddStep("assign-storage-role", async (context) =>
{
var roleAssignmentStep = await context.ActivityReporter
.CreateStepAsync($"assign-storage-role", context.CancellationToken);

await using (roleAssignmentStep.ConfigureAwait(false))
{
var assignRoleTask = await roleAssignmentStep
.CreateTaskAsync($"Granting file share access...", context.CancellationToken);

await using (assignRoleTask.ConfigureAwait(false))
{
// ... task work
}
}
});
```

The types used were:

- `DeployingContext` - Provided context for pipeline execution
- `IPublishingActivityReporter` - Interface for reporting activities
- `PublishingActivityReporter` - Implementation of the activity reporter
- `NullPublishingActivityReporter` - Null object pattern implementation
- `IPublishingStep` - Interface for publishing steps
- `IPublishingTask` - Interface for publishing tasks

## New behavior

The API now uses pipeline-specific names and automatically creates steps during pipeline execution:

```csharp
builder.Pipeline.AddStep("assign-storage-role", async (stepContext) =>
{
var assignRoleTask = await stepContext.ReportingStep
.CreateTaskAsync($"Granting file share access...", stepContext.CancellationToken);

await using (assignRoleTask.ConfigureAwait(false))
{
// ... task work
}
});
```

The types have been renamed as follows:

- `DeployingContext` → `PipelineContext` - Shared context across all pipeline steps
- `IPublishingActivityReporter` → `IPipelineActivityReporter` - Interface for reporting pipeline activities
- `PublishingActivityReporter` → `PipelineActivityReporter` - Implementation of the pipeline activity reporter
- `NullPublishingActivityReporter` → `NullPipelineActivityReporter` - Null object pattern implementation
- `IPublishingStep` → `IReportingStep` - Interface for reporting steps
- `IPublishingTask` → `IReportingTask` - Interface for reporting tasks

Additionally, a new `PipelineStepContext` type has been introduced that combines the shared `PipelineContext` with a step-specific `IReportingStep`, allowing each step to track its own tasks and completion state independently.

## Type of breaking change

This change can affect [binary compatibility](../categories.md#binary-compatibility) and [source compatibility](../categories.md#source-compatibility).

## Reason for change

The previous three-level hierarchy (`ActivityReporter → Step → Task`) was unnecessarily complex. The new architecture simplifies this by automatically creating steps during pipeline execution and integrating step management directly into the pipeline. This provides a cleaner separation between the shared pipeline context and step-specific execution context, making the API more intuitive and reducing boilerplate code.

## Recommended action

Update your code to use the new type names and simplified step creation pattern:

1. Replace `DeployingContext` with `PipelineContext` for shared pipeline context or `PipelineStepContext` for step-specific context.
1. Replace `IPublishingActivityReporter` with `IPipelineActivityReporter`.
1. Replace `PublishingActivityReporter` with `PipelineActivityReporter`.
1. Replace `NullPublishingActivityReporter` with `NullPipelineActivityReporter`.
1. Replace `IPublishingStep` with `IReportingStep`.
1. Replace `IPublishingTask` with `IReportingTask`.
1. Update pipeline step actions to accept `PipelineStepContext` instead of `DeployingContext`.
1. Remove explicit step creation calls within pipeline actions and use the automatically created `context.ReportingStep` instead.

Migration example:

```csharp
// Before
builder.Pipeline.AddStep("my-step", async (context) =>
{
var step = await context.ActivityReporter
.CreateStepAsync("my-step", context.CancellationToken);

await using (step.ConfigureAwait(false))
{
var task = await step.CreateTaskAsync("Doing work...", context.CancellationToken);
await using (task.ConfigureAwait(false))
{
// Do work
await task.CompleteAsync("Done", CompletionState.Completed, context.CancellationToken);
}
}
});

// After
builder.Pipeline.AddStep("my-step", async (stepContext) =>
{
var task = await stepContext.ReportingStep
.CreateTaskAsync("Doing work...", stepContext.CancellationToken);

await using (task.ConfigureAwait(false))
{
// Do work
await task.CompleteAsync("Done", CompletionState.Completed, stepContext.CancellationToken);
}
});
```

## Affected APIs

- <xref:Aspire.Hosting.ApplicationModel.DeployingContext?displayProperty=fullName>
- <xref:Aspire.Hosting.Publishing.IPublishingActivityReporter?displayProperty=fullName>
- `Aspire.Hosting.Publishing.PublishingActivityReporter`
- <xref:Aspire.Hosting.Publishing.NullPublishingActivityReporter?displayProperty=fullName>
- <xref:Aspire.Hosting.Publishing.IPublishingStep?displayProperty=fullName>
- <xref:Aspire.Hosting.Publishing.IPublishingTask?displayProperty=fullName>
- `Aspire.Hosting.Publishing.PublishingStep`
- `Aspire.Hosting.Publishing.PublishingTask`
- <xref:Aspire.Hosting.Publishing.PublishingExtensions?displayProperty=fullName>
2 changes: 2 additions & 0 deletions docs/compatibility/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ items:
- name: Breaking changes in 13.0
expanded: true
items:
- name: Activity reporter and pipeline context renamed
href: 13.0/pipeline-activity-reporter-renamed.md
- name: DefaultAzureCredential defaults to ManagedIdentityCredential on ACA and App Service
href: 13.0/defaultazurecredential-managedidentity-default.md
- name: Aspire 9.5
Expand Down
2 changes: 1 addition & 1 deletion docs/extensibility/interaction-service.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ These approaches help you create interactive, user-friendly experiences for loca
> });
> ```
>
> For CLI specific contexts, the interaction service is retrieved from either the `PublishingContext` or `DeploymentContext` depending on the operation being performed.
> For CLI specific contexts, the interaction service is retrieved from either the `PublishingContext` or `PipelineStepContext` depending on the operation being performed.

## Display messages

Expand Down
18 changes: 9 additions & 9 deletions docs/fundamentals/custom-deployments.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Aspire provides powerful APIs for building container images from your resources
During publishing and deployment, the container image builder is available to create images for resources that need them. Aspire uses this builder when a resource requires a container image, such as when publishing with Docker Compose. The process involves two main components:

- <xref:Aspire.Hosting.Publishing.IResourceContainerImageBuilder>: The service that turns resource definitions into runnable container images.
- <xref:Aspire.Hosting.Publishing.IPublishingActivityReporter>: The API that provides structured progress reporting during long-running operations.
- `IPipelineActivityReporter`: The API that provides structured progress reporting during long-running operations.

These APIs give you fine-grained control over the image building process and provide real-time feedback to users during lengthy build operations.

Expand Down Expand Up @@ -53,27 +53,27 @@ The <xref:Aspire.Hosting.Publishing.ContainerBuildOptions> class provides strong

The builder performs container runtime health checks (Docker/Podman) only when at least one resource requires a Dockerfile build. This change eliminates false-positive errors in projects that publish directly from .NET assemblies. If the container runtime is required but unhealthy, the builder throws an explicit `InvalidOperationException` to surface the problem early.

## Publishing activity reporter API
## Pipeline activity reporter API

The `PublishingActivityProgressReporter` API enables structured progress reporting during [`aspire publish`](../cli-reference/aspire-publish.md) and [`aspire deploy`](../cli-reference/aspire-deploy.md) commands. This reduces uncertainty during long-running operations and surfaces failures early.
The `PipelineActivityReporter` API enables structured progress reporting during [`aspire publish`](../cli-reference/aspire-publish.md) and [`aspire deploy`](../cli-reference/aspire-deploy.md) commands. This reduces uncertainty during long-running operations and surfaces failures early.

### API overview and behavior

The progress reporter uses a hierarchical model with guaranteed ordering and thread-safe operations:

| Concept | Description | CLI Rendering | Behavior |
|---------|-------------|---------------|----------|
| **Step** | Top-level phase, such as "Build images" or "Deploy workloads". | Step message with status glyph and elapsed time. | Forms a strict tree structure; nested steps are unsupported. |
| **Step** | Top-level phase, such as "Build images" or "Deploy workloads". | Step message with status glyph and elapsed time. | Forms a strict tree structure; nested steps are unsupported. Steps are created automatically during pipeline execution. |
| **Task** | Discrete unit of work nested under a step. | Task message with indentation. | Belongs to a single step; supports parallel creation with deterministic completion ordering. |
| **Completion state** | Final status: `Completed`, `Warning`, or `Error`. | ✅ (Completed), ⚠️ (Warning), ❌ (Error) | Each step/task transitions exactly once to a final state. |

### API structure and usage

The reporter API provides structured access to progress reporting with the following characteristics:

- **Acquisition**: Retrieved from `PublishingContext.ActivityReporter` or `DeployingContext.ActivityReporter`.
- **Step creation**: `CreateStepAsync(title, ct)` returns an `IPublishingActivityStep`.
- **Task creation**: `IPublishingActivityStep.CreateTaskAsync(title, ct)` returns an `IPublishingActivityTask`.
- **Acquisition**: Retrieved from `PublishingContext.ActivityReporter` or through the `PipelineStepContext.ReportingStep` property in pipeline steps.
- **Step creation**: Steps are now created automatically during pipeline execution. The `CreateStepAsync(title, ct)` method returns an `IReportingStep`.
- **Task creation**: `IReportingStep.CreateTaskAsync(title, ct)` returns an `IReportingTask`.
- **State transitions**: `SucceedAsync`, `WarnAsync`, `FailAsync` methods accept a summary message.
- **Completion**: `CompletePublishAsync(message, state, isDeploy, ct)` marks the entire operation.
- **Ordering**: Creation and completion events preserve call order; updates are serialized.
Expand Down Expand Up @@ -130,7 +130,7 @@ The preceding code:

- Implements a publishing pipeline that builds container images and generates deployment manifests.
- Uses the `IResourceContainerImageBuilder` API to build container images.
- Reports progress and completion status using the `PublishingActivityProgressReporter` API.
- Reports progress and completion status using the `PipelineActivityReporter` API.

Your publishing callback might use `IResourceContainerImageBuilder` to build container images, while your deployment callback might use the built images and push them to a registry or deployment target.

Expand All @@ -143,7 +143,7 @@ Like the publishing callback, the deploying callback is registered using the `De
The preceding code:

- Simulates deploying workloads to a Kubernetes cluster.
- Uses the `PublishingActivityProgressReporter` API to create and manage deployment steps and tasks.
- Uses the `PipelineActivityReporter` API to create and manage deployment steps and tasks.
- Reports progress and marks each deployment phase as completed.
- Completes the deployment operation with a final status update.
- Handles cancellation through the provided `CancellationToken`.
Expand Down