Expose IServiceProvider and callback contexts to ATS polyglot hosts#18059
Expose IServiceProvider and callback contexts to ATS polyglot hosts#18059sebastienros wants to merge 7 commits into
Conversation
Several callback contexts that previously carried [AspireExportIgnore] on their IServiceProvider members were ignored entirely because polyglot hosts could not consume IServiceProvider. Now that IServiceProvider is an exported ATS handle, expose those members (named "services") and the contexts that wrap them, and close the WithContainerFiles callback gap so polyglot hosts can build file-system entries through factory methods. - Expose ServiceProvider/Services members as "services" on the command, https endpoint, container build, required-command, and container-file callback contexts; keep only accurate, documented ignores. - Export the WithContainerBuildOptions (async), WithHttpsCertificateConfiguration, SubscribeHttpsEndpointsUpdate, and WithRequiredCommand validation overloads. - Add internal static factory shims (CreateFile/CreateCertificateFile/ CreateDirectory) on ContainerFileSystemCallbackContext plus a WithContainerFilesCallbackExport shim that accepts integer file-mode options. - Add Success()/Failure() helpers on RequiredCommandValidationContext. - Wire all four polyglot app hosts (Go/Java/Python/TypeScript) with real extension-method usage on services, regenerate the five codegen snapshots, and add unit tests for the new factories and validation helpers. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 18059Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 18059" |
There was a problem hiding this comment.
Pull request overview
This PR expands the Aspire Hosting ATS/polyglot surface by exporting IServiceProvider on multiple callback contexts (as services), exporting additional builder overloads used by polyglot app hosts, and adding ATS-friendly factory shims so polyglot callbacks can construct container file-system entries.
Changes:
- Exported callback contexts and builder overloads so polyglot app hosts can access
servicesand use async callback-based configuration APIs (HTTPS certificate config, HTTPS endpoint update subscription, container build options, required-command validation). - Added ATS-friendly container-files callback support by exporting
ContainerFileSystemItemas an opaque handle and providing context factory shims to create file/directory/certificate entries. - Updated polyglot app hosts and regenerated codegen snapshots; added unit tests covering new container-files factories and required-command validation helpers.
Reviewed changes
Copilot reviewed 21 out of 24 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/PolyglotAppHosts/Aspire.Hosting/TypeScript/apphost.mts | Exercises newly exported callbacks and services() usage from TypeScript. |
| tests/PolyglotAppHosts/Aspire.Hosting/Python/apphost.py | Exercises newly exported callbacks and services usage from Python. |
| tests/PolyglotAppHosts/Aspire.Hosting/Java/AppHost.java | Exercises newly exported callbacks and services() usage from Java. |
| tests/PolyglotAppHosts/Aspire.Hosting/Go/apphost.go | Exercises newly exported callbacks and Services() usage from Go. |
| tests/Aspire.Hosting.Tests/RequiredCommandAnnotationTests.cs | Adds unit tests for RequiredCommandValidationContext.Success/Failure. |
| tests/Aspire.Hosting.Containers.Tests/ContainerFileSystemCallbackContextTests.cs | Adds unit tests for the new container-files context factories and mode validation. |
| tests/Aspire.Hosting.CodeGeneration.Rust.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.rs | Updated Rust SDK snapshot for newly exported types/methods. |
| tests/Aspire.Hosting.CodeGeneration.Python.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.py | Updated Python SDK snapshot for newly exported types/methods. |
| src/Aspire.Hosting/ResourceBuilderExtensions.cs | Exports HTTPS certificate configuration + HTTPS endpoints update subscription for ATS. |
| src/Aspire.Hosting/RequiredCommandResourceExtensions.cs | Exports required-command validation overload for ATS. |
| src/Aspire.Hosting/IInteractionService.cs | Exposes InputsDialogValidationContext.Services to ATS. |
| src/Aspire.Hosting/Dcp/Model/Container.cs | Adds ATS ignore annotation on internal DCP conversion extension. |
| src/Aspire.Hosting/ContainerResourceBuilderExtensions.cs | Adds ATS-exported withContainerFilesCallback shim and updates ATS-related remarks/ignore reasons. |
| src/Aspire.Hosting/ApplicationModel/ResourceExtensions.cs | Exports async WithContainerBuildOptions overload for ATS. |
| src/Aspire.Hosting/ApplicationModel/ResourceCommandAnnotation.cs | Exports command callback ServiceProvider as services. |
| src/Aspire.Hosting/ApplicationModel/RequiredCommandValidationResult.cs | Exports validation result properties for ATS. |
| src/Aspire.Hosting/ApplicationModel/RequiredCommandValidationContext.cs | Exports validation context properties + helper methods for ATS. |
| src/Aspire.Hosting/ApplicationModel/HttpsEndpointUpdateCallbackContext.cs | Exports HTTPS endpoint update context properties for ATS. |
| src/Aspire.Hosting/ApplicationModel/HttpsCertificateConfigurationCallbackAnnotaion.cs | Exports HTTPS certificate callback context and ATS-friendly argument/env editors. |
| src/Aspire.Hosting/ApplicationModel/ContainerFileSystemCallbackAnnotation.cs | Exports container file-system callback context + adds ATS factory shims for entries. |
| src/Aspire.Hosting/ApplicationModel/ContainerBuildOptionsCallbackAnnotation.cs | Exports container build options callback context properties for ATS. |
PR Testing ReportPR Information
CLI Version Verification
Changes AnalyzedThis PR removes stale Change Categories
Test ApproachInstalled the PR dogfood CLI, scaffolded a fresh TypeScript app host Test Scenarios ExecutedScenario 1: Type-check custom TS app host against generated SDKObjective: All new API signatures compile in a real TS app host. Scenario 2: Runtime execution under Docker (callbacks fire over RPC)Objective: Confirm RPC handshake + each callback executes and the new Scenario 3 (boundary): malformed certificate via createCertificateFileObjective: Negative case — feed Per-API Verification
Summary
Overall Result✅ PR VERIFIED — Every newly-exported API is present in the generated TypeScript SDK, Notes
|
…ed_command codegen Resolves copilot-pull-request-reviewer feedback on the ATS export PR: - CreateFile/CreateCertificateFile now throw ArgumentException up front when both `contents` and `sourcePath` are provided, since they are mutually exclusive. Added unit tests covering both factories. - Python generator: stop merging callback-differentiated overloads in MergeCapabilitiesBySourceLocation (added IsCallback to the merge guard). This restores `required_command: str | tuple[str, str]` (no breaking change to the published tuple shorthand) and emits a separate `with_required_command_validation` method/`required_command_validation` option instead of forcing a TypedDict and a buggy conditional dispatch that always registered a null validationCallback. - Regenerated the Python snapshot and updated the Python polyglot apphost to call the new `with_required_command_validation` method. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…erviceprovider-ats # Conflicts: # src/Aspire.Hosting/ApplicationModel/ContainerFileSystemCallbackAnnotation.cs # src/Aspire.Hosting/ApplicationModel/ResourceCommandAnnotation.cs
After merging origin/main (#18034 obsoleted ServiceProvider in favor of a Services property), the two command callback contexts were left ignored, which broke the polyglot apphosts that call services() on them and the Containers test helper that still set the obsolete ServiceProvider. - ResourceCommandAnnotation.cs: ExecuteCommandContext and UpdateCommandStateContext now export 'services' via the Services property (ExposeProperties = true); the obsolete ServiceProvider alias keeps [AspireExportIgnore] to avoid a duplicate 'serviceProvider' export. - ContainerFileSystemCallbackContextTests.cs: use Services instead of the obsolete ServiceProvider in the test helper (fixes CS0618/CS9035). - Regenerated all 5 language codegen snapshots to include ExecuteCommandContext.services and UpdateCommandStateContext.services. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Exposing the container-files callback overload (and other CancellationToken callbacks) made the generated Java SDK call CancellationToken.fromValue(args[N]) to materialize the token the AppHost passes when invoking the callback. The Java runtime CancellationToken template never defined that factory, so the generated apphost failed to compile (cannot find symbol: fromValue), breaking Java SDK Validation. The codegen snapshot tests only diff text and never compile Java, so this latent gap was not caught. Add a static fromValue(Object) factory mirroring the TypeScript and Go SDKs: it returns the value if it is already a CancellationToken, wraps a remote token id string, and otherwise returns a fresh token. Regenerated the Java snapshots. Verified by splitting the generated Java snapshot into files and compiling all 217 with javac: clean (no fromValue/CancellationToken errors). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The C# <summary> and <returns> XML docs are valid for ATS, and the scanner already falls back to the standard tags when no ats- override is present (AtsCapabilityScanner.GetDocumentationElement). Drop the duplicate ats-summary and ats-returns so the generated polyglot docs use the C# documentation directly. Regenerated all 5 language snapshots. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
❓ CLI E2E Tests unknown — 113 passed, 0 failed, 2 unknown (commit View all recordings
📹 Recordings uploaded automatically from CI run #27232459256 |
Both ignored WithContainerFiles overloads had a one-line <remarks> that restated the attribute's Reason. Drop them; the [AspireExportIgnore] Reason already documents how each overload is exposed to ATS. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Description
Several callback contexts carried
[AspireExportIgnore]on theirIServiceProvidermembers, which forced the entire context (and its builder overloads) to be hidden from polyglot app hosts becauseIServiceProvidercould not be consumed from ATS. Now thatIServiceProvideris an exported ATS handle, those members can be exposed, and the contexts that wrap them become usable from TypeScript/Go/Java/Python.This PR removes the now-unnecessary ignores, exposes the service provider consistently as
services, and closes theWithContainerFilescallback gap so polyglot hosts can build container file-system entries (including inline contents and OpenSSL certificate files) through factory methods rather than the host-only polymorphic hierarchy.What changed
services:ServiceProvider/Servicesmembers on the command (ExecuteCommandContext,UpdateCommandStateContext), HTTPS endpoint update, container build options, required-command validation, and container-file callback contexts are now exported, namedserviceson the newly exposed members. Properties already namedServicesmap toservicesautomatically;ServiceProviderproperties useMethodName = "services". Remaining ignores are only onFunc<IServiceProvider, ...>parameters (lifecycle hooks, Kusto health check) and carry accurate reasons pointing to ATS-friendly alternatives.WithContainerBuildOptions,WithHttpsCertificateConfiguration,SubscribeHttpsEndpointsUpdate, and the validation-callbackWithRequiredCommandoverloads are now exported. The threeContainerImage*enums they depend on are exported too.CreateFile/CreateCertificateFile/CreateDirectory) onContainerFileSystemCallbackContext, plus aWithContainerFilesCallbackExportshim that accepts integer file-mode options (ContainerFilesOptions) and forwards to the realWithContainerFiles. This lets polyglot callbacks construct theIEnumerable<ContainerFileSystemItem>result that was previously .NET-only.Success()/Failure(string)onRequiredCommandValidationContextso polyglot callbacks can return a result without a static factory reference.services(e.g.services().getLoggerFactory()), regenerated the five codegen snapshots, and added unit tests for the new factories (ConvertModerange/validation, recursive entries) and the validation helpers.Notes for reviewers
tests/PolyglotAppHostsapps and codegen snapshots rather than unit tests asserting generated shape.internal staticextension methods (the established polyglot-only shim pattern) so they do not expand the public C# surface.api/*.csbaseline files are intentionally not regenerated here; that happens at release time.Checklist
<remarks />and<code />elements on your triple slash comments?