Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 22, 2025

Pipeline Steps Tagging Support - MERGED WITH MAIN ✅

Successfully merged with main branch! All conflicts resolved.

Latest Changes

Commit cf743d0 - Azure Environment Resource:

  • Updated AzureEnvironmentResource to use unique step names with proper tags
  • Steps now have descriptive names: "provision-azure-bicep-resources", "build-container-images", "deploy-compute-resources"
  • Tags property properly used for categorization with WellKnownPipelineTags constants

Commit [current] - Merge with main:

  • Merged latest changes from main branch
  • Resolved conflicts in DistributedApplicationPipelineTests.cs
  • Added 4 new tests from main for step filtering functionality
  • All 64 tests passing

Implementation Summary

1. WellKnownPipelineTags

  • Single class with constants for categorizing pipeline steps (not for step names)

2. Pipeline Configuration Phase

  • AddPipelineConfiguration() for registering callbacks
  • WithPipelineConfiguration() for resource-level configuration

3. PipelineConfigurationContext API

  • Services - IServiceProvider for dependency resolution
  • Steps - IReadOnlyList of all collected steps
  • Model - Access to DistributedApplicationModel (consistent naming)
  • GetSteps() overloads for finding steps by tag, resource, or both

4. Proper Usage of Tags

  • Step names are unique identifiers (e.g., "provision-azure-bicep-resources")
  • Tags are used for categorization and filtering (e.g., WellKnownPipelineTags.ProvisionInfrastructure)

5. Test Coverage

  • All 64 pipeline tests passing
  • Includes new tests from main for step filtering

Example Usage

// Steps with unique names and tags
var provisionStep = new PipelineStep
{
    Name = "provision-azure-bicep-resources",
    Action = ctx => ProvisionAsync(ctx),
    Tags = [WellKnownPipelineTags.ProvisionInfrastructure]
};

// Configuration phase uses tags to find related steps
pipeline.AddPipelineConfiguration((context) =>
{
    var provisionSteps = context.GetSteps(WellKnownPipelineTags.ProvisionInfrastructure);
    var buildSteps = context.GetSteps(WellKnownPipelineTags.BuildCompute);
    
    foreach (var build in buildSteps)
        foreach (var provision in provisionSteps)
            build.DependsOn(provision);
    
    return Task.CompletedTask;
});

Status: Ready for re-review

Original prompt

This section details on the original issue you should resolve

<issue_title>Support annotating pipeline steps with tags</issue_title>
<issue_description>1. Rename WellKnownPipelineSteps to WellKnownPipelineTags
2. Add a List<string> Tags property to PipelineStep.
3. While collecting pipeline steps from resource annotations in the DistributedApplicationPipelineApplication execution, maintain a dictionary between steps and the resources that it produced.
4. Add a second pass to the DistributedApplicationPipelineApplication after all steps are collected that allows users to update the DependsOn and RequiredBy in steps.
5. There should be an API to register a second-pass using either the builder.Pipeline property or a PipelinePassFactory annotation on a resource.
6. The PipelinePassFactory should expose a Callback that supports async and takes a context that exposes a service provider, the list of pipeline steps, the resource that registered the pass (if it came from a resource).
7. There should be an API to for pipeline steps with a certain tag and resource. Use the map created in #3 to facilitate this.</issue_description>

Comments on the Issue (you are @copilot in this section)

Fixes #12289


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Support annotating pipeline steps with tags Add support for pipeline step tagging and second-pass dependency configuration Oct 23, 2025
Copilot AI requested a review from captainsafia October 23, 2025 00:08
Copilot finished work on behalf of captainsafia October 23, 2025 00:08
Copy link
Member

@captainsafia captainsafia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Fix these issues.

#pragma warning disable ASPIREAZURE001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
#pragma warning disable ASPIREPUBLISHERS001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
#pragma warning disable ASPIREINTERACTION001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
#pragma warning disable CS0618 // Type or member is obsolete
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pragma was needed because we had marked WellKnownPipelineSteps as obsolete while keeping it for backward compatibility. I've now removed the obsolete class entirely and renamed WellKnownPipelineSteps to WellKnownPipelineTags as requested, so the pragma is no longer needed. Fixed in 3a44d2f.

