[Automated] Update API Surface Area - #17846
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 17846Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 17846" |
|
❓ CLI E2E Tests unknown — 110 passed, 0 failed, 2 unknown (commit View all recordings
📹 Recordings uploaded automatically from CI run #26838658119 |
fe197aa to
ac810bc
Compare
cfe8b79 to
346b8cc
Compare
fe5a901 to
84fffd3
Compare
84fffd3 to
b8f9bdf
Compare
e88df30 to
641f06c
Compare
641f06c to
08720bf
Compare
08720bf to
f6dcb52
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 27 out of 27 changed files in this pull request and generated 7 comments.
Suppressed comments (2)
src/Aspire.Hosting/api/Aspire.Hosting.cs:667
InputsDialogValidationContextis markedAspireExport(ExposeProperties = true)and now exposesServicesasSystem.IServiceProvider. If this type is intended to be part of the ATS/polyglot surface,IServiceProvideris a .NET runtime concept that generally isn’t representable in generated polyglot SDKs. Consider re-addingAspireExportIgnoretoServices(as it previously had), or exposing a polyglot-friendly abstraction/handle instead.
[AspireExport(ExposeProperties = true)]
public sealed partial class InputsDialogValidationContext
{
src/Aspire.Hosting/api/Aspire.Hosting.cs:671
InputsDialogValidationContextis markedAspireExport(ExposeProperties = true)and now exposesServicesasSystem.IServiceProvider. If this type is intended to be part of the ATS/polyglot surface,IServiceProvideris a .NET runtime concept that generally isn’t representable in generated polyglot SDKs. Consider re-addingAspireExportIgnoretoServices(as it previously had), or exposing a polyglot-friendly abstraction/handle instead.
public required System.IServiceProvider Services { get { throw null; } init { } }
| [AspireExport] | ||
| public static ApplicationModel.IResourceBuilder<T> WithDelveServer<T>(this ApplicationModel.IResourceBuilder<T> builder, Go.DelveServerOptions? options = null) | ||
| where T : Go.GoAppResource { throw null; } | ||
|
|
||
| [System.Obsolete("Use WithDelveServer() or WithDelveServer(DelveServerOptions) instead.")] | ||
| [AspireExportIgnore(Reason = "This obsolete compatibility overload is C#-only. Polyglot AppHosts use the DelveServerOptions overload.")] | ||
| public static ApplicationModel.IResourceBuilder<T> WithDelveServer<T>(this ApplicationModel.IResourceBuilder<T> builder, int port = 2345) | ||
| where T : Go.GoAppResource { throw null; } | ||
|
|
||
| [AspireExportIgnore(Reason = "This C# convenience overload uses default options. Polyglot AppHosts use the DelveServerOptions overload.")] | ||
| public static ApplicationModel.IResourceBuilder<T> WithDelveServer<T>(this ApplicationModel.IResourceBuilder<T> builder) | ||
| where T : Go.GoAppResource { throw null; } |
| [AspireExport] | ||
| public sealed partial class HttpsCertificateConfigurationCallbackAnnotationContext | ||
| { | ||
| public required System.Collections.Generic.List<object> Arguments { get { throw null; } init { } } |
| [AspireExport] | ||
| public required ReferenceExpression CertificateWithKeyPath { get { throw null; } init { } } | ||
|
|
||
| public required System.Collections.Generic.Dictionary<string, object> EnvironmentVariables { get { throw null; } init { } } |
| public static ApplicationModel.IResourceBuilder<T> WithDebugSupport<T, TLaunchConfiguration>(this ApplicationModel.IResourceBuilder<T> builder, System.Func<ApplicationModel.LaunchConfigurationCallbackContext, System.Threading.Tasks.Task<TLaunchConfiguration>> launchConfigurationProducer, string launchConfigurationType) | ||
| where T : ApplicationModel.IResource { throw null; } |
|
|
||
| [System.Diagnostics.CodeAnalysis.Experimental("ASPIREEXTENSION001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")] | ||
| [AspireExportIgnore(Reason = "Generic debug launch configuration support is not part of the ATS surface.")] |
| public static ApplicationModel.IResourceBuilder<T> WithDebugSupport<T, TLaunchConfiguration>(this ApplicationModel.IResourceBuilder<T> builder, System.Func<string, System.Threading.CancellationToken, System.Threading.Tasks.Task<TLaunchConfiguration>> launchConfigurationProducer, string launchConfigurationType) | ||
| where T : ApplicationModel.IResource { throw null; } |
| protected override void ClearItems() { } | ||
|
|
||
| protected override void InsertItem(int index, IResourceAnnotation item) { } | ||
|
|
||
| protected override void RemoveItem(int index) { } | ||
|
|
||
| protected override void SetItem(int index, IResourceAnnotation item) { } |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 28 out of 28 changed files in this pull request and generated no new comments.
Suppressed comments (4)
src/Aspire.Hosting/api/Aspire.Hosting.cs:703
- Exposing a server-local
FilePathinInteractionFilecan leak internal filesystem layout and encourages consumers to bypass the safe accessors (OpenRead/ReadAllBytesAsync). Consider removingFilePathfrom the public surface (or making it non-public), and rely onName/Idplus streaming/byte APIs instead.
public sealed partial class InteractionFile
{
internal InteractionFile() { }
public string FilePath { get { throw null; } }
public string Id { get { throw null; } }
public string Name { get { throw null; } }
public System.IO.Stream OpenRead() { throw null; }
public System.Threading.Tasks.Task<byte[]> ReadAllBytesAsync(System.Threading.CancellationToken cancellationToken = default) { throw null; }
}
src/Aspire.Hosting/api/Aspire.Hosting.cs:648
PromptProgressAsyncuses(message, title)ordering, while the other prompt APIs in the same interface consistently use(title, message). This inconsistency makes the API easier to misuse. Recommend aligning the parameter order with the existing pattern (e.g.,PromptProgressAsync(string title, string message, ...), or at least use the same ordering across all prompt methods).
System.Threading.Tasks.Task<InteractionResult<InteractionInputCollection>> PromptInputsAsync(string title, string? message, System.Collections.Generic.IReadOnlyList<InteractionInput> inputs, InputsDialogInteractionOptions? options = null, System.Threading.CancellationToken cancellationToken = default);
System.Threading.Tasks.Task<InteractionResult<bool>> PromptMessageBoxAsync(string title, string message, MessageBoxInteractionOptions? options = null, System.Threading.CancellationToken cancellationToken = default);
System.Threading.Tasks.Task<InteractionResult<bool>> PromptNotificationAsync(string title, string message, NotificationInteractionOptions? options = null, System.Threading.CancellationToken cancellationToken = default);
[System.Diagnostics.CodeAnalysis.Experimental("ASPIREINTERACTION001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")]
System.Threading.Tasks.Task<InteractionResult<bool>> PromptProgressAsync(string message, string? title = null, ProgressInteractionOptions? options = null, System.Threading.CancellationToken cancellationToken = default);
src/Aspire.Hosting/api/Aspire.Hosting.cs:1087
- The exported name
withRequiredCommandValidationdoesn’t match the method nameWithRequiredCommandand may be confusing for consumers (especially in polyglot SDKs). Consider exporting with a name aligned to the API concept (e.g.,withRequiredCommand) and treat validation as an argument rather than the primary name, unless there is a strong reason to diverge.
[System.Diagnostics.CodeAnalysis.Experimental("ASPIRECOMMAND001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")]
[AspireExport("withRequiredCommandValidation", MethodName = "withRequiredCommandValidation")]
public static ApplicationModel.IResourceBuilder<T> WithRequiredCommand<T>(this ApplicationModel.IResourceBuilder<T> builder, string command, System.Func<ApplicationModel.RequiredCommandValidationContext, System.Threading.Tasks.Task<ApplicationModel.RequiredCommandValidationResult>> validationCallback, string? helpLink = null)
where T : ApplicationModel.IResource { throw null; }
src/Aspire.Hosting.Azure/api/Aspire.Hosting.Azure.cs:541
- Nullability is inconsistent for
Subscription: the new constructor requires a non-nullsubscriptionparameter, but theSubscriptionproperty is declared nullable (object?). IfSubscriptionis always provided for that constructor, consider making the property non-nullable (or alternatively, make the constructor parameter nullable) to keep the contract consistent.
public sealed partial class ExistingAzureResourceAnnotation : ApplicationModel.IResourceAnnotation
{
public ExistingAzureResourceAnnotation(object name, object? resourceGroup, object subscription) { }
public ExistingAzureResourceAnnotation(object name, object? resourceGroup = null) { }
public bool IsTenantScope { get { throw null; } }
public object Name { get { throw null; } }
public object? ResourceGroup { get { throw null; } }
public object? Subscription { get { throw null; } }
}
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 28 out of 28 changed files in this pull request and generated 1 comment.
Suppressed comments (2)
src/Aspire.Hosting/api/Aspire.Hosting.cs:671
- InputsDialogValidationContext.Services is now part of the exported surface (the prior export-ignore was removed). Since System.IServiceProvider is a .NET runtime type and is frequently excluded elsewhere in this file for polyglot/ATS compatibility, consider re-adding AspireExportIgnore here (or projecting an ATS-friendly abstraction) to keep the exported contract consistent and avoid exposing a type that non-.NET SDKs typically cannot represent.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2024
- Now that both ServiceProvider (obsolete) and Services exist on an ATS-exported context, it would be clearer to hide the obsolete alias from the ATS surface to prevent duplicate concepts and reduce binding ambiguity in generated polyglot SDKs. Consider adding AspireExportIgnore to ServiceProvider (similar to the approach used on other obsolete aliases in this file) while keeping Services as the single exported entry point.
[System.Obsolete("Use Services instead.")]
public System.IServiceProvider ServiceProvider { get { throw null; } init { } }
[AspireExport]
public required System.IServiceProvider Services { get { throw null; } init { } }
| protected override void ClearItems() { } | ||
|
|
||
| protected override void InsertItem(int index, IResourceAnnotation item) { } | ||
|
|
||
| protected override void RemoveItem(int index) { } | ||
|
|
||
| protected override void SetItem(int index, IResourceAnnotation item) { } |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 28 out of 28 changed files in this pull request and generated 2 comments.
Suppressed comments (9)
src/Aspire.Hosting/api/Aspire.Hosting.cs:2755
- The obsolete
ServiceProvideralias is stillinit-settable and independent ofServices, which can allow inconsistent initialization (two different service providers) even though the intent is an alias. Prefer makingServiceProviderget-only (noinit) and ensuring it always forwards toServicesin the implementation, keeping a single source of truth.
[System.Obsolete("Use Services instead.")]
[AspireExportIgnore(Reason = "Obsolete alias for Services. The service provider is exposed to polyglot hosts via Services (services).")]
public System.IServiceProvider ServiceProvider { get { throw null; } init { } }
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting.Foundry/api/Aspire.Hosting.Foundry.cs:973
- This introduces
ProtocolVersionswhile the previousContainerProtocolVersionsmember was removed. Removing/renaming a public member is a breaking change for .NET consumers. Consider keepingContainerProtocolVersionsas an[Obsolete]alias that forwards toProtocolVersions(and keep[EditorBrowsable(Never)]if you want it hidden), to preserve source/binary compatibility.
[AspireExportIgnore(Reason = "Azure SDK-specific type not usable from polyglot hosts.")]
public System.Collections.Generic.IList<global::Azure.AI.Projects.Agents.ProtocolVersionRecord> ProtocolVersions { get { throw null; } init { } }
src/Aspire.Hosting.Foundry/api/Aspire.Hosting.Foundry.cs:459
- Several public
FoundryModelfields were renamed/removed/replaced (e.g.,ClaudeMythosPreviewrenamed toClaudeMythos5, and other model identifiers removed elsewhere in this file). This is a breaking API change for callers who reference these fields/constants. If the goal is to steer users away from retired model identifiers, keep the old members as[Obsolete]aliases (optionally withEditorBrowsable(Never)) for at least one compatibility window.
[AspireValue("FoundryModels")]
public static readonly FoundryModel ClaudeFable5;
src/Aspire.Hosting.Foundry/api/Aspire.Hosting.Foundry.cs:463
- Several public
FoundryModelfields were renamed/removed/replaced (e.g.,ClaudeMythosPreviewrenamed toClaudeMythos5, and other model identifiers removed elsewhere in this file). This is a breaking API change for callers who reference these fields/constants. If the goal is to steer users away from retired model identifiers, keep the old members as[Obsolete]aliases (optionally withEditorBrowsable(Never)) for at least one compatibility window.
public static readonly FoundryModel ClaudeMythos5;
[AspireValue("FoundryModels")]
public static readonly FoundryModel ClaudeMythosPreview;
src/Aspire.Hosting.Azure/api/Aspire.Hosting.Azure.cs:311
CreateForTenant()implies a scope without a resource group, butResourceGroupremains non-nullable (object). That’s a confusing contract for NRT consumers (and encourages sentinel values or null-in-objectat runtime). Consider makingResourceGroupnullable (object?) whenHasResourceGroupis false, or split the API into mutually exclusive properties (e.g.,ResourceGroup?+Subscription?) that align withIsTenantScope/HasResourceGroup.
public bool HasResourceGroup { get { throw null; } }
public bool IsTenantScope { get { throw null; } }
public object ResourceGroup { get { throw null; } }
src/Aspire.Hosting.Azure/api/Aspire.Hosting.Azure.cs:317
CreateForTenant()implies a scope without a resource group, butResourceGroupremains non-nullable (object). That’s a confusing contract for NRT consumers (and encourages sentinel values or null-in-objectat runtime). Consider makingResourceGroupnullable (object?) whenHasResourceGroupis false, or split the API into mutually exclusive properties (e.g.,ResourceGroup?+Subscription?) that align withIsTenantScope/HasResourceGroup.
public static AzureBicepResourceScope CreateForSubscription(object subscription) { throw null; }
public static AzureBicepResourceScope CreateForTenant() { throw null; }
src/Aspire.Hosting.Azure.AppContainers/api/Aspire.Hosting.Azure.AppContainers.cs:65
- The
Experimental(\"ASPIREACADOMAINS001\")attribute was removed fromConfigureCustomDomain. If this API is still meant to be gated as experimental, the attribute should remain to preserve consistent diagnostics/warnings for consumers. If it’s now stable, consider ensuring other related custom-domain APIs have aligned annotations so the stability contract is consistent.
[AspireExport]
public static void ConfigureCustomDomain(this global::Azure.Provisioning.AppContainers.ContainerApp app, ApplicationModel.IResourceBuilder<ApplicationModel.ParameterResource> customDomain, ApplicationModel.IResourceBuilder<ApplicationModel.ParameterResource> certificateName) { }
src/Aspire.Hosting/api/Aspire.Hosting.cs:4305
- Since
DisplayOrderis an obsolete public field (and fields are harder to version), consider also addingEditorBrowsable(EditorBrowsableState.Never)to reduce accidental use, and prefer reintroducing the replacement as a property as soon as possible. This helps keep IntelliSense clean and reduces the chance that new code takes a dependency on a member slated for change.
[System.Obsolete("DisplayOrder was incorrectly created as a field. It will be re-added as a property in a future Aspire version.")]
public int? DisplayOrder;
src/Aspire.Hosting/api/Aspire.Hosting.cs:4678
- The
Experimental(\"ASPIREPIPELINES001\")attribute was removed fromCompletionState. If pipeline completion state is still part of the experimental pipelines surface, keep the attribute to maintain the intended compatibility/diagnostic signal. If it’s intended to be stable now, consider reviewing nearby pipelines APIs to ensure the experimental/stable boundaries remain consistent.
public enum CompletionState
{
InProgress = 0,
| public required System.Threading.CancellationToken CancellationToken { get { throw null; } init { } } | ||
|
|
||
| public required InteractionInputCollection Inputs { get { throw null; } init { } } | ||
|
|
| @@ -3650,9 +3879,14 @@ public RequiredCommandValidationContext(string resolvedPath, System.IServiceProv | |||
| public string ResolvedPath { get { throw null; } } | |||
|
|
|||
| public System.IServiceProvider Services { get { throw null; } } | |||
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 28 out of 28 changed files in this pull request and generated no new comments.
Suppressed comments (5)
src/Aspire.Hosting/api/Aspire.Hosting.cs:1
Argumentsis non-nullable but not markedrequired(and there’s no visible constructor enforcing initialization), unlike the other context properties. This makes the nullability contract inconsistent and allows consumers to instantiate an invalid object state. Consider makingArgumentsrequired(matching the surrounding pattern), or alternatively make it nullable if it’s legitimately optional.
//------------------------------------------------------------------------------
src/Aspire.Hosting/api/Aspire.Hosting.cs:1
- Same issue as the HTTP command contexts:
Argumentsis non-nullable but notrequired, while most other properties on the context arerequired. To keep the public contract consistent and avoid invalid states, markArgumentsasrequired(or make it nullable if it can be absent).
//------------------------------------------------------------------------------
src/Aspire.Hosting/api/Aspire.Hosting.cs:3613
- Same issue as the HTTP command contexts:
Argumentsis non-nullable but notrequired, while most other properties on the context arerequired. To keep the public contract consistent and avoid invalid states, markArgumentsasrequired(or make it nullable if it can be absent).
[System.Obsolete("Use Services instead.")]
public System.IServiceProvider ServiceProvider { get { throw null; } init { } }
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:3951
- These new overrides have empty bodies, which is inconsistent with the rest of this API stub file (which uses
throw null;to prevent accidental runtime behavior). If these API files are ever compiled into a runtime assembly (or referenced in tests/tools), the empty overrides would silently change behavior. Prefer usingthrow null;stubs here (or ensure these members are only present in reference assemblies where behavior is irrelevant).
protected override void ClearItems() { }
protected override void InsertItem(int index, IResourceAnnotation item) { }
protected override void RemoveItem(int index) { }
protected override void SetItem(int index, IResourceAnnotation item) { }
src/Aspire.Hosting.DevTunnels/api/Aspire.Hosting.DevTunnels.cs:100
UKSouthis inconsistent with typical .NET PascalCase acronym handling and with other region names in this enum (e.g.,EastUs,WestUs2). Consider renaming it toUkSouthfor consistency (or alternatively standardize all acronym casing across the enum if the project has a different convention).
public enum DevTunnelRegion
{
WestEurope = 0,
UKSouth = 1,
NorthEurope = 2,
EastUs = 3,
EastUs2 = 4,
CentralIndia = 5,
WestUs3 = 6,
WestUs2 = 7,
SoutheastAsia = 8,
BrazilSouth = 9,
AustraliaCentral = 10,
AustraliaEast = 11,
JapanEast = 12
}
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 28 out of 28 changed files in this pull request and generated no new comments.
Suppressed comments (5)
src/Aspire.Hosting/api/Aspire.Hosting.cs:1
- Both
HttpCommandRequestContextandHttpCommandResultContextnow haveServicesplus an obsoleteServiceProviderthat remainsinit-settable. This duplicates state and can lead to inconsistent initialization. Prefer makingServiceProvidera get-only alias (noinit) and/or marking it withAspireExportIgnore(similar to other contexts in this file) so the polyglot surface is single-source-of-truth.
//------------------------------------------------------------------------------
src/Aspire.Hosting/api/Aspire.Hosting.cs:2027
- The obsolete
ServiceProvideralias is stillinit-settable and can diverge from the requiredServicesproperty. To keep the contract unambiguous, makeServiceProvidera get-only alias ofServices(noinit), and consider addingAspireExportIgnoretoServiceProviderso polyglot projections only seeServices.
[AspireExport]
public sealed partial class ContainerFileSystemCallbackContext
{
[System.Diagnostics.CodeAnalysis.Experimental("ASPIRECERTIFICATES001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")]
[AspireExportIgnore(Reason = "HttpsCertificateContext is an experimental certificate-specific type that is not yet part of the ATS surface.")]
public ContainerFileSystemCallbackHttpsCertificateContext? HttpsCertificateContext { get { throw null; } set { } }
[AspireExport]
public required IResource Model { get { throw null; } init { } }
[System.Obsolete("Use Services instead.")]
public System.IServiceProvider ServiceProvider { get { throw null; } init { } }
[AspireExport]
public required System.IServiceProvider Services { get { throw null; } init { } }
}
src/Aspire.Hosting/api/Aspire.Hosting.cs:3617
- In
ProcessCommandResultContext, the obsoleteServiceProvideris stillinit-settable alongside requiredServices. As with other contexts, this should be modeled as a read-only alias ofServices(and optionally hidden from ATS viaAspireExportIgnore) to prevent divergent state and reduce API ambiguity.
public required string ResourceName { get { throw null; } init { } }
[System.Obsolete("Use Services instead.")]
public System.IServiceProvider ServiceProvider { get { throw null; } init { } }
public required System.IServiceProvider Services { get { throw null; } init { } }
public required int TotalOutputLineCount { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:444
DistributedApplicationExecutionContextOptionsexposes bothServiceProviderandServicesas independently settable properties, which allows them to get out of sync. Consider makingServiceProvidera get-only alias ofServices(and/or removing its setter) so there is a single authoritative value.
[System.Obsolete("Use Services instead.")]
public System.IServiceProvider? ServiceProvider { get { throw null; } set { } }
public System.IServiceProvider? Services { get { throw null; } set { } }
src/Aspire.Hosting.DevTunnels/api/Aspire.Hosting.DevTunnels.cs:100
- Enum member
UKSouthuses an all-caps country code, while the other members follow standard PascalCase word capitalization (e.g.,EastUs,WestEurope). For consistency, consider renaming toUkSouthor addingUkSouthas an alias (keepingUKSouthfor back-compat if this API is already public).
public enum DevTunnelRegion
{
WestEurope = 0,
UKSouth = 1,
NorthEurope = 2,
EastUs = 3,
EastUs2 = 4,
CentralIndia = 5,
WestUs3 = 6,
WestUs2 = 7,
SoutheastAsia = 8,
BrazilSouth = 9,
AustraliaCentral = 10,
AustraliaEast = 11,
JapanEast = 12
}
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 28 out of 28 changed files in this pull request and generated 1 comment.
Suppressed comments (3)
src/Aspire.Hosting/api/Aspire.Hosting.cs:1
- The
[Experimental(\"ASPIREINTERACTION001\")]attribute was moved offIInteractionService(and other interaction-related types) and is now only applied to the newPromptProgressAsyncmethod. This changes the compile-time/consumer-facing stability contract for the existing interaction APIs (they will no longer be flagged as experimental). If the broader interaction surface is still intended to be experimental, consider keeping the attribute on the interface (or applying it consistently to the related types/members) to avoid unintentionally making the API appear stable.
//------------------------------------------------------------------------------
src/Aspire.Hosting/api/Aspire.Hosting.cs:1231
- This replaces the prior
WithDebugSupport<T, TLaunchConfiguration>(Func<string, TLaunchConfiguration> ..., string launchConfigurationType, Action<CommandLineArgsCallbackContext>? argsCallback = null)signature with new overloads that removeargsCallbackand add a different callback-context type. That is a source-breaking public API change for existing .NET callers. Consider re-introducing the previous overload (optionally marked[Obsolete]if you want to steer callers) or adding a compatibility overload that preservesargsCallbackbehavior so existing callers can upgrade without code changes.
public static ApplicationModel.IResourceBuilder<T> WithDebugSupport<T, TLaunchConfiguration>(this ApplicationModel.IResourceBuilder<T> builder, System.Func<ApplicationModel.LaunchConfigurationCallbackContext, System.Threading.Tasks.Task<TLaunchConfiguration>> launchConfigurationProducer, string launchConfigurationType)
where T : ApplicationModel.IResource { throw null; }
[System.Diagnostics.CodeAnalysis.Experimental("ASPIREEXTENSION001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")]
[AspireExportIgnore(Reason = "Generic debug launch configuration support is not part of the ATS surface.")]
public static ApplicationModel.IResourceBuilder<T> WithDebugSupport<T, TLaunchConfiguration>(this ApplicationModel.IResourceBuilder<T> builder, System.Func<string, TLaunchConfiguration> launchConfigurationProducer, string launchConfigurationType)
where T : ApplicationModel.IResource { throw null; }
[System.Diagnostics.CodeAnalysis.Experimental("ASPIREEXTENSION001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")]
[AspireExportIgnore(Reason = "Generic debug launch configuration support is not part of the ATS surface.")]
public static ApplicationModel.IResourceBuilder<T> WithDebugSupport<T, TLaunchConfiguration>(this ApplicationModel.IResourceBuilder<T> builder, System.Func<string, System.Threading.CancellationToken, System.Threading.Tasks.Task<TLaunchConfiguration>> launchConfigurationProducer, string launchConfigurationType)
where T : ApplicationModel.IResource { throw null; }
src/Aspire.Hosting.Azure.AppContainers/api/Aspire.Hosting.Azure.AppContainers.cs:70
- The
ConfigureCustomDomainmethod previously had an[Experimental(\"ASPIREACADOMAINS001\")]annotation, but it has been removed. If this API is still experimental, the attribute removal changes the public contract and stops producing the expected warnings for consumers. Consider restoring the[Experimental]attribute (or moving it to a containing type) if the API is still meant to be guarded.
public static partial class ContainerAppExtensions
{
[AspireExport]
public static void ConfigureCustomDomain(this global::Azure.Provisioning.AppContainers.ContainerApp app, ApplicationModel.IResourceBuilder<ApplicationModel.ParameterResource> customDomain, ApplicationModel.IResourceBuilder<ApplicationModel.ParameterResource> certificateName) { }
[AspireExportIgnore(Reason = "Polyglot AppHosts use the internal publishAsAzureContainerAppJob dispatcher export.")]
public static ApplicationModel.IResourceBuilder<T> PublishAsAzureContainerAppJob<T>(this ApplicationModel.IResourceBuilder<T> resource, System.Action<Azure.AzureResourceInfrastructure, global::Azure.Provisioning.AppContainers.ContainerAppJob> configure)
| public sealed partial class ResourceAnnotationCollection : System.Collections.ObjectModel.Collection<IResourceAnnotation> | ||
| { | ||
| protected override void ClearItems() { } | ||
|
|
||
| protected override void InsertItem(int index, IResourceAnnotation item) { } | ||
|
|
||
| protected override void RemoveItem(int index) { } | ||
|
|
||
| protected override void SetItem(int index, IResourceAnnotation item) { } | ||
| } |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 29 out of 29 changed files in this pull request and generated no new comments.
Suppressed comments (3)
src/Aspire.Hosting/api/Aspire.Hosting.cs:1089
- The exported name
withRequiredCommandValidationdoesn’t match the method’s primary purpose/name (WithRequiredCommand). This is likely to be confusing in generated polyglot SDKs (it reads like “validation-only”, but also registers the required command). Consider exporting it under a name aligned with the operation (e.g.,withRequiredCommand) and keeping “validation” as a parameter/overload concept rather than the exported symbol name.
[AspireExport("withRequiredCommandValidation", MethodName = "withRequiredCommandValidation")]
public static ApplicationModel.IResourceBuilder<T> WithRequiredCommand<T>(this ApplicationModel.IResourceBuilder<T> builder, string command, System.Func<ApplicationModel.RequiredCommandValidationContext, System.Threading.Tasks.Task<ApplicationModel.RequiredCommandValidationResult>> validationCallback, string? helpLink = null)
src/Aspire.Hosting.Azure/api/Aspire.Hosting.Azure.cs:317
AzureBicepResourceScope.CreateForTenant()implies a valid scope without a resource group, butResourceGroupis typed as non-nullableobject. This creates an API contract mismatch (eitherResourceGroupmust always exist, or it must be nullable for tenant/subscription scopes). Consider changingResourceGrouptoobject?(and documenting when it’s present), or splitting the API into distinct scope types to avoid ambiguous/invalid states.
public bool HasResourceGroup { get { throw null; } }
public bool IsTenantScope { get { throw null; } }
public object ResourceGroup { get { throw null; } }
public object? Subscription { get { throw null; } }
public static AzureBicepResourceScope CreateForSubscription(object subscription) { throw null; }
public static AzureBicepResourceScope CreateForTenant() { throw null; }
src/Aspire.Hosting.Kubernetes/api/Aspire.Hosting.Kubernetes.cs:424
KubernetesPersistentVolumeResourceis exported but does not specifyExposeProperties = true, andParentis not individually annotated for export. If polyglot callers are intended to observe resource relationships (common forIResourceWithParent<T>types), consider either setting[AspireExport(ExposeProperties = true)]on the class or adding an explicit export annotation forParentto ensure it’s visible in generated SDKs.
[System.Diagnostics.CodeAnalysis.Experimental("ASPIRECOMPUTE002", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")]
[AspireExport]
public sealed partial class KubernetesPersistentVolumeResource : ApplicationModel.Resource, ApplicationModel.IResourceWithParent<KubernetesEnvironmentResource>, ApplicationModel.IResourceWithParent, ApplicationModel.IResource
{
public KubernetesPersistentVolumeResource(string name, KubernetesEnvironmentResource environment) : base(default!) { }
public KubernetesEnvironmentResource Parent { get { throw null; } }
}
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 29 out of 29 changed files in this pull request and generated 2 comments.
Suppressed comments (3)
src/Aspire.Hosting/api/Aspire.Hosting.cs:3953
- These
Collection<T>mutation overrides are currently no-ops, which would silently prevent modifications if this type is ever used with these overrides invoked (and differs from the commonthrow null;reference-assembly pattern used throughout these API files). If the intent is to block mutation, these should throwNotSupportedException; if mutation is intended, they should callbase.*. If this is a reference-assembly stub, usethrow null;to match the rest of the file and avoid accidental runtime behavior differences.
protected override void ClearItems() { }
protected override void InsertItem(int index, IResourceAnnotation item) { }
protected override void RemoveItem(int index) { }
protected override void SetItem(int index, IResourceAnnotation item) { }
src/Aspire.Hosting.Go/api/Aspire.Hosting.Go.cs:70
DelveServerOptions.Portis a non-nullableintwith no required/default semantics in the public contract, so callers constructing options will naturally end up with0unless they remember to set it. If the intent is a conventional default (e.g., 2345), consider makingPortnullable (treat null as default), marking itrequired, or ensuring the implementation enforces a non-zero default so0doesn’t unintentionally become the effective port.
[AspireDto]
public sealed partial class DelveServerOptions
{
public bool AcceptMultiClient { get { throw null; } init { } }
public bool ContinueOnStart { get { throw null; } init { } }
public bool Log { get { throw null; } init { } }
public string? LogOutput { get { throw null; } init { } }
public bool? OnlySameUser { get { throw null; } init { } }
public int Port { get { throw null; } init { } }
}
src/Aspire.Hosting/api/Aspire.Hosting.cs:703
InteractionFileis a new public type that looks like it belongs to the same interaction feature area that still usesASPIREINTERACTION001experimental annotations on some members/types in this file. Consider annotatingInteractionFileconsistently (or documenting why it’s intentionally non-experimental) so consumers get consistent compile-time guidance about API stability.
public sealed partial class InteractionFile
{
internal InteractionFile() { }
public string FilePath { get { throw null; } }
public string Id { get { throw null; } }
public string Name { get { throw null; } }
public System.IO.Stream OpenRead() { throw null; }
public System.Threading.Tasks.Task<byte[]> ReadAllBytesAsync(System.Threading.CancellationToken cancellationToken = default) { throw null; }
}
| [System.Diagnostics.CodeAnalysis.Experimental("ASPIREEXTENSION001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")] | ||
| [AspireExportIgnore(Reason = "Generic debug launch configuration support is not part of the ATS surface.")] | ||
| public static ApplicationModel.IResourceBuilder<T> WithDebugSupport<T, TLaunchConfiguration>(this ApplicationModel.IResourceBuilder<T> builder, System.Func<string, TLaunchConfiguration> launchConfigurationProducer, string launchConfigurationType) | ||
| where T : ApplicationModel.IResource { throw null; } | ||
|
|
||
| [System.Diagnostics.CodeAnalysis.Experimental("ASPIREEXTENSION001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")] | ||
| [AspireExportIgnore(Reason = "Generic debug launch configuration support is not part of the ATS surface.")] | ||
| public static ApplicationModel.IResourceBuilder<T> WithDebugSupport<T, TLaunchConfiguration>(this ApplicationModel.IResourceBuilder<T> builder, System.Func<string, System.Threading.CancellationToken, System.Threading.Tasks.Task<TLaunchConfiguration>> launchConfigurationProducer, string launchConfigurationType) | ||
| where T : ApplicationModel.IResource { throw null; } | ||
|
|
|
|
||
| [AspireExportIgnore(Reason = "Azure SDK-specific type not usable from polyglot hosts.")] |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 31 out of 31 changed files in this pull request and generated 1 comment.
Suppressed comments (3)
src/Aspire.Hosting.Azure.AppContainers/api/Aspire.Hosting.Azure.AppContainers.cs:65
- The
ConfigureCustomDomainAPI appears to have lost its[Experimental(\"ASPIREACADOMAINS001\", ...)]annotation (it was present before per the removed line). If this API is still experimental, please restore theExperimentalattribute to preserve the intended diagnostics/stability contract; if it is meant to be stable now, consider adding a PR note/changelog entry since this changes the public API’s stability signal.
[AspireExport]
public static void ConfigureCustomDomain(this global::Azure.Provisioning.AppContainers.ContainerApp app, ApplicationModel.IResourceBuilder<ApplicationModel.ParameterResource> customDomain, ApplicationModel.IResourceBuilder<ApplicationModel.ParameterResource> certificateName) { }
src/Aspire.Hosting.Go/api/Aspire.Hosting.Go.cs:22
- The parameterless
WithDelveServer()overload is redundant because theWithDelveServer(DelveServerOptions? options = null)overload already supports the same call-site (builder.WithDelveServer()). Keeping both increases API surface area and documentation burden. Consider removing the parameterless overload (preferred), or alternatively remove the default value on the options parameter if you want the parameterless overload to be the single ‘default options’ entry point.
public static ApplicationModel.IResourceBuilder<T> WithDelveServer<T>(this ApplicationModel.IResourceBuilder<T> builder, Go.DelveServerOptions? options = null)
where T : Go.GoAppResource { throw null; }
src/Aspire.Hosting.Go/api/Aspire.Hosting.Go.cs:32
- The parameterless
WithDelveServer()overload is redundant because theWithDelveServer(DelveServerOptions? options = null)overload already supports the same call-site (builder.WithDelveServer()). Keeping both increases API surface area and documentation burden. Consider removing the parameterless overload (preferred), or alternatively remove the default value on the options parameter if you want the parameterless overload to be the single ‘default options’ entry point.
[AspireExportIgnore(Reason = "This C# convenience overload uses default options. Polyglot AppHosts use the DelveServerOptions overload.")]
public static ApplicationModel.IResourceBuilder<T> WithDelveServer<T>(this ApplicationModel.IResourceBuilder<T> builder)
where T : Go.GoAppResource { throw null; }
| @@ -1175,7 +1219,17 @@ public static ApplicationModel.IResourceBuilder<T> WithContainerFilesSource<T>(t | |||
|
|
|||
| [System.Diagnostics.CodeAnalysis.Experimental("ASPIREEXTENSION001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")] | |||
| [AspireExportIgnore(Reason = "Generic debug launch configuration support is not part of the ATS surface.")] | |||
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 31 out of 31 changed files in this pull request and generated 1 comment.
Suppressed comments (3)
src/Aspire.Hosting.Foundry/api/Aspire.Hosting.Foundry.cs:503
CohereCommandAPlus052026appears to be missing an[AspireValue(\"FoundryModels\")]attribute (it’s present on surrounding model fields). If tooling relies onAspireValueto project these values into catalogs/exports, this entry will be silently omitted. Add the attribute to keep behavior consistent with other Foundry model constants.
[AspireValue("FoundryModels")]
public static readonly FoundryModel CohereCommandA;
[AspireValue("FoundryModels")]
public static readonly FoundryModel CohereCommandAPlus052026;
[AspireValue("FoundryModels")]
public static readonly FoundryModel CohereEmbedV3English;
src/Aspire.Hosting.Foundry/api/Aspire.Hosting.Foundry.cs:973
- This PR replaces/renames the hosted-agent protocol versions property (previously
ContainerProtocolVersions) withProtocolVersions. IfContainerProtocolVersionswas publicly released, removing it is a breaking change for consumers. Consider keepingContainerProtocolVersionsas an[Obsolete]alias that forwards toProtocolVersionsfor at least one release to preserve compatibility.
[AspireExportIgnore(Reason = "Azure SDK-specific type not usable from polyglot hosts.")]
public System.Collections.Generic.IList<global::Azure.AI.Projects.Agents.ProtocolVersionRecord> ProtocolVersions { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:4359
- The
DebuggerDisplaylabelRequiredExtensionIddoesn’t match the exposed property nameLaunchConfigurationType, which can be confusing during debugging. Update the display string to use a label aligned with the actual API surface (e.g.,LaunchConfigurationType = ...).
[System.Diagnostics.DebuggerDisplay("Type = {GetType().Name,nq}, RequiredExtensionId = {LaunchConfigurationType,nq}")]
[System.Diagnostics.CodeAnalysis.Experimental("ASPIREEXTENSION001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")]
public sealed partial class SupportsDebuggingAnnotation : IResourceAnnotation
{
internal SupportsDebuggingAnnotation() { }
public string LaunchConfigurationType { get { throw null; } }
}
| public partial interface ILanguageSupport | ||
| { | ||
| string? CertificateBundleEnvironmentVariable { get; } | ||
|
|
||
| string Language { get; } | ||
|
|
||
| DetectionResult Detect(string directoryPath); |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 31 out of 31 changed files in this pull request and generated no new comments.
Suppressed comments (4)
src/Aspire.Hosting.Go/api/Aspire.Hosting.Go.cs:21
- The options overload has a default value while a separate parameterless overload is also present. This creates two APIs for the same zero-argument call shape and makes the overload set harder to evolve. Remove
= nullfrom the options overload (or remove the parameterless overload) before this surface ships.
public static ApplicationModel.IResourceBuilder<T> WithDelveServer<T>(this ApplicationModel.IResourceBuilder<T> builder, Go.DelveServerOptions? options = null)
src/Aspire.Hosting/api/Aspire.Hosting.cs:742
- This property is being introduced as obsolete in the same release as its replacement. Since no released API compatibility requires it, shipping both permanently expands the surface and burdens callers with an API they should never use. Remove
Filesand expose onlyGetFiles().
[System.Obsolete("Use GetFiles() and dispose the returned collection when the files are no longer needed.")]
[AspireExportIgnore(Reason = "InteractionFile contains non-serializable methods and server-local paths; polyglot callers use InteractionInputFile from base.mts.")]
public System.Collections.Generic.IReadOnlyList<InteractionFile>? Files { get { throw null; } }
src/Aspire.Hosting.DevTunnels/api/Aspire.Hosting.DevTunnels.cs:91
USis a two-letter acronym and should retain both capitals under .NET naming guidelines, consistent withUKSouthin this enum. Rename these members toEastUSandEastUS2before the names become a compatibility commitment.
EastUs = 3,
EastUs2 = 4,
src/Aspire.Hosting.DevTunnels/api/Aspire.Hosting.DevTunnels.cs:94
USis a two-letter acronym and should retain both capitals under .NET naming guidelines, consistent withUKSouthin this enum. Rename these members toWestUS3andWestUS2before the names become a compatibility commitment.
WestUs3 = 6,
WestUs2 = 7,
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 31 out of 31 changed files in this pull request and generated no new comments.
Suppressed comments (6)
src/Aspire.Hosting/api/Aspire.Hosting.cs:648
- This makes the now-stable
IInteractionServicerequire an experimental abstract member. Consumers cannot implement the stable interface without implementing and referencingASPIREINTERACTION001, and later changes to that experimental contract would break stable implementations. Keep the interface experimental until this member stabilizes, provide a default implementation, or move progress support to a separate experimental interface.
[System.Diagnostics.CodeAnalysis.Experimental("ASPIREINTERACTION001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")]
System.Threading.Tasks.Task<InteractionResult<bool>> PromptProgressAsync(string message, ProgressInteractionOptions? options = null, System.Threading.CancellationToken cancellationToken = default);
src/Aspire.Hosting/api/Aspire.Hosting.cs:2046
- Replacing the previously required
ServiceProviderwith requiredServicesis source-breaking. Even though the obsolete alias forwards its init setter, C# required-member analysis does not recognize that assignment, so existing object initializers that setServiceProvidernow fail with CS9035. Preserve an initialization path that accepts the old member during the compatibility window.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2781
- Replacing the previously required
ServiceProviderwith requiredServicesis source-breaking. The alias setter forwards at runtime, but required-member analysis still rejects existingnew ExecuteCommandContext { ServiceProvider = ... }initializers with CS9035. Preserve source compatibility for the old initializer while deprecating it.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2935
- Making
Servicesrequired while removingrequiredfrom the obsolete alias breaks existingHttpCommandRequestContextobject initializers. AssigningServiceProviderdoes setServicesat runtime, but it does not satisfy C# required-member analysis, so recompilation fails with CS9035. Keep the old initialization shape source-compatible during deprecation.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2955
- Making
Servicesrequired while removingrequiredfrom the obsolete alias breaks existingHttpCommandResultContextobject initializers. The forwarding setter cannot satisfy C# required-member analysis, so code that still initializesServiceProviderfails with CS9035 instead of receiving only an obsolete warning. Preserve the old initialization path for the compatibility window.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:4401
- The required-member rename is source-breaking for callers constructing
UpdateCommandStateContext. Existing initializers that set the obsoleteServiceProvideralias do initializeServicesat runtime, but the compiler still reports CS9035 because onlyServicesis marked required. Preserve compatibility with the old initializer while migrating consumers.
public required System.IServiceProvider Services { get { throw null; } init { } }
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 31 out of 31 changed files in this pull request and generated 2 comments.
Suppressed comments (5)
src/Aspire.Hosting/api/Aspire.Hosting.cs:648
IInteractionServiceis being made stable while this newly added abstract member remains experimental. Existing implementations stop compiling, and new implementations of the stable interface must opt intoASPIREINTERACTION001. Give this member a default interface implementation or move it to a separate experimental interface; otherwise the interface itself needs to remain experimental.
System.Threading.Tasks.Task<InteractionResult<bool>> PromptProgressAsync(string message, ProgressInteractionOptions? options = null, System.Threading.CancellationToken cancellationToken = default);
src/Aspire.Hosting/api/Aspire.Hosting.cs:2781
- Making
Servicesrequired breaks source compatibility for existingExecuteCommandContextinitializers that set the previously requiredServiceProvider; the alias setter does not satisfy the compiler's required-member check. Keep the replacement non-required during the obsolete transition or add a compatible construction path.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2935
- Making
Servicesrequired breaks source compatibility for existingHttpCommandRequestContextinitializers that setServiceProvider; assigning that forwarding alias does not satisfy C# required-member analysis. KeepServicesnon-required during the obsolete transition or provide a compatible constructor.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2955
- Making
Servicesrequired breaks source compatibility for existingHttpCommandResultContextinitializers that setServiceProvider; assigning that forwarding alias does not satisfy C# required-member analysis. KeepServicesnon-required during the obsolete transition or provide a compatible constructor.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:4401
- Making
Servicesrequired breaks source compatibility for existingUpdateCommandStateContextinitializers that set the previously requiredServiceProvider; the alias setter does not satisfy the compiler's required-member check. Keep the replacement non-required during the obsolete transition or add a compatible construction path.
public required System.IServiceProvider Services { get { throw null; } init { } }
| public System.IServiceProvider ServiceProvider { get { throw null; } init { } } | ||
|
|
||
| [AspireExport] | ||
| public required System.IServiceProvider Services { get { throw null; } init { } } |
| public static ApplicationModel.IResourceBuilder<AzureCosmosDBResource> AddDatabase(this ApplicationModel.IResourceBuilder<AzureCosmosDBResource> builder, string databaseName) { throw null; } | ||
|
|
||
| [AspireExport(RunSyncOnBackgroundThread = true)] | ||
| public static ApplicationModel.IResourceBuilder<AzureCosmosDBResource> RunAsClassicEmulator(this ApplicationModel.IResourceBuilder<AzureCosmosDBResource> builder, System.Action<ApplicationModel.IResourceBuilder<Azure.AzureCosmosDBEmulatorResource>>? configureContainer = null) { throw null; } |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 31 out of 31 changed files in this pull request and generated 2 comments.
Suppressed comments (5)
src/Aspire.Hosting/api/Aspire.Hosting.cs:648
IInteractionServiceis being stabilized, but this abstract member depends on experimental types. Any external implementation of the otherwise stable interface must now implementPromptProgressAsyncand opt intoASPIREINTERACTION001. Keep the experimental contract off the stable interface (for example, use a separate interface), or provide a default interface implementation so implementers are not forced to adopt it.
[System.Diagnostics.CodeAnalysis.Experimental("ASPIREINTERACTION001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")]
System.Threading.Tasks.Task<InteractionResult<bool>> PromptProgressAsync(string message, ProgressInteractionOptions? options = null, System.Threading.CancellationToken cancellationToken = default);
src/Aspire.Hosting/api/Aspire.Hosting.cs:2046
- Making
Servicesrequired while removingrequiredfrom the obsoleteServiceProvideralias is source-breaking. Existing object initializers that set onlyServiceProvidernow fail with CS9035 because the compiler cannot infer that its init accessor assignsServices. Preserve compatibility by allowing either spelling to initialize one validated backing value instead of requiring only the new property.
[System.Obsolete("Use Services instead.")]
public System.IServiceProvider ServiceProvider { get { throw null; } init { } }
[AspireExport]
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2935
- Making
Servicesrequired while removingrequiredfrom the obsoleteServiceProvideralias is source-breaking. ExistingHttpCommandRequestContextinitializers that use the old property now fail with CS9035. Preserve compatibility by allowing either property to initialize the same validated backing value.
[System.Obsolete("Use Services instead.")]
public System.IServiceProvider ServiceProvider { get { throw null; } init { } }
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2955
- Making
Servicesrequired while removingrequiredfrom the obsoleteServiceProvideralias is source-breaking. ExistingHttpCommandResultContextinitializers that use the old property now fail with CS9035. Preserve compatibility by allowing either property to initialize the same validated backing value.
[System.Obsolete("Use Services instead.")]
public System.IServiceProvider ServiceProvider { get { throw null; } init { } }
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:4401
- Making
Servicesrequired while removingrequiredfrom the obsoleteServiceProvideralias is source-breaking. ExistingUpdateCommandStateContextinitializers that set onlyServiceProvidernow fail with CS9035. Preserve compatibility by allowing either property to initialize the same validated backing value.
[System.Obsolete("Use Services instead.")]
[AspireExportIgnore(Reason = "Obsolete alias for Services. The service provider is exposed to polyglot hosts via Services (services).")]
public System.IServiceProvider ServiceProvider { get { throw null; } init { } }
public required System.IServiceProvider Services { get { throw null; } init { } }
| [System.Obsolete("Use GetFiles() and dispose the returned collection when the files are no longer needed.")] | ||
| [AspireExportIgnore(Reason = "InteractionFile contains non-serializable methods and server-local paths; polyglot callers use InteractionInputFile from base.mts.")] | ||
| public System.Collections.Generic.IReadOnlyList<InteractionFile>? Files { get { throw null; } } |
| [System.Obsolete("Use Services instead.")] | ||
| [AspireExportIgnore(Reason = "Obsolete alias for Services. The service provider is exposed to polyglot hosts via Services (services).")] | ||
| public System.IServiceProvider ServiceProvider { get { throw null; } init { } } | ||
|
|
||
| public required System.IServiceProvider Services { get { throw null; } init { } } |
This comment has been minimized.
This comment has been minimized.
|
|
||
| namespace Aspire.Hosting.Radius.CloudProviders | ||
| { | ||
| public partial interface IAwsRadiusProviderBuilder |
| IAwsRadiusProviderBuilder WithIrsa(string iamRoleArn); | ||
| } | ||
|
|
||
| public partial interface IAzureRadiusProviderBuilder |
| { | ||
| [System.Diagnostics.CodeAnalysis.Experimental("ASPIREDOTNETPROJECT001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")] | ||
| [AspireExport(ExposeProperties = true)] | ||
| public partial class DotnetProjectResource : ApplicationModel.ExecutableResource, IResourceWithServiceDiscovery, ApplicationModel.IResourceWithEndpoints, ApplicationModel.IResource |
|
|
||
| public sealed partial class ExistingAzureResourceAnnotation : ApplicationModel.IResourceAnnotation | ||
| { | ||
| public ExistingAzureResourceAnnotation(object name, object? resourceGroup, object subscription) { } |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 31 out of 31 changed files in this pull request and generated 1 comment.
Suppressed comments (6)
src/Aspire.Hosting/api/Aspire.Hosting.cs:742
- This member is new relative to the released surface but is already obsolete, so shipping it permanently reserves an API that no released consumer needs. Remove
Filesbefore the baseline ships and expose only the ownership-safeGetFiles()API.
[System.Obsolete("Use GetFiles() and dispose the returned collection when the files are no longer needed.")]
[AspireExportIgnore(Reason = "InteractionFile contains non-serializable methods and server-local paths; polyglot callers use InteractionInputFile from base.mts.")]
public System.Collections.Generic.IReadOnlyList<InteractionFile>? Files { get { throw null; } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2046
- Making
Servicesrequired breaks existing object initializers that set the formerly requiredServiceProvidermember. The alias init accessor assignsServicesat runtime, but that does not satisfy C# required-member analysis, so those callers now fail with CS9035. Keep the replacement non-required (or provide an equivalent compatibility construction path) while the obsolete alias is supported.
[AspireExport]
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2781
- Making
Servicesrequired breaks existingExecuteCommandContextinitializers that set the formerly requiredServiceProvidermember. Assigning the obsolete alias does not satisfy C# required-member analysis, so source-compatible callers fail with CS9035. Keep the replacement non-required (or provide an equivalent compatibility construction path) during the rename.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2935
- Making
Servicesrequired breaks existingHttpCommandRequestContextinitializers that set the formerly requiredServiceProvidermember. The alias setter does not count toward C# required-member initialization, so those callers fail with CS9035. Keep the new alias non-required (or provide an equivalent compatibility construction path).
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2955
- Making
Servicesrequired breaks existingHttpCommandResultContextinitializers that set the formerly requiredServiceProvidermember. The obsolete alias forwards at runtime but does not satisfy C# required-member analysis, causing CS9035. Keep the new alias non-required (or provide an equivalent compatibility construction path).
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:4402
- Making
Servicesrequired breaks existingUpdateCommandStateContextinitializers that set the formerly requiredServiceProvidermember. The alias init accessor does not satisfy C# required-member analysis, so callers fail with CS9035 despite the compatibility alias. KeepServicesnon-required (or provide an equivalent compatibility construction path) during the rename.
public required System.IServiceProvider Services { get { throw null; } init { } }
| [System.Diagnostics.CodeAnalysis.Experimental("ASPIREINTERACTION001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")] | ||
| System.Threading.Tasks.Task<InteractionResult<bool>> PromptProgressAsync(string message, ProgressInteractionOptions? options = null, System.Threading.CancellationToken cancellationToken = default); |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 31 out of 31 changed files in this pull request and generated 1 comment.
Suppressed comments (5)
src/Aspire.Hosting/api/Aspire.Hosting.cs:2046
- Making
Servicesa new required member defeats theServiceProvidercompatibility alias. Existing object initializers that set every previously required member, includingServiceProvider, now fail with CS9035 because the compiler does not infer that the alias initializer assignsServices. Keep the new canonical property non-required (with both properties sharing storage) so existing callers remain source-compatible, then regenerate this API baseline.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2781
- Making
Servicesa new required member defeats theServiceProvidercompatibility alias. Existing object initializers that set every previously required member, includingServiceProvider, now fail with CS9035 because assigning the alias does not satisfy the compiler's required-member check. KeepServicesnon-required while sharing storage with the obsolete alias, then regenerate the API baseline.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2935
- Making
Servicesa new required member defeats theServiceProvidercompatibility alias. ExistingHttpCommandRequestContextinitializers that set the formerly requiredServiceProvidernow fail with CS9035 because the compiler does not treat that alias assignment as satisfyingServices. Make the canonical property non-required and share its backing storage with the alias before regenerating this file.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2955
- Making
Servicesa new required member defeats theServiceProvidercompatibility alias. ExistingHttpCommandResultContextinitializers that set the formerly requiredServiceProvidernow fail with CS9035 because the compiler does not treat that alias assignment as satisfyingServices. Make the canonical property non-required and share its backing storage with the alias before regenerating this file.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:4402
- Making
Servicesa new required member defeats theServiceProvidercompatibility alias. ExistingUpdateCommandStateContextinitializers that set the formerly requiredServiceProvidernow fail with CS9035 because the compiler does not treat that alias assignment as satisfyingServices. Make the canonical property non-required and share its backing storage with the alias before regenerating this file.
public required System.IServiceProvider Services { get { throw null; } init { } }
| EastUs = 3, | ||
| EastUs2 = 4, | ||
| CentralIndia = 5, | ||
| WestUs3 = 6, | ||
| WestUs2 = 7, |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 32 out of 32 changed files in this pull request and generated no new comments.
Suppressed comments (6)
src/Aspire.Hosting/api/Aspire.Hosting.cs:2046
- Adding
Servicesas a new required member does not preserve source compatibility for theServiceProviderrename. Existing callers that initialize the previously requiredServiceProviderproperty will now get CS9035 because the compiler cannot infer that its init accessor assignsServices. KeepServicesnon-required for the deprecation window (using the shared backing value), then regenerate this API baseline.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2781
- Adding
Servicesas a new required member breaks existingExecuteCommandContextobject initializers that set the previously requiredServiceProvider: the compiler does not treat the alias init accessor as satisfyingServices, so those callers now fail with CS9035. Keep the replacement property non-required during the obsolete alias's compatibility window, then regenerate this API baseline.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2955
- This new required
Servicesmember makes existingHttpCommandResultContextinitializers that setServiceProviderfail with CS9035; the alias initializer is not recognized as satisfying another required member. KeepServicesnon-required for the compatibility period and regenerate this baseline from the corrected source.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:4402
- Adding required
Servicesbreaks source compatibility for callers that constructUpdateCommandStateContextwith the formerly requiredServiceProvider; assigning the obsolete alias does not satisfy this required member at compile time. Keep the new alias target non-required until the old property is removed, then regenerate the API file.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2935
- This new required
Servicesmember makes existingHttpCommandRequestContextinitializers that setServiceProviderfail with CS9035; C# required-member analysis does not follow the alias property's init accessor. KeepServicesnon-required until the obsolete alias can be removed, then regenerate the API baseline.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:648
IInteractionServiceis being promoted out of experimental status, but this experimental member remains abstract. Every implementation of the now-stable interface must therefore implement an API that is explicitly allowed to change or disappear, so future iteration onPromptProgressAsyncwould break stable implementers. Move progress support to an experimental sub-interface or provide a compatible default interface implementation before stabilizingIInteractionService.
[System.Diagnostics.CodeAnalysis.Experimental("ASPIREINTERACTION001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")]
System.Threading.Tasks.Task<InteractionResult<bool>> PromptProgressAsync(string message, ProgressInteractionOptions? options = null, System.Threading.CancellationToken cancellationToken = default);
Tests selector53 / 99 PR test projects · 4 PR jobs · 2 advisory-only targets, from 32 changed files. Selected PR test projects (53 / 99)
Selected PR jobs (4)
Advisory workflow impact (2)
How these were chosen — grouped by what changed
🔧 show 17
🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 📦 affected project 📦 affected project 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 🔧 Job reasons
Selection computed for commit |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 32 out of 32 changed files in this pull request and generated no new comments.
Suppressed comments (6)
src/Aspire.Hosting/api/Aspire.Hosting.cs:648
IInteractionServiceis now stable, but this new abstract member requires the experimentalProgressInteractionOptionsAPI. Existing implementations must add this member and opt into/suppressASPIREINTERACTION001just to implement the stable interface. Move progress support to a separate experimental interface or provide a default interface implementation before stabilizingIInteractionService.
System.Threading.Tasks.Task<InteractionResult<bool>> PromptProgressAsync(string message, ProgressInteractionOptions? options = null, System.Threading.CancellationToken cancellationToken = default);
src/Aspire.Hosting/api/Aspire.Hosting.cs:2053
- Making
Servicesrequired while changingServiceProviderinto a non-required alias breaks existing object initializers: assigningServiceProviderdoes not satisfy C#'s required-member check forServices, so callers receive CS9035 despite following the obsolete migration path. Preserve compatibility by keeping the new alias non-required, or defer this required-member rename to a breaking release.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2788
- Making
Servicesrequired while changingServiceProviderinto a non-required alias breaks existing object initializers: assigningServiceProviderdoes not satisfy C#'s required-member check forServices, so callers receive CS9035 despite following the obsolete migration path. Preserve compatibility by keeping the new alias non-required, or defer this required-member rename to a breaking release.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2962
- Making
Servicesrequired while changingServiceProviderinto a non-required alias breaks existing object initializers: assigningServiceProviderdoes not satisfy C#'s required-member check forServices, so callers receive CS9035 despite following the obsolete migration path. Preserve compatibility by keeping the new alias non-required, or defer this required-member rename to a breaking release.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:4413
- Making
Servicesrequired while changingServiceProviderinto a non-required alias breaks existing object initializers: assigningServiceProviderdoes not satisfy C#'s required-member check forServices, so callers receive CS9035 despite following the obsolete migration path. Preserve compatibility by keeping the new alias non-required, or defer this required-member rename to a breaking release.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2942
- Making
Servicesrequired while changingServiceProviderinto a non-required alias breaks existing object initializers: assigningServiceProviderdoes not satisfy C#'s required-member check forServices, so callers receive CS9035 despite following the obsolete migration path. Preserve compatibility by keeping the new alias non-required, or defer this required-member rename to a breaking release.
public required System.IServiceProvider Services { get { throw null; } init { } }
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 32 out of 32 changed files in this pull request and generated no new comments.
Suppressed comments (1)
src/Aspire.Hosting/api/Aspire.Hosting.cs:742
Filesis being added to the shipped baseline already obsolete. Since it is absent from the previous release surface, retaining it creates a permanent compatibility obligation without providing a migration need. Remove this property from the source before regenerating the baseline and ship onlyGetFiles().
[System.Obsolete("Use GetFiles() and dispose the returned collection when the files are no longer needed.")]
[AspireExportIgnore(Reason = "InteractionFile contains non-serializable methods and server-local paths; polyglot callers use InteractionInputFile from base.mts.")]
public System.Collections.Generic.IReadOnlyList<InteractionFile>? Files { get { throw null; } }
There was a problem hiding this comment.
🔵 Needs a closer look
The baseline captures source-breaking required-member renames, a stable interface tied to an experimental member, and a silent Cosmos emulator behavior change.
Review details
Suppressed comments (7)
src/Aspire.Hosting/api/Aspire.Hosting.cs:2053
- Replacing the required
ServiceProviderinitializer with a new requiredServicesmember is source-breaking: existing object initializers that set the obsolete alias still fail required-member analysis because the compiler does not treat that assignment as settingServices. Keep existing initializers valid, for example by making the new alias non-required or providing a compatibility construction path that satisfies the required-member contract.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2788
- Replacing the required
ServiceProviderinitializer with a new requiredServicesmember is source-breaking: existing object initializers that set the obsolete alias still fail required-member analysis because the compiler does not treat that assignment as settingServices. Keep existing initializers valid, for example by making the new alias non-required or providing a compatibility construction path that satisfies the required-member contract.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2942
- Replacing the required
ServiceProviderinitializer with a new requiredServicesmember is source-breaking: existing object initializers that set the obsolete alias still fail required-member analysis because the compiler does not treat that assignment as settingServices. Keep existing initializers valid, for example by making the new alias non-required or providing a compatibility construction path that satisfies the required-member contract.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:2962
- Replacing the required
ServiceProviderinitializer with a new requiredServicesmember is source-breaking: existing object initializers that set the obsolete alias still fail required-member analysis because the compiler does not treat that assignment as settingServices. Keep existing initializers valid, for example by making the new alias non-required or providing a compatibility construction path that satisfies the required-member contract.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:4413
- Replacing the required
ServiceProviderinitializer with a new requiredServicesmember is source-breaking: existing object initializers that set the obsolete alias still fail required-member analysis because the compiler does not treat that assignment as settingServices. Keep existing initializers valid, for example by making the new alias non-required or providing a compatibility construction path that satisfies the required-member contract.
public required System.IServiceProvider Services { get { throw null; } init { } }
src/Aspire.Hosting/api/Aspire.Hosting.cs:648
- Graduating
IInteractionServicewhile adding this abstract experimental member makes the stable interface require implementers to depend on an experimental contract, and future changes to progress interactions would break stable third-party implementations. Keep the interface experimental until this member stabilizes, move progress support to a separate experimental capability interface, or provide a compatibility-safe default implementation.
[System.Diagnostics.CodeAnalysis.Experimental("ASPIREINTERACTION001", UrlFormat = "https://aka.ms/aspire/diagnostics/{0}")]
System.Threading.Tasks.Task<InteractionResult<bool>> PromptProgressAsync(string message, ProgressInteractionOptions? options = null, System.Threading.CancellationToken cancellationToken = default);
src/Aspire.Hosting.Azure.CosmosDB/api/Aspire.Hosting.Azure.CosmosDB.cs:68
- This new escape hatch does not preserve behavior for existing callers: the stable
RunAsEmulatorAPI now silently selects the Linux/vNext emulator instead of the classic emulator. Preserve the establishedRunAsEmulatorsemantics and expose the new emulator under a distinct API, or explicitly approve and document this as a breaking migration before accepting the release baseline.
[AspireExport(RunSyncOnBackgroundThread = true)]
public static ApplicationModel.IResourceBuilder<AzureCosmosDBResource> RunAsClassicEmulator(this ApplicationModel.IResourceBuilder<AzureCosmosDBResource> builder, System.Action<ApplicationModel.IResourceBuilder<Azure.AzureCosmosDBEmulatorResource>>? configureContainer = null) { throw null; }
- Files reviewed: 32/32 changed files
- Comments generated: 0 new
- Review effort level: Balanced
There was a problem hiding this comment.
🟡 Changes recommended
Stable API changes introduce source-compatibility and contract-design issues that should be resolved before release.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (6)
src/Aspire.Hosting/api/Aspire.Hosting.cs:648
IInteractionServiceis now stable, but every implementation must implement this experimental member and opt intoASPIREINTERACTION001. Keep the interface experimental until all required members are stable, or move this operation behind an experimental derived interface/default implementation.
src/Aspire.Hosting/api/Aspire.Hosting.cs:2057- The obsolete alias does not preserve source compatibility: an existing initializer that assigns
ServiceProviderno longer satisfies the newly requiredServicesmember and fails with CS9035. Provide a construction pattern where either alias initializes the shared value before regenerating the API.
src/Aspire.Hosting/api/Aspire.Hosting.cs:2792 - The obsolete alias does not preserve source compatibility: an existing initializer that assigns
ServiceProviderno longer satisfies the newly requiredServicesmember and fails with CS9035. Provide a construction pattern where either alias initializes the shared value before regenerating the API.
src/Aspire.Hosting/api/Aspire.Hosting.cs:2946 - The obsolete alias does not preserve source compatibility: an existing initializer that assigns
ServiceProviderno longer satisfies the newly requiredServicesmember and fails with CS9035. Provide a construction pattern where either alias initializes the shared value before regenerating the API.
src/Aspire.Hosting/api/Aspire.Hosting.cs:2966 - The obsolete alias does not preserve source compatibility: an existing initializer that assigns
ServiceProviderno longer satisfies the newly requiredServicesmember and fails with CS9035. Provide a construction pattern where either alias initializes the shared value before regenerating the API.
src/Aspire.Hosting/api/Aspire.Hosting.cs:4417 - The obsolete alias does not preserve source compatibility: an existing initializer that assigns
ServiceProviderno longer satisfies the newly requiredServicesmember and fails with CS9035. Provide a construction pattern where either alias initializes the shared value before regenerating the API.
- Files reviewed: 34/34 changed files
- Comments generated: 2
- Review effort level: Balanced
| public static AzureBicepResourceScope CreateForSubscription(object subscription) { throw null; } | ||
|
|
||
| public static AzureBicepResourceScope CreateForTenant() { throw null; } |
| public sealed partial class ParameterProcessor | ||
| { | ||
| public ParameterProcessor(ApplicationModel.ResourceNotificationService notificationService, ApplicationModel.ResourceLoggerService loggerService, IInteractionService interactionService, Microsoft.Extensions.Logging.ILogger<ParameterProcessor> logger, DistributedApplicationExecutionContext executionContext, Pipelines.IDeploymentStateManager deploymentStateManager, IUserSecretsManager userSecretsManager) { } |
Auto-generated update to the API surface to compare current surface vs latest release. This should only be merged once this surface area ships in a new release.