microsoft / microsoft/aspire

Graduate experimental Aspire APIs

Open
#17,175 7 comments 2 reactions 1 assignee Claimed by @sebastienros View on GitHub
💥 blocking-release 💥 triage:bot-seen
Dominant language
C#
Stars
6.3k
Forks
991
Avg merge
2d 15h
Merged PRs (30d)
196

Description

# Graduate experimental Aspire APIs

## Current decision summary

**Updated 2026-09-14.** Source: [`main` at 51c8f93ed00b](https://github.com/microsoft/aspire/tree/51c8f93ed00b11f8b8afbe979951171cfd8182d3). Latest published stable release: [13.5.3](https://github.com/microsoft/aspire/releases/tag/v13.5.3), published **2026-08-25**.

| Decision signal | Current inventory |
|---|---:|
| Directly annotated public API/scope rows | 327 |
| Distinct diagnostic IDs | 40 |
| Rows found experimentally in at least one stable release | 245 |
| Rows not found experimentally in any stable release | 82 |
| Rows meeting the one-year release-age threshold | 8 |

Review the oldest still-experimental surfaces first, then decide **graduate / change API shape / retain with a documented blocker**. Release age alone does not establish usage, API stability, test coverage, or dependency readiness; those remain review inputs, not inferred conclusions.

## Graduation progress

The previously recorded eleven one-year-threshold graduations remain recorded: nine interaction APIs in #18032, plus `ConfigureCustomDomain` and `CompletionState` in #19007. This refresh preserves those decisions and replaces the stale pending list with current source evidence.

| Change since the original May inventory | Current status / evidence |
|---|---|
| ACA job APIs (`ASPIREAZURE002`) | Experimental markers removed in #17219. Excluded from the current experimental table. |
| ATS types and six assembly scopes (`ASPIREATS001`) | Experimental markers removed in #17600 / #17602. Excluded from the current experimental table; assembly-marker removal is not deletion of the assembly APIs. |
| Interaction APIs | #18032 removed markers from the existing interaction surface, beyond the nine rows recorded at the original age threshold. Three currently annotated rows still use this diagnostic; the family is not assumed completely graduated. |
| Custom domains and completion state | #19007 removed the markers; no longer pending. |
| Cosmos emulator | #19510 removed the experimental markers. `WithDataExplorer` is no longer experimental; `RunAsPreviewEmulator` is an **obsolete compatibility wrapper**, with `RunAsEmulator` the supported API. The old naming blocker is resolved by replacement/deprecation, not by treating the Preview name as the preferred graduated API. |
| JavaScript publish API | `PublishAsNpmScript` was renamed `PublishAsPackageScript` in #17382 and remains experimental. The table retains its verified earlier tenure rather than treating the rename as graduation. |
| Debug-support overload | The exact old four-parameter overload is no longer present. Current experimental overloads are listed separately; an absent signature is not counted as graduation. |

### Still experimental at the one-year threshold

Threshold: first published experimental release on or before **2025-09-14**. These are review candidates, not approved graduations.

| Age (days) | Release trains / releases | API | Review status |
|---:|---:|---|---|
| 483 | 9 / 39 | [`Aspire.Hosting.Azure.AzureEnvironmentResource`](https://github.com/microsoft/aspire/blob/51c8f93ed00b11f8b8afbe979951171cfd8182d3/src/Aspire.Hosting.Azure/AzureEnvironmentResource.cs#L25-L26) | Now included at the one-year threshold: experimental since 9.3, not 9.5. API-shape/dependency review still needed. |
| 483 | 9 / 39 | [`Aspire.Hosting.Azure.AzureEnvironmentResourceExtensions.AddAzureEnvironment`](https://github.com/microsoft/aspire/blob/51c8f93ed00b11f8b8afbe979951171cfd8182d3/src/Aspire.Hosting.Azure/AzureEnvironmentResourceExtensions.cs#L25-L26) | Still experimental; review together with AzureEnvironmentResource. The earlier 'younger dependency' age rationale was based on a later edit and is corrected. |
| 483 | 9 / 39 | [`Aspire.Hosting.Azure.AzureEnvironmentResourceExtensions.WithLocation`](https://github.com/microsoft/aspire/blob/51c8f93ed00b11f8b8afbe979951171cfd8182d3/src/Aspire.Hosting.Azure/AzureEnvironmentResourceExtensions.cs#L111-L112) | Still experimental; review together with AzureEnvironmentResource. The earlier 'younger dependency' age rationale was based on a later edit and is corrected. |
| 483 | 9 / 39 | [`Aspire.Hosting.Azure.AzureEnvironmentResourceExtensions.WithResourceGroup`](https://github.com/microsoft/aspire/blob/51c8f93ed00b11f8b8afbe979951171cfd8182d3/src/Aspire.Hosting.Azure/AzureEnvironmentResourceExtensions.cs#L136-L137) | Still experimental; review together with AzureEnvironmentResource. The earlier 'younger dependency' age rationale was based on a later edit and is corrected. |
| 483 | 9 / 39 | [`Aspire.Hosting.Azure.AzurePublishingContext`](https://github.com/microsoft/aspire/blob/51c8f93ed00b11f8b8afbe979951171cfd8182d3/src/Aspire.Hosting.Azure/AzurePublishingContext.cs#L27-L28) | Still experimental; recorded dependency concerns with environment/pipeline types require review, not automatic graduation. |
| 412 | 8 / 36 | [`Aspire.Hosting.Pipelines.PublishingExtensions`](https://github.com/microsoft/aspire/blob/51c8f93ed00b11f8b8afbe979951171cfd8182d3/src/Aspire.Hosting/Publishing/PublishingExtensions.cs#L13-L15) | Still experimental; recorded IReportingStep/IReportingTask/MarkdownString dependencies need review. Age includes the verified namespace move. |
| 412 | 8 / 36 | [`Aspire.Hosting.Publishing.ContainerImageFormat`](https://github.com/microsoft/aspire/blob/51c8f93ed00b11f8b8afbe979951171cfd8182d3/src/Aspire.Hosting/Publishing/ResourceContainerImageManager.cs#L21-L22) | Newly surfaced by corrected history: experimental since 9.4, not 9.5. Review current shape and dependencies. |
| 412 | 8 / 36 | [`Aspire.Hosting.Publishing.ContainerTargetPlatform`](https://github.com/microsoft/aspire/blob/51c8f93ed00b11f8b8afbe979951171cfd8182d3/src/Aspire.Hosting/Publishing/ResourceContainerImageManager.cs#L55-L57) | Newly surfaced by corrected history: experimental since 9.4, not 9.5. Review current shape and dependencies. |

Preserved prior graduation record (2026-08-04 assessment; pending list superseded above)

The first graduation threshold covers APIs whose listed stable release date is at least one year old as of 2026-08-04.

| Status | API rows | Details |
|---|---:|---|
| Graduated | 11 | Nine `ASPIREINTERACTION001` APIs in #18032; `ConfigureCustomDomain` and `CompletionState` in #19007. |
| Still to graduate | 7 | Blocked on API shape changes or younger experimental dependencies, as detailed below. |

### APIs still to graduate at the one-year threshold

| Diagnostic ID | API | Blocker |
|---|---|---|
| `ASPIRECOSMOSDB001` | `RunAsPreviewEmulator` | The vNext emulator image is GA, but the public API still has stale `Preview` naming and needs a focused API-shape change before graduation. |
| `ASPIRECOSMOSDB001` | `WithDataExplorer` | Graduate with the related emulator API after its public shape is resolved. |
| `ASPIREAZURE001` | `AddAzureEnvironment` | Its signature exposes `AzureEnvironmentResource`, a younger experimental type. |
| `ASPIREAZURE001` | `WithLocation` | Its signature exposes `AzureEnvironmentResource`, a younger experimental type. |
| `ASPIREAZURE001` | `WithResourceGroup` | Its signature exposes `AzureEnvironmentResource`, a younger experimental type. |
| `ASPIREAZURE001` | `AzurePublishingContext` | Its public surface exposes younger experimental Azure environment and pipeline types. |
| `ASPIREPIPELINES001` | `PublishingExtensions` | Its methods expose younger experimental `IReportingStep`, `IReportingTask`, and `MarkdownString` APIs. |

The audit data and API-table comments below are the original inventory snapshot. This progress section is the authoritative status for APIs reviewed under the current one-year threshold.

## Goal and acceptance criteria

Graduate eligible APIs by removing `ExperimentalAttribute` where the shape is stable; otherwise record the required changes, owner, and follow-up blocker.

- Each diagnostic/API family in the table is reviewed.
- APIs that are ready are graduated.
- APIs that are not ready have documented blockers or follow-up issues.
- Any graduation updates include source changes, analyzer suppression cleanup, docs/readme updates where applicable, and API review as needed.

## Table headings and decision order

| Heading | Meaning |
|---|---|
| Release trains | Number of distinct major.minor release lines whose source includes this API experimentally, e.g. 13.4 and 13.5 count as two. Leads because repeated patch releases are not independent API-design iterations. |
| Releases incl. patches | Number of distinct stable versions whose source includes the experimental declaration. Includes its first experimental release. These are **repository release-source counts**, not a claim that every package was republished in each version. |
| First experimental release | Earliest matching stable release with the annotation, linking to that release's source. A later last-blame edit does not reset this date. This measures experimental tenure, not necessarily the API's original non-experimental introduction. |
| Published date | GitHub release publication date in UTC, not tag creation or commit date. |
| API | Fully qualified current declaration, including enclosing type and overload parameter types; links to the pinned current source. |
| Kind | Method/property/etc. A type or assembly is one annotated **scope row**; its unannotated children are not separately counted and may have been added later. |
| Diagnostic | Current experimental diagnostic ID; useful for grouping/suppression, not graduation priority. |
| Git history | Author date and commit of the earliest matching experimental syntax recovered in that file's `git log --follow` history. Useful provenance, **not a guaranteed original commit across arbitrary copies/splits/renames**. Release-source evidence determines the release dates/counts. |
| Latest blame | Author date/commit from current declaration-line `git blame` (attribute line for assembly scopes). It can be a refactor, not introduction. |
| Notes | Scope/conditional-source caveats and explicitly verified identity changes. |

## Methodology and corrections

The inventory is rebuilt from current `src/` C# syntax using Roslyn, not the generated `api/*.cs` baselines. Includes directly annotated publicly accessible types/members, implicit interface members, and assembly attributes. Excludes private/internal APIs and public members of inaccessible containing types. Type/assembly annotation rows represent their scope without expanding every child member.

Each current declaration is matched against **50 stable version source trees**, through 13.5.3; a count requires an experimental annotation in that release's source, not merely commit ancestry. This handles cherry-picked source independently of ancestry. The published `v13.4.4-release` and its same-commit `v13.4.4` alias count once. The historical 8.0.1 tag has no GitHub publication record (date unknown); none of the current rows start there.

Matching uses fully qualified syntax identities and parameter types, ignoring whitespace, nullable annotations, generic parameter names, parameter names/defaults, `this`, and `params`. File-path and diagnostic changes do not reset age. The `PublishingExtensions` namespace move and `PublishAsPackageScript` rename are explicitly linked to verified predecessor identities. **Other renames, signature changes, aliases, or type qualification changes can make ages/counts conservative.** Type-level ages do not imply an unchanged type shape or equally old child members. This is source analysis, not a build of every historical package; conditional project/TFM inclusion is not evaluated. Conditional source is marked in the table.

The May table incorrectly treated last declaration blame as introduction and tag dates as publication dates. Corrected examples: `AzureEnvironmentResource` starts in **9.3**, and `ContainerImageFormat` / `ContainerTargetPlatform` in **9.4**. Consequently this refresh is not simply the old 225 rows plus new releases, and the earlier 'younger AzureEnvironmentResource' blocker needs reassessment.

## Counts by first experimental release

| First experimental release | Current rows |
|---|---:|
| v9.3.0 | 5 |
| v9.4.0 | 3 |
| v9.5.0 | 7 |
| v13.0.0 | 59 |
| v13.1.0 | 43 |
| v13.2.0 | 34 |
| v13.3.0 | 30 |
| v13.4.0 | 17 |
| v13.5.0 | 47 |
| Not found in stable releases | 82 |

## Current API table

The refreshed full inventory is split across the API-table comments below. These replace the May snapshot. Sorted by release trains, then total stable releases, with unreleased/unmatched rows last.

- [API table, part 1](https://github.com/microsoft/aspire/issues/17175#issuecomment-4467792349)
- [API table, part 2](https://github.com/microsoft/aspire/issues/17175#issuecomment-4467792405)
- [API table, part 3](https://github.com/microsoft/aspire/issues/17175#issuecomment-5673802256)
- [API table, part 4](https://github.com/microsoft/aspire/issues/17175#issuecomment-5673802406)
- [API table, part 5](https://github.com/microsoft/aspire/issues/17175#issuecomment-5673802536)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.