_steps.Add(step);
}

public void AddSecondPassCallback(Func<PipelinePassContext, Task> callback)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public void AddSecondPassCallback(Func<PipelinePassContext, Task> callback)
public void AddPipelineConfiguration(Func<PipelineConfigurationContext, Task> callback)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Renamed to AddPipelineConfiguration in 3a44d2f.

/// allowing modification of step dependencies and relationships.
/// </summary>
[Experimental("ASPIREPIPELINES001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")]
public class PipelinePassAnnotation : IResourceAnnotation
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public class PipelinePassAnnotation : IResourceAnnotation
public class PipelineConfigurationAnnotation : IResourceAnnotation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Renamed to PipelineConfigurationAnnotation in 3a44d2f.

/// <summary>
/// Gets the resource that registered this pass callback, if any.
/// </summary>
public IResource? Resource { get; internal set; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the Resource property from this context and add a property for the DistributedApplicationModel.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Removed the Resource property and added ApplicationModel property to PipelineConfigurationContext. Tests updated to find resources via ApplicationModel.Resources. Fixed in 3a44d2f.

/// Defines well-known pipeline step names used in the deployment process.
/// </summary>
[Experimental("ASPIREPIPELINES001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")]
[Obsolete("Use WellKnownPipelineTags instead.")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use obsolete here. Rename this type and remove the new one you added.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Removed the obsolete attribute and the duplicate WellKnownPipelineTags class. WellKnownPipelineSteps has been renamed to WellKnownPipelineTags as the single source of truth. Fixed in 3a44d2f.

Copy link
Contributor Author

Copilot AI commented Oct 23, 2025

@copilot Fix these issues.

All issues have been addressed in commit 3a44d2f:

  • Renamed classes and methods per review feedback
  • Removed obsolete class and pragmas
  • Updated context API (removed Resource, added ApplicationModel)
  • All 60 tests passing

Copilot AI changed the title Add support for pipeline step tagging and second-pass dependency configuration Add support for pipeline step tagging and configuration phase dependency management Oct 23, 2025
Copilot AI requested a review from captainsafia October 23, 2025 00:25
Copilot finished work on behalf of captainsafia October 23, 2025 00:25
@eerhardt
Copy link
Member

@copilot - Fix the bulid errors in playground/pipelines/Pipelines.AppHost/AppHost.cs

Copy link
Contributor Author

Copilot AI commented Oct 23, 2025

@copilot - Fix the bulid errors in playground/pipelines/Pipelines.AppHost/AppHost.cs

Fixed the build errors in playground/pipelines/Pipelines.AppHost/AppHost.cs. The file was using WellKnownPipelineSteps which we renamed to WellKnownPipelineTags. Updated all three occurrences. Fixed in 19d0a8c.

Copilot finished work on behalf of eerhardt October 23, 2025 14:41
Copilot AI requested a review from eerhardt October 23, 2025 14:41
@captainsafia
Copy link
Member

@copilot Update the dependsOn and requiredBy arguments in AzureEnvironmentResource to refer to the specific steps that are declared instead of tags.

Copy link
Contributor Author

Copilot AI commented Oct 23, 2025

@copilot Update the dependsOn and requiredBy arguments in AzureEnvironmentResource to refer to the specific steps that are declared instead of tags.

Updated AzureEnvironmentResource to use unique step names instead of tag constants. Steps now have descriptive names:

  • "provision-azure-bicep-resources" (with ProvisionInfrastructure tag)
  • "build-container-images" (with BuildCompute tag)
  • "deploy-compute-resources" (with DeployCompute tag)

The WellKnownPipelineTags constants are now properly used as tags for categorization rather than as step names. Fixed in cf743d0.

Copilot finished work on behalf of captainsafia October 23, 2025 15:54
@captainsafia
Copy link
Member

@copilot There's a merge conflict DistributedApplicationPipelineTests.cs in main and the one in this branch. Resolve the merge conflicts with main.

Copy link
Contributor Author

Copilot AI commented Oct 23, 2025

@copilot There's a merge conflict DistributedApplicationPipelineTests.cs in main and the one in this branch. Resolve the merge conflicts with main.

Resolved the merge conflict in DistributedApplicationPipelineTests.cs. Merged main branch and kept both sets of tests:

  • My tagging/configuration tests (12 tests)
  • New step filtering tests from main (4 tests)

All 64 tests now passing. Fixed in ce6b7d9.

Copilot finished work on behalf of captainsafia October 23, 2025 16:07
@captainsafia captainsafia force-pushed the copilot/support-annotating-pipeline-steps-again branch from ce6b7d9 to ceba773 Compare October 23, 2025 17:18
@github-actions
Copy link
Contributor

github-actions bot commented Oct 23, 2025

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 12293

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 12293"

Copilot AI and others added 9 commits October 23, 2025 10:21
- Rename WellKnownPipelineSteps to WellKnownPipelineTags (keep old class for backward compatibility)
- Add Tags property to PipelineStep
- Create PipelinePassAnnotation and PipelinePassContext for second-pass callbacks
- Implement step-to-resource mapping during step collection
- Add AddSecondPassCallback API to IDistributedApplicationPipeline
- Add extension methods for registering second-pass callbacks on resources
- Add helper methods to find steps by tag, resource, or both

Co-authored-by: captainsafia <1857993+captainsafia@users.noreply.github.com>
- Test Tags property on PipelineStep
- Test second-pass callback execution and step dependency modification
- Test finding steps by tag, resource, and tag+resource combination
- Test WithPipelinePassCallback extension methods (sync and async)
- Test resource capture in second-pass callbacks
- Test complex dependency relationships using tags
- Test WellKnownPipelineTags constants and backward compatibility
- Ensure second-pass callbacks execute even when no steps exist

Co-authored-by: captainsafia <1857993+captainsafia@users.noreply.github.com>
Co-authored-by: captainsafia <1857993+captainsafia@users.noreply.github.com>
- Rename WellKnownPipelineSteps to WellKnownPipelineTags (removed obsolete class)
- Rename PipelinePassAnnotation to PipelineConfigurationAnnotation
- Rename PipelinePassContext to PipelineConfigurationContext
- Rename AddSecondPassCallback to AddPipelineConfiguration
- Rename WithPipelinePassCallback to WithPipelineConfiguration
- Remove Resource property from context, add ApplicationModel property
- Update all tests to use new API
- Remove CS0618 pragma warnings (no longer needed)

Co-authored-by: captainsafia <1857993+captainsafia@users.noreply.github.com>
- Fix build errors in playground AppHost (use WellKnownPipelineTags)
- Rename ApplicationModel to Model for consistency with PipelineContext
- Rename Find* methods to GetSteps with overloads (tag/resource/both)
- Update StepToResourceMap to use required initialization pattern
- Update all tests to use new API naming

Co-authored-by: eerhardt <8291187+eerhardt@users.noreply.github.com>
- Changed provision step name from WellKnownPipelineTags.ProvisionInfrastructure to "provision-azure-bicep-resources" with tag
- Changed build step name from WellKnownPipelineTags.BuildCompute to "build-container-images" with tag
- Changed deploy step name from WellKnownPipelineTags.DeployCompute to "deploy-compute-resources" with tag
- Step names are now unique identifiers while tags are used for categorization

Co-authored-by: captainsafia <1857993+captainsafia@users.noreply.github.com>
- Merged latest changes from main branch
- Resolved merge conflict in DistributedApplicationPipelineTests.cs
- Kept both sets of tests: tagging/configuration tests and step filtering tests
- All 64 tests passing (60 original + 4 new from main)

Co-authored-by: captainsafia <1857993+captainsafia@users.noreply.github.com>
@captainsafia captainsafia force-pushed the copilot/support-annotating-pipeline-steps-again branch from ceba773 to 7a6fd89 Compare October 23, 2025 17:21
@captainsafia captainsafia marked this pull request as ready for review October 23, 2025 17:23
Copilot AI review requested due to automatic review settings October 23, 2025 17:23
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements pipeline step tagging and configuration phase dependency management by renaming WellKnownPipelineSteps to WellKnownPipelineTags, adding a Tags property to pipeline steps, and introducing a configuration phase that allows modification of step dependencies after initial collection.

Key Changes:

  • Renamed WellKnownPipelineSteps to WellKnownPipelineTags to reflect that these are categorization tags, not step names
  • Added Tags property to PipelineStep for categorizing steps
  • Implemented configuration phase with AddPipelineConfiguration() and WithPipelineConfiguration() APIs
  • Created PipelineConfigurationContext with methods to query steps by tag, resource, or both
  • Updated step names in AzureEnvironmentResource to be descriptive and unique, using tags for categorization

Reviewed Changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
WellKnownPipelineTags.cs Renamed class and updated documentation to clarify these are tags for categorization, not step names
PipelineStep.cs Added Tags property for step categorization
PipelineConfigurationContext.cs New context class providing APIs to query steps and access model/services
PipelineConfigurationAnnotation.cs New annotation for resource-level configuration callbacks
PipelineStepExtensions.cs Added WithPipelineConfiguration() extension methods for resources
IDistributedApplicationPipeline.cs Added AddPipelineConfiguration() method to interface
DistributedApplicationPipeline.cs Implemented configuration phase execution and step-to-resource mapping
AzureEnvironmentResource.cs Updated to use unique step names with proper tagging
DistributedApplicationPipelineTests.cs Added 13 comprehensive tests for new functionality
Pipelines.Library/DistributedApplicationPipelineExtensions.cs Updated reference from WellKnownPipelineSteps to WellKnownPipelineTags
Pipelines.AppHost/AppHost.cs Updated references from WellKnownPipelineSteps to WellKnownPipelineTags

Comment on lines +119 to +121
// Execute configuration callbacks even if there are no steps
// This allows callbacks to run validation or other logic
await ExecuteConfigurationCallbacksAsync(context, allSteps, stepToResourceMap).ConfigureAwait(false);
Copy link

Copilot AI Oct 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the explanatory comments about executing configuration callbacks. The method name ExecuteConfigurationCallbacksAsync is self-documenting, and the comment simply restates what the code does rather than explaining why or providing useful context.

Copilot generated this review using guidance from repository custom instructions.
Copy link
Member

@eerhardt eerhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I just had some minor comments.

/// </summary>
public required DistributedApplicationModel Model { get; init; }

internal IReadOnlyDictionary<PipelineStep, IResource> StepToResourceMap { get; init; } = null!;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
internal IReadOnlyDictionary<PipelineStep, IResource> StepToResourceMap { get; init; } = null!;
internal required IReadOnlyDictionary<PipelineStep, IResource> StepToResourceMap { get; init; }

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unfortunate that it is internal, but the ctor is public. If we want to keep it that way, we should reall make this:

Suggested change
internal IReadOnlyDictionary<PipelineStep, IResource> StepToResourceMap { get; init; } = null!;
internal IReadOnlyDictionary<PipelineStep, IResource>? StepToResourceMap { get; init; }

@captainsafia captainsafia merged commit b2f90eb into main Oct 23, 2025
302 checks passed
@captainsafia captainsafia deleted the copilot/support-annotating-pipeline-steps-again branch October 23, 2025 17:55
@captainsafia
Copy link
Member

@copilot Open a new PR and address the feedback in #12293 (comment).

@dotnet-policy-service dotnet-policy-service bot added this to the 13.0 milestone Oct 23, 2025
Copilot AI added a commit that referenced this pull request Oct 23, 2025
Co-authored-by: captainsafia <1857993+captainsafia@users.noreply.github.com>
captainsafia added a commit that referenced this pull request Oct 23, 2025
… safety (#12320)

* Initial plan

* Make StepToResourceMap nullable to address PR #12293 feedback

Co-authored-by: captainsafia <1857993+captainsafia@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: captainsafia <1857993+captainsafia@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support annotating pipeline steps with tags

3 participants