Skip to content

Graduate pipeline output service APIs to stable - #20814

Merged
Mitch Denny (mitchdenny) merged 1 commit into
mainfrom
mitchdenny-stable-pipeline-output-apis
Oct 8, 2026
Merged

Mitch Denny (mitchdenny) merged 1 commit into
mainfrom
mitchdenny-stable-pipeline-output-apis

Conversation

@mitchdenny

@mitchdenny Mitch Denny (mitchdenny) commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

Description

Graduate the pipeline output-directory API family so consumers can use IPipelineOutputService without suppressing ASPIREPIPELINES004.

The only actual source declarations carrying this diagnostic are IPipelineOutputService and the internal PipelineOutputService. Remove both experimental attributes, their unused imports, and all suppressions for this diagnostic in hosting, Azure deployment infrastructure, Entity Framework Core, Radius, the linked publishing helper, and test consumers.

All four method signatures, output/temp-directory behavior, resource-specific routing, defaults, and lifecycle/cleanup semantics remain unchanged. This PR introduces no graduation of other diagnostic families. Rebased onto 4932ff6cfd, preserving the filesystem and core-pipeline graduations already on main; the previously necessary local PipelineOptions suppression is no longer needed because PipelineOptions is now stable on main.

No directly related documentation explicitly labels this family experimental. The generated api/*.cs baseline is intentionally untouched and remains the sole ASPIREPIPELINES004 reference. This is an independent change based on main, not stacked on other graduation PRs. No new dependencies or package/version changes.

User-facing usage

Given an IPipelineOutputService outputService and an IResource resource, the existing calls no longer require an ASPIREPIPELINES004 suppression:

var outputDirectory = outputService.GetOutputDirectory();
var resourceOutputDirectory = outputService.GetOutputDirectory(resource);
var tempDirectory = outputService.GetTempDirectory();
var resourceTempDirectory = outputService.GetTempDirectory(resource);

Validation

Passed on macOS arm64:

./restore.sh

Result: succeeded, 0 warnings and 0 errors (initial validation).

Re-run after rebasing onto 4932ff6cfd:

MSBUILDTERMINALLOGGER=false dotnet test --project tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj --no-launch-profile -p:SkipNativeBuild=true -- --filter-method '*.PipelineOutputService*' --filter-not-trait 'quarantined=true' --filter-not-trait 'outerloop=true'

Result: 3 passed, 0 failed, 0 skipped. Covers the AppHost-directory default, explicit output-path precedence with an invalid AppHost directory, and current-directory fallback. Builds hosting and its test utilities as dependencies.

MSBUILDTERMINALLOGGER=false dotnet build src/Aspire.Hosting.Azure/Aspire.Hosting.Azure.csproj --no-restore -p:SkipNativeBuild=true --verbosity quiet
MSBUILDTERMINALLOGGER=false dotnet build src/Aspire.Hosting.Azure.Sandboxes/Aspire.Hosting.Azure.Sandboxes.csproj --no-restore -p:SkipNativeBuild=true --verbosity quiet
MSBUILDTERMINALLOGGER=false dotnet build src/Aspire.Hosting.EntityFrameworkCore/Aspire.Hosting.EntityFrameworkCore.csproj --no-restore -p:SkipNativeBuild=true --verbosity quiet
MSBUILDTERMINALLOGGER=false dotnet build src/Aspire.Hosting.Radius/Aspire.Hosting.Radius.csproj --no-restore -p:SkipNativeBuild=true --verbosity quiet
MSBUILDTERMINALLOGGER=false dotnet build src/Aspire.Hosting.Docker/Aspire.Hosting.Docker.csproj --no-restore -p:SkipNativeBuild=true --verbosity quiet
MSBUILDTERMINALLOGGER=false dotnet build src/Aspire.Hosting.Kubernetes/Aspire.Hosting.Kubernetes.csproj --no-restore -p:SkipNativeBuild=true --verbosity quiet

Result: all six builds succeeded with 0 warnings and 0 errors, including every project linking PublishingContextUtils.cs.

git diff origin/main...HEAD --check

Result: passed. An exact-content comparison (ignoring blank lines) verified that all 13 changed files contain only diagnostic-specific cleanup; all signatures and executable code match main.

Limitations: full solution/test suite, native AOT builds, and live cloud deployments were not run for this attribute-only graduation.

Fixes # (issue)

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

🚀 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/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 20814

Or

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

@github-actions github-actions Bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Oct 8, 2026
@aspire-repo-bot
aspire-repo-bot Bot requested a balanced review from Copilot October 8, 2026 06:27
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The changes consistently graduate the API while preserving signatures and implementation behavior.

0 open findings

What changed in this PR

Graduates IPipelineOutputService from experimental status without changing runtime behavior.

Changes:

  • Removes ASPIREPIPELINES004 attributes and suppressions.
  • Retains a targeted suppression for experimental PipelineOptions.
File Description
tests/​Aspire.Hosting.TestUtilities/​Helpers/​JsonDocumentManifestPublisher.cs Removes obsolete suppression.
tests/​Aspire.Hosting.Tests/​DistributedApplicationBuilderTests.cs Removes obsolete suppression.
src/​Shared/​PublishingContextUtils.cs Removes obsolete suppression.
src/​Aspire.Hosting/​Pipelines/​PipelineOutputService.cs Graduates implementation while suppressing PipelineOptions.
src/​Aspire.Hosting/​Pipelines/​IPipelineOutputService.cs Graduates the public interface.
src/​Aspire.Hosting/​DistributedApplicationBuilder.cs Removes obsolete suppression.
src/​Aspire.Hosting.Radius/​Publishing/​SealedSecretApplyStep.cs Removes obsolete suppression.
src/​Aspire.Hosting.Radius/​Publishing/​RadiusDeploymentPipelineStep.cs Removes obsolete suppression.
src/​Aspire.Hosting.Radius/​Publishing/​RadiusBicepPublishingContext.cs Removes obsolete suppression.
src/​Aspire.Hosting.Radius/​Publishing/​RadCredentialRegisterStep.cs Removes obsolete suppression.
src/​Aspire.Hosting.EntityFrameworkCore/​EFResourceBuilderExtensions.cs Removes localized suppression.
src/​Aspire.Hosting.Azure/​AzureEnvironmentResource.cs Removes obsolete suppression.
src/​Aspire.Hosting.Azure.Sandboxes/​AzureSandboxContainerDeployment.cs Removes obsolete suppression.

🧠 Review effort: Balanced


Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewed all 13 changed files and relevant service consumers and existing tests. No high-confidence findings. Changes are limited to experimental attributes and diagnostic suppression cleanup; method signatures, runtime behavior, and DI registration are unchanged. Validation: git diff --check passed; current PR checks show 282 successful and 16 skipped checks. No local builds or tests were run.

@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The changes consistently graduate the API without altering signatures or runtime behavior.

0 open findings

🧠 Review effort: Balanced


Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.

Remove ASPIREPIPELINES004 attributes and obsolete consumer suppressions while preserving all API signatures and directory behavior. Keep PipelineOptions experimental with a local implementation suppression.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Tests selector

50 / 98 PR test projects · 4 PR jobs, from 13 changed files.

Selected PR test projects (50 / 98)

Aspire.Cli.EndToEnd.Tests, Aspire.Hosting.Analyzers.Tests, Aspire.Hosting.Azure.Kubernetes.Tests, Aspire.Hosting.Azure.Kusto.Tests, Aspire.Hosting.Azure.Provisioning.Tests, Aspire.Hosting.Azure.Tests, Aspire.Hosting.Blazor.Tests, Aspire.Hosting.Browsers.Tests, Aspire.Hosting.CodeGeneration.Go.Tests, Aspire.Hosting.CodeGeneration.Java.Tests, Aspire.Hosting.CodeGeneration.Python.Tests, Aspire.Hosting.CodeGeneration.Rust.Tests, Aspire.Hosting.CodeGeneration.TypeScript.Tests, Aspire.Hosting.Containers.Tests, Aspire.Hosting.DevTunnels.Tests, Aspire.Hosting.Docker.Tests, Aspire.Hosting.Dotnet.Tests, Aspire.Hosting.DotnetTool.Tests, Aspire.Hosting.EntityFrameworkCore.Tests, Aspire.Hosting.Foundry.Tests, Aspire.Hosting.Garnet.Tests, Aspire.Hosting.Go.Tests, Aspire.Hosting.Java.Tests, Aspire.Hosting.JavaScript.Tests, Aspire.Hosting.Kafka.Tests, Aspire.Hosting.Keycloak.Tests, Aspire.Hosting.Kubernetes.Tests, Aspire.Hosting.Maui.Tests, Aspire.Hosting.Milvus.Tests, Aspire.Hosting.MongoDB.Tests, Aspire.Hosting.MySql.Tests, Aspire.Hosting.Nats.Tests, Aspire.Hosting.OpenAI.Tests, Aspire.Hosting.Oracle.Tests, Aspire.Hosting.Orleans.Tests, Aspire.Hosting.PostgreSQL.Tests, Aspire.Hosting.Python.Tests, Aspire.Hosting.Qdrant.Tests, Aspire.Hosting.RabbitMQ.Tests, Aspire.Hosting.Radius.Tests, Aspire.Hosting.Redis.Tests, Aspire.Hosting.RemoteHost.Tests, Aspire.Hosting.Rust.Tests, Aspire.Hosting.Seq.Tests, Aspire.Hosting.SqlServer.Tests, Aspire.Hosting.Testing.Tests, Aspire.Hosting.Tests, Aspire.Hosting.Valkey.Tests, Aspire.Hosting.Yarp.Tests, Aspire.Playground.Tests

Selected PR jobs (4)

cli-starter-validation, extension-e2e, polyglot, typescript-api-compat


How these were chosen — grouped by what changed

⚠️ 29 of the 50 selected test projects come from a single change — tests/Aspire.Hosting.TestUtilities/Helpers/JsonDocumentManifestPublisher.cs.

🧪 tests/Aspire.Hosting.TestUtilities/Helpers/JsonDocumentManifestPublisher.cs (changed test)
→ 29 via the project graph

show 29

Aspire.Hosting.Azure.Kubernetes.Tests, Aspire.Hosting.Azure.Kusto.Tests, Aspire.Hosting.Browsers.Tests, Aspire.Hosting.Containers.Tests, Aspire.Hosting.DevTunnels.Tests, Aspire.Hosting.DotnetTool.Tests, Aspire.Hosting.Foundry.Tests, Aspire.Hosting.Garnet.Tests, Aspire.Hosting.Go.Tests, Aspire.Hosting.Java.Tests, Aspire.Hosting.JavaScript.Tests, Aspire.Hosting.Kafka.Tests, Aspire.Hosting.Keycloak.Tests, Aspire.Hosting.Milvus.Tests, Aspire.Hosting.MongoDB.Tests, Aspire.Hosting.MySql.Tests, Aspire.Hosting.Nats.Tests, Aspire.Hosting.OpenAI.Tests, Aspire.Hosting.Oracle.Tests, Aspire.Hosting.Orleans.Tests, Aspire.Hosting.PostgreSQL.Tests, Aspire.Hosting.Python.Tests, Aspire.Hosting.Qdrant.Tests, Aspire.Hosting.RabbitMQ.Tests, Aspire.Hosting.Redis.Tests, Aspire.Hosting.Rust.Tests, Aspire.Hosting.Seq.Tests, Aspire.Hosting.SqlServer.Tests, Aspire.Hosting.Valkey.Tests

🔧 src/Aspire.Hosting/DistributedApplicationBuilder.cs (changed source)
→ 10 via the project graph: Aspire.Hosting.Analyzers.Tests (2 hops), Aspire.Hosting.CodeGeneration.Go.Tests, Aspire.Hosting.CodeGeneration.Java.Tests, Aspire.Hosting.CodeGeneration.Python.Tests, Aspire.Hosting.CodeGeneration.Rust.Tests, Aspire.Hosting.CodeGeneration.TypeScript.Tests, Aspire.Hosting.Maui.Tests, Aspire.Hosting.RemoteHost.Tests, Aspire.Hosting.Testing.Tests (2 hops), Aspire.Playground.Tests

🔧 src/Shared/PublishingContextUtils.cs (changed source)
→ 3 via the project graph: Aspire.Hosting.Docker.Tests, Aspire.Hosting.Kubernetes.Tests, Aspire.Hosting.Yarp.Tests

🧪 tests/Aspire.Hosting.Tests/DistributedApplicationBuilderTests.cs (changed test)
→ 1 directly: Aspire.Hosting.Tests
→ 2 via the project graph: Aspire.Hosting.Blazor.Tests, Aspire.Hosting.Dotnet.Tests

🔧 src/Aspire.Hosting.Azure/AzureEnvironmentResource.cs (changed source)
→ 1 directly: Aspire.Hosting.Azure.Tests
→ 1 via the project graph: Aspire.Hosting.Azure.Provisioning.Tests (2 hops)

📦 affected project Aspire.Hosting.EntityFrameworkCore
→ 1 test: Aspire.Cli.EndToEnd.Tests

🔧 src/Aspire.Hosting.Azure.Sandboxes/AzureSandboxContainerDeployment.cs (changed source)
→ 1 directly: Aspire.Hosting.Azure.Tests

🔧 src/Aspire.Hosting.EntityFrameworkCore/EFResourceBuilderExtensions.cs (changed source)
→ 1 directly: Aspire.Hosting.EntityFrameworkCore.Tests

🔧 src/Aspire.Hosting.Radius/Publishing/RadCredentialRegisterStep.cs (changed source)
→ 1 directly: Aspire.Hosting.Radius.Tests

🔧 src/Aspire.Hosting.Radius/Publishing/RadiusBicepPublishingContext.cs (changed source)
→ 1 directly: Aspire.Hosting.Radius.Tests

🔧 src/Aspire.Hosting.Radius/Publishing/RadiusDeploymentPipelineStep.cs (changed source)
→ 1 directly: Aspire.Hosting.Radius.Tests

🔧 src/Aspire.Hosting.Radius/Publishing/SealedSecretApplyStep.cs (changed source)
→ 1 directly: Aspire.Hosting.Radius.Tests

Job reasons

Job Triggered by
cli-starter-validation affected project Aspire.Hosting.PostgreSQL
extension-e2e • src/Aspire.Hosting/DistributedApplicationBuilder.cs, src/Aspire.Hosting/Pipelines/IPipelineOutputService.cs, src/Aspire.Hosting/Pipelines/PipelineOutputService.cs
• affected project Aspire.Hosting
polyglot • affected project Aspire.Hosting.Azure.Sandboxes
• affected project Aspire.Hosting.Azure.Provisioning.KeyVault
typescript-api-compat affected project Aspire.Hosting.Azure.Sandboxes

Selection computed for commit 5679885.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The changes consistently remove the experimental diagnostic without altering signatures or executable behavior.

0 open findings

🧠 Review effort: Balanced

@mitchdenny
Mitch Denny (mitchdenny) merged commit 4d4bee8 into main Oct 8, 2026
585 of 588 checks passed
@microsoft-github-policy-service microsoft-github-policy-service Bot added this to the 17.0 milestone Oct 8, 2026
@aspire-repo-bot

Copy link
Copy Markdown
Contributor

Pull request created: #1852

Generated by PR Documentation Check · copilot · auto · 54.3 AIC · ⌖ 10.6 AIC · ⊞ 20.4K

@aspire-repo-bot

Copy link
Copy Markdown
Contributor

📝 Documentation has been drafted in microsoft/aspire.dev#1852 targeting release/17.0.

Updated diagnostics/aspirepipelines004.mdx to note that IPipelineOutputService/PipelineOutputService graduated from experimental as of Aspire 17.0 and no longer trigger ASPIREPIPELINES004, following the existing graduation-note pattern used by ASPIREPIPELINES001/ASPIREAZURE002/ASPIRECOSMOSDB001. Triggered signals: pr_body_has_user_facing_section (PR body's "User-facing usage" section shows the four IPipelineOutputService calls no longer need suppression) and pr_body_has_cli_flag_mention (false-positive match on a dotnet test command in the validation section, not an actual CLI flag addition).

Note

This draft PR needs human review before merging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants