Merge release/13.4 to main after v13.4.0 release#17804
Closed
aspire-repo-bot[bot] wants to merge 43 commits into
Closed
Merge release/13.4 to main after v13.4.0 release#17804aspire-repo-bot[bot] wants to merge 43 commits into
aspire-repo-bot[bot] wants to merge 43 commits into
Conversation
…7520) Flip StabilizePackageVersion default to true in eng/Versions.props. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix remaining issue 17244 items Preserve legacy auxiliary backchannel resource property serialization unless clients opt in to JSON-valued properties, and remove the unused dashboard start command filter. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address backchannel review feedback Use the existing auxiliary backchannel V3 capability for typed resource properties and stop advertising a new V4 capability. Also limit the watch-resource capability test to the first streamed snapshot so it does not wait for a never-ending watch stream. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Adam Ratzman <adam@adamratzman.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: IEvangelist <7679720+IEvangelist@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…egration and fix found issues (#17531) * Migrate playground/SqlServerEndToEnd to EF Hosting integration - Remove the `SqlServerEndToEnd.DbSetup` worker project. Its `EnsureCreatedAsync` schema bootstrap is replaced by the `AddEFMigrations` resource model. - Check in the initial migration set. `Aspire.Hosting.EntityFrameworkCore` fixes - Connection-string resolution for the generated `Dockerfile` / bundle env-var now prefers explicit `.WithReference(<db>)` over `.WaitFor(<db>)`. Falls back to wait-based inference only when no references are declared. - `EFCoreOperationExecutor`: read exit code from the strongly-typed `snapshot.ExitCode` instead of parsing the `ExitCode` property string, and publish `ExitCode` on the tool resource's final snapshot update so consumers (including the executor itself) see it. - Tighten `AddEFMigrationsCore` duplicate-registration error messages to talk about "registered for specific DbContext types" / "registered without a context type" instead of "auto-detected". - XML doc cleanup on the public `AddEFMigrations` / `PublishAsMigrationBundle` / `WithMigrationsProject` / `WithMigrationOutputDirectory` / `WithMigrationNamespace` / `RunDatabaseUpdateOnStart` overloads (more accurate summaries, `<c>` instead of quotes, drop obsolete "auto-detected" language, add `<exception>` notes). * Avoid concurrent tool execution --------- Co-authored-by: Andriy Svyryd <Andriy.Svyryd@microsoft.com>
…g.md (#17541) The Spectre.Console [Y/n] confirmation prompt is a single-character reader, not a line reader. Sending TypeAsync("n") + EnterAsync() queues both bytes in the TTY input buffer; when the CLI returns on "n" and tears down its stdin handler before \n is consumed, bash receives the stray \n as an empty command and bumps CMDCOUNT via PROMPT_COMMAND. The test's SequenceCounter then ends up coincidentally agreeing with bash's drifted CMDCOUNT. The next WaitForAspireAddSuccessAsync false-positives on the typed-command prompt header line ([N OK] $ aspire add ...) that bash printed when accepting the command, returning success before aspire add has actually written aspire.config.json. The follow-on Assert reads the file too early and fails. This matches the existing convention in DeclineAgentInitPromptAsync which documents the same race and avoids it by not sending Enter after the single-character answer. Also adds .github/skills/cli-e2e-testing/troubleshooting.md describing the diagnostic recipe (right-artifact selection, cast reconstruction, prompt- counter desync, Y/n race signature) so future agent sessions can recognize the pattern, and references it from SKILL.md. Co-authored-by: Mitch Denny <midenn@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address remaining PR feedback and fix Docker Compose publish PR feedback from #15691: - Add [ResourceName] attribute to all Add* API name parameters - Replace null-forgiving operator with explicit throw in EndpointsManifestTransformer - Use StringComparison.OrdinalIgnoreCase for route comparison - Fix '.NET Aspire' phrasing in README files Docker Compose publish fixes for Blazor gateway: - Add GatewayOriginReference (IValueProvider + IManifestExpressionProvider) - Use ReferenceExpression for ConfigResponse so publishers emit proper placeholders - Use TextEncoderSettings to escape braces in JSON string values - Simplify Gateway.cs.in (serve ConfigResponse directly, no Replace logic) - Add System.Text.Unicode dependency for brace-escaping encoder Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add OTLP misconfiguration warning to hosted Blazor path The standalone gateway path already logged a warning when telemetry proxying was requested but no HTTP OTLP endpoint could be resolved. The hosted model (ProxyBlazorTelemetry via BlazorHostedExtensions) was missing the equivalent diagnostic. - Add LogWarning in BlazorHostedExtensions.EnsureEnvironmentCallback - Add tests verifying the warning fires (and does not fire) in both scenarios Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Rename ASPIRE_OTLP_PATH_BASE to OTEL_EXPORTER_OTLP_ENDPOINT Use the standard OpenTelemetry environment variable name instead of a custom Aspire-specific one. The value remains a relative path that the WASM client resolves against its page origin to stay same-origin. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use TestSink/TestLogger instead of custom ListLogger Replace private ListLogger and LogMessage with shared TestSink and TestLogger from Microsoft.Extensions.Logging.Testing. Also moves the OTLP warning in the standalone gateway path before the build step so it is testable, and adds two tests for that path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Filter OTLP proxy traffic from tracing to prevent feedback loop The gateway and hosted server YARP proxies forward /_otlp/* requests to the dashboard. Without filtering, those forwarding requests are themselves traced and exported, creating recursive telemetry entries. - Gateway (Gateway.cs.in): Simplified filter to use Contains for /_otlp/ paths (handles prefix-mounted apps like /app/_otlp/...). Removed IsStaticAssetOrOtlpRequest helper since static asset requests don't go through YARP. - Hosted server (Program.cs): Added PostConfigure to wrap existing OTEL filters with /_otlp/ and /v1/ exclusions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Javier Calvarro Nelson <jacalvar@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…step (#17543) * Friendly error for 'aspire do --list-steps' without a step 'aspire do' is always step-targeted, so '--list-steps' with no step has no meaningful scope. The validator previously allowed it, which caused the CLI to launch the AppHost and race ahead executing the full pipeline before the CLI could fetch steps and stop. That race surfaced as 'InvalidOperationException: Sequence contains more than one matching element' from AzurePublishingContext (#17526). Tighten the DoCommand validator to always require the step argument (outside the extension host, which prompts interactively). When the user specifies '--list-steps' without a step, emit a friendly, localized error pointing at concrete examples: 'aspire do deploy --list-steps' or 'aspire do publish --list-steps'. Adds StepArgumentRequired and ListStepsRequiresStep entries to DoCommandStrings.resx + Designer.cs and refreshes all xlf translations via UpdateXlf. Tests: - DoCommandTests: new DoCommandWithListStepsAndNoStepArgumentShowsFriendlyError regression case; existing list-steps tests updated to pass a step. - ListStepsTests (E2E): single Docker-backed test now exercises 'aspire do --list-steps' (asserts friendly error and the absence of the 'Sequence contains more than one matching element' crash) plus 'aspire do deploy --list-steps', 'aspire publish --list-steps' and 'aspire deploy --list-steps' against a freshly created starter app. Fixes: #17526 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * List all well-known step names in the friendly error Expand the 'aspire do --list-steps' validation error to enumerate every well-known pipeline step instead of just naming 'deploy' and 'publish'. The step names are hand-maintained in DoCommand alongside a comment pointing at src/Aspire.Hosting/Pipelines/WellKnownPipelineSteps.cs (the CLI does not reference Aspire.Hosting). Updated unit and E2E assertions to match the new message shape. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Trim list to build/publish/deploy and add docs link Replace the long enumeration of well-known step names with a short, opinionated suggestion (build, publish, deploy) and a link to the official 'aspire do' reference page on aspire.dev for the full list. This removes the hand-maintained mirror of WellKnownPipelineSteps in DoCommand and simplifies localization since the message no longer takes a format parameter. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address review: fix extension-host bypass and harden E2E asserts - DoCommand validator: fire the ListStepsRequiresStep friendly error for `aspire do --list-steps` even when running in the extension host, because --list-steps does not flow through GetRunArgumentsAsync's interactive step prompt and would otherwise still hit the original pipeline crash from #17526. - ListStepsTests (E2E): replace long, wrap-sensitive substrings with short fragments ("required when using --list-steps", "aspire.dev/") so the assertion does not fail when the friendly error wraps in a narrow Docker terminal. - DoCommandTests: add DoCommandWithListStepsAndNoStepArgumentInExtensionHostShowsFriendlyError to regression-test the extension-host path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Mitch Denny <midenn@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… deploy (#17542) * Validate Helm CLI version (>= 4.2.0) before Kubernetes deploy Aspire's Kubernetes deployment pipeline shells out to 'helm upgrade --install' for the main application chart and for any AddHelmChart(...) resources on a KubernetesEnvironmentResource. Previously we only checked that 'helm' was on PATH; we never asserted the installed Helm version was new enough for the flags and behaviors we depend on (e.g. '--server-side=true --force-conflicts' in the Helm 4 form). Missing or older Helm produced confusing low-level errors like 'unknown flag: --force-conflicts', 'Flag --force has been deprecated', or raw process-spawn failures. Changes: * Add internal HelmVersionValidator that runs 'helm version --short --client', parses the SemVer, and asserts a minimum of Helm 4.2.0. Throws a clear actionable InvalidOperationException (detected vs required + link to https://helm.sh/docs/intro/install/) when the version is too old, unparseable, or the command fails. * Wire the validator into the existing check-helm-prereqs-{env} pipeline step in HelmDeploymentEngine. One check per environment covers both the main chart deploy and AddHelmChart(...) flows since they all DependsOn this step. * Update the 'Helm CLI not found' message to also mention the minimum version requirement. * Remove the now-redundant ad-hoc 'helm version --short' probe at the top of HelmDeployAsync (the prereq step covers it with a much better error). * Promote FakeHelmRunner to a file-scoped test helper that emits canned 'helm version' stdout (defaults to v4.2.0+gfa15ec0) and supports a separate VersionExitCode, so any test exercising the deploy path automatically passes the prereq check. * Add HelmVersionValidatorTests covering: SemVer parsing of v3/v4/v5 outputs with and without '+gitsha' build metadata, rejection of unparseable output, threshold behavior for too-old versions (v4.1.0, v4.0.0, v3.18.0, v3.14.4), and that error messages include the detected version, the required version, and the install docs URL. * Document the Helm 4.2.0+ requirement in the Aspire.Hosting.Kubernetes and Aspire.Hosting.Azure.Kubernetes READMEs. Fixes #16977 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Drop --client flag from helm version invocation The validator was invoking 'helm version --short --client', but the --client flag was removed in Helm 4 (it existed in Helm 2 for the real client/server split, was kept as a no-op in Helm 3, and is unknown in Helm 4). Since this validator's purpose is to enforce Helm 4.2.0 or later, passing --client guarantees a failure against the very minimum version we require, surfacing the exact kind of confusing prereq error this step exists to prevent. Caught by dogfood testing of PR #17491 against a local Helm 4.2.0 install, which produced: Step 'check-helm-prereqs-k8s' failed: 'helm version --short --client' failed (Error: unknown flag: --client). Aspire requires Helm 4.2.0 or later. Switch to 'helm version --short', which produces identical output shape (e.g. v4.2.0+gfa15ec0) on Helm 3 and Helm 4. Add a regression test that records the arguments passed to the runner and asserts --client is never included. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review feedback Three review items from the automated PR reviewer: 1. Gate destroy/uninstall on the same Helm prereq check as deploy. Both 'destroy-helm-{env}' and 'helm-uninstall-{env}' invoke 'helm uninstall', so a missing or too-old Helm would surface as a raw process-spawn / unknown-flag error during teardown instead of the actionable validator message. Add a 'DependsOn(check-helm-prereqs- {env})' on both, and add a regression test that asserts the dependency edge exists. 2. Fix the misleading comment above HelmVersionRegex. The regex is intentionally unanchored so we tolerate banner/shim lines that some shells, oh-my-zsh plugins, or asdf-style shims can prepend to the version output. Update the comment to describe that intent instead of claiming a start anchor that isn't there. 3. Shorten the Helm prerequisite bullets in both Kubernetes README files. Keep the bullet to the requirement itself and move the 'why we validate up front' narrative into a short paragraph below, matching the scannable style of the other hosting READMEs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Bump E2E Helm install version to v4.2.0 to match new floor The 11 DeployK8s* CLI E2E tests failed on commit d03916c because the container install scripts default HELM_VERSION to v3.17.3 — below the new HelmVersionValidator.MinimumHelmVersion (v4.2.0) that the check-helm-prereqs-{env} pipeline step now enforces. Centralize the version constants in a new tests/Aspire.Cli.EndToEnd.Tests/Helpers/KubernetesE2EVersions.cs so the default lives in one place (and points at the validator's documented minimum), then bump HelmVersion default v3.17.3 -> v4.2.0 (used by every DeployK8s* test and by the quarantined KubernetesPublishTests). HELM_VERSION / KIND_VERSION / KUBECTL_VERSION env-var overrides are preserved so CI can still bump to a newer point release without a code change. The AKS deployment workflow (deployment-tests.yml) still pins azure/setup-helm to v4.1.4 and needs the same bump to v4.2.0 to avoid breaking AKS scenarios under the new validator; that workflow file edit will land in a separate push that has 'workflow' OAuth scope. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Bump deployment-tests.yml Helm pin to v4.2.0 Match Aspire.Hosting.Kubernetes' new minimum supported Helm version (HelmVersionValidator.MinimumHelmVersion). The check-helm-prereqs-{env} pipeline step now fails fast on older Helm CLIs, so leaving the AKS deployment workflow pinned to v4.1.4 would break every AKS deployment scenario. Also refresh the surrounding rationale comment, which still referred to the historical v3.18 server-side narrative. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Gate AddHelmChart uninstall on prereqs and unify Helm CLI check Address self-review follow-ups on PR #17491: - Per-chart `helm-uninstall-{name}` step (AddHelmChart(...).WithDestroy()) now depends on `check-helm-prereqs-{env}`. Previously only the env-level destroy/uninstall steps were gated, so chart teardown could still hit the cryptic spawn / unknown-flag error the validator exists to prevent. - Drop the standalone PathLookupHelper probe from the prereq step. The validator already wraps spawn failures with the same actionable hint, and routing everything through IHelmRunner lets tests inject a fake without needing real Helm on PATH (fixes 3 pre-existing K8s test failures in environments without helm installed). - Refresh validator catch comment + error wording accordingly. - Drop stale `--client` mention in FakeHelmRunner comment. - Add regression test PerChartHelmUninstallStep_DependsOnCheckHelmPrereqs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Defer Helm version check in destroy-helm-{env} until state is found Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Mitch Denny <midenn@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add embedded Aspire skills fallback (#17537) Embed a checked-in Aspire skills bundle snapshot for CLI fallback, make agent init warn instead of fail when bundle acquisition is unavailable, and add automation to refresh the snapshot via a draft PR. Co-authored-by: IEvangelist <7679720+IEvangelist@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix release backport resource strings Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix Docker compose prepare test runtime dependency Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: IEvangelist <7679720+IEvangelist@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rce mapping (#17528) * Bake AspireCliChannel=staging for release-branch builds even when stabilizing The channel-compute step in build_sign_native.yml was checking $versionKind -eq 'release' BEFORE the release-branch regex check. A 13.4 staging build runs from a release/* branch with StabilizePackageVersion=true, which sets DotNetFinalVersionKind=release, so the wrong arm fired and baked AspireCliChannel=stable into the binary. Downstream, aspire init reads CliExecutionContext.IdentityChannel to pick the channel mappings it writes into the workspace nuget.config. With identity=stable there's no Aspire.* → staging-feed mapping, so aspire add tries to resolve packages from nuget.org and either gets 13.3.5 or fails outright (the apphost.cs template pins #:sdk Aspire.AppHost.Sdk@13.4.0+<sha>, which isn't on nuget.org). Swap the conditions so the release-branch check runs first. Release- branch builds are always staging artifacts; only release-shaped non-release-branch builds (effectively none in practice) get stable. Fixes #17527 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add aspireCliChannelOverride pipeline parameter for GA ship builds With release-branch builds now defaulting to 'staging' (so stabilizing dogfood builds aren't mis-baked as 'stable'), there was no remaining path to produce a real 'stable' GA ship binary — the same release/* branch that produces the staging dogfood drops also produces the final ship build, and the pipeline has no other signal to tell them apart. Add a runtime pipeline parameter 'aspireCliChannelOverride' (auto | stable | staging | daily, default auto) to azure-pipelines.yml and thread it through every build_sign_native.yml invocation. When the release manager kicks off the official GA ship build, they set this to 'stable' so the distributed binary bakes AspireCliChannel=stable and aspire init writes the nuget.org-only nuget.config that matches the promoted package set. Routine stabilizing builds leave it on 'auto' and continue to bake 'staging'. The override is validated against the same accepted-channel set that IdentityChannelReader.IsValidChannel enforces at CLI startup so a typo fails the pipeline step rather than producing a binary that refuses to boot. pr-<N> is intentionally excluded from the override set since PR builds always come from the PullRequest reason arm. The unofficial pipeline doesn't get the parameter — its test builds should always derive the channel from branch+reason, and the template's default 'auto' achieves that. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Route stabilizing staging CLI to SHA-derived darc feed The staging-channel synthesis in PackagingService defaulted to PackageChannelQuality.Both for staging-identity CLIs. With Both, useSharedFeed=true and Aspire.* gets routed to the shared dnceng/dotnet9 daily feed -- which only contains prerelease-tagged 13.4.0-preview.* packages, not the stable-shaped 13.4.0 packages produced during release stabilization (StabilizePackageVersion=true). Net effect on the just-shipped staging build of 13.4: `aspire init` drops a NuGet.config pointing Aspire.* at dotnet9, then `aspire add yarp` fails to resolve Aspire.Hosting.Yarp 13.4.0 because dotnet9 doesn't carry it. The packages actually live in the SHA-derived darc-pub-microsoft-aspire-<hash> feed. Fix: when the CLI's identity is staging, derive the synthesized channel's default quality from the CLI build's version shape: - Stable-shaped (no semver prerelease tag) -> Stable, which makes useSharedFeed=false and routes Aspire.* to the SHA-derived darc feed where stabilizing packages actually live. - Prerelease-shaped -> Both (the historical default), since SHA- specific darc feeds are only created for stable release-branch builds and prerelease staging CLIs must use the shared feed. The identity-staging branch runs before the requested/configured branches in the if/else because `init` (and many other commands) calls GetChannelsAsync(requestedChannelName: "staging") when the running CLI's identity is staging -- short-circuiting on the requested branch would re-introduce the bug. The version-shape predicate is injected via constructor so unit tests can deterministically exercise both paths regardless of the test-host assembly's baked InformationalVersion. Validated end-to-end with a locally-built NAOT `aspire` binary (`/p:AspireCliChannel=staging`) + overrideStagingFeed pointing at darc-pub-microsoft-aspire-0f514452: `aspire init` -> `aspire add yarp` now resolves Aspire.Hosting.Yarp 13.4.0 instead of falling back to 13.3.5. Refs #17527 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Pin PackagingService stable-shape predicate to false in CliTestHelper The stabilization-check CI job builds the test host with StabilizePackageVersion=true, which bakes a stable-shaped (no '-') informational version into Aspire.Cli. PackagingService's new identity-staging branch then defaults quality to Stable and requires a SHA suffix in the assembly's InformationalVersion to compute the darc-pub feed URL. Stabilized test-host assemblies don't carry a +sha suffix, so CreateStagingChannel returned null and the UpdateCommand_WhenStagingIdentityRegistersChannel_UsesStagingForUnpinnedProject test fell back to the default channel instead of staging. Default CliTestHelper.PackagingServiceFactory to inject isStableShapedCliVersion: () => false so command-level tests get deterministic prerelease-shaped behavior (quality=Both → shared dotnet9 feed) regardless of how the test host was built. Tests that specifically exercise the stable-shape branch (in PackagingServiceTests) construct PackagingService directly and already pass an explicit predicate. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update eng/pipelines/templates/build_sign_native.yml --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Jose Perez Rodriguez <joperezr@microsoft.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…17556) * Enrich AppHost codegen TypeLoadException diagnostics (#16709) When the installed Aspire CLI ships an �spire-managed server whose bundled Aspire.Hosting.dll is on a different build than the user-restored Aspire.Hosting.CodeGeneration.TypeScript / Aspire.TypeSystem DLLs, reflection-based codegen can throw an empty TypeLoadException that travels back to the CLI with no message and triggers a 60-second backchannel timeout. This change adds three coordinated improvements: 1. Server-side: wrap reflection-load exceptions (TypeLoadException, MissingMethodException, MissingFieldException, BadImageFormatException, FileLoadException, ReflectionTypeLoadException) in a LocalRpcException with a safe, language-agnostic Message and a structured ErrorData payload (TypeName, MemberName, loaded ATS assemblies + informational versions, runtime Aspire.Hosting version, original exception type) carried via JSON-RPC error code -32050. 2. CLI-side: tiered output — emit a yellow pre-flight warning on detected CLI/SDK skew; render only the safe summary + remediation hint by default; reveal the full .NET diagnostic payload under --debug; always log the full payload via LogDebug. Also fault the BackchannelCompletionSource immediately on codegen failure so users no longer wait through the 60s timeout. 3. CLI-side: prune leftover cli.sock.* files older than 24 hours from ~/.aspire/cli/runtime/sockets/ on startup so stale entries don't accumulate from previous crashed runs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review feedback for #16709 - Drop [JsonPropertyName(camelCase)] from CLI diagnostic DTO so the source-generated context deserializes the server's default PascalCase payload. Add a wire-contract test that round-trips the on-the-wire shape and the BackchannelJsonSerializerContext options. - Use SemVersion.ComparePrecedence in IsKnownIncompatibleSkew so SemVer prerelease identifiers are compared (the #16709 case: 13.4.0-preview.1.26218.1 vs 13.4.0-preview.1.26227.1). Update skew tests to cover prerelease and build-metadata cases. - Resolve the runtime Aspire.Hosting version by walking AppDomain.CurrentDomain.GetAssemblies(); never fall back to Aspire.Hosting.RemoteHost (which is what typeof(AssemblyLoader) returned). Add a regression test. - Only the diagnostic-section header keeps the microscope emoji; the continuation lines (Exception, Type, Member, runtime version, loaded assemblies) render as plain text indented under the header. - Tests: use Directory.CreateTempSubdirectory() instead of manually combining Path.GetTempPath() + Guid for CliPathHelper janitor tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix stale CLI socket cleanup matching Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR feedback on codegen diagnostics - Catch AppHostCodeGenerationException in sdk dump per-integration path so one failing integration does not abort the full Task.WhenAll batch. - Log the full serialized AppHostCodeGenerationDiagnostic payload in RenderCodeGenerationFailure so debug logs match the XML doc contract. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: IEvangelist <7679720+IEvangelist@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Sebastien Ros <sebastienros@gmail.com>
* Prefer current CLI template version Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Pin aspire new template version to CLI Ensure CLI-runtime templates selected from explicit package channels use the current bundled CLI/SDK version instead of floating to newer channel packages that can mismatch the bundled AppHost server. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…Folder path (#17573) * Stabilize PrebuiltAppHostServer staging globalPackagesFolder path PackagingService creates the staging channel with ConfigureGlobalPackagesFolder=true so each darc/override feed restore lands in an isolated cache (two staging builds of the same release branch ship as 13.4.0 but from different feeds, and NuGet keys by (id,version) only). PrebuiltAppHostServer was wiring that flag into a TemporaryNuGetConfig whose default globalPackagesFolder value is the relative '.nugetpackages' -- NuGet resolved it under the temp config's own directory, BundleNuGetService baked those temp paths into integration-package-probe-manifest.json, and TemporaryNuGetConfig.Dispose then recursively deleted the cache out from under the manifest. On macOS osx-arm64 polyglot staging builds this surfaced as a hang during DI / assembly loading in aspire-managed. Preserve the per-feed cache isolation behavior and anchor the override at a stable absolute path instead: <ASPIRE_HOME>/.nugetpackages/<first-8-of-CLI-commit-sha> Keying by the truncated commit hash matches the existing darc-pub-microsoft-aspire-<hash> feed URL convention in PackagingService.GetStagingFeedUrl, so the cache key and feed key stay aligned at 8 hex chars. 8 chars is short enough to avoid Windows MAX_PATH blow-ups on deep integration cache trees while keeping SHA collisions negligible. The cache lives under ASPIRE_HOME (not the per-AppHost working directory) so multiple AppHosts on the same machine running against the same staging build can share a single restore -- the unit of isolation here is the staging build, not the individual restore command. Mechanics: - TemporaryNuGetConfig.CreateAsync now accepts an optional globalPackagesFolderValue and propagates it through AddGlobalPackagesFolderToConfigAsync into the merger. - NuGetConfigMerger.AddGlobalPackagesFolderConfiguration takes the optional override and falls back to the workspace-relative default ('.nugetpackages') for the non-temp workspace-merge path. - PrebuiltAppHostServer.ResolveStableGlobalPackagesFolder routes both temp config branches (channel and package-source-override) through the new helper. - VersionHelper.TryGetCurrentCommitHashShort surfaces the truncated SHA from the running CLI's AssemblyInformationalVersion (returns null on clean release builds with no '+sha' suffix; callers fall back to 'default'). - CliPathHelper centralizes the '<ASPIRE_HOME>/.nugetpackages' path so the producer (PrebuiltAppHostServer) and consumer (CacheCommand) can't drift. - CacheCommand.ClearCommand now wipes <ASPIRE_HOME>/.nugetpackages so a wedged staging restore is recoverable through the same UX as every other CLI cache. Tests: - Updated existing PrebuiltAppHostServerTests staging cases to assert the globalPackagesFolder value is absolute and lives outside the temp config directory. - New PrebuiltAppHostServerTests case wires a real PackagingService with overrideStagingFeed on a stable-shaped CLI and pins the same invariant end-to-end. - New TemporaryNuGetConfigTests for the override propagation and for the no-override-when-disabled invariant. - New CacheCommandTests covering the staging cache wipe and the missing-cache no-op path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Key staging globalPackagesFolder cache by feed URL hash The staging globalPackagesFolder fix in the previous commit keyed the \`.nugetpackages\` subdirectory off the CLI's own commit SHA (first 8 hex chars of \`AssemblyInformationalVersionAttribute\`). That handles two darc-shipped staging builds of the same release branch, but it breaks the local-dev case where one CLI is repeatedly retargeted at different \`overrideStagingFeed\` values: the URL changes but the SHA doesn't, so every override silently shares one cache bucket and the second restore reuses the first feed's now-stale \`13.4.0\` assemblies. Switch the cache key to the first 8 hex chars of \`XxHash3\` over the trimmed, lower-cased resolved feed URL: - Override branch passes the explicit \`--source\` URL. - Channel branch passes the channel's \`Aspire*\` mapping source (or the first mapping for forward compatibility). Trim + lower-case before hashing so a stray whitespace from a config file or a hostname-case change doesn't fragment the cache. Non-cryptographic hashing is fine here — the key is a directory name, not a security boundary — and 8 hex chars keep deep integration cache paths well under Windows MAX_PATH while giving ~4 billion buckets, so collisions are negligible across the handful of staging feeds any user ever sees. Removes the now-unused \`VersionHelper.TryGetCurrentCommitHashShort\` helper (added in the previous commit, no remaining callers). Tests: - New \`CliPathHelperTests.ComputeStagingFeedCacheKey_*\` cover determinism, normalization, length defaults, and null/empty input. - Existing \`PrebuiltAppHostServerTests\` strengthened to assert the emitted globalPackagesFolder equals \`<aspireHome>/.nugetpackages/<hash(feed)>\`. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Narrow #17564 CLI-pin fallback to prerelease channels PR #17564 introduced a new fallback in TryGetCurrentCliTemplateVersionPackage that pins the template package to the running CLI's SDK version whenever the selected channel is explicit and not local-build. That preserved the intended fix for prerelease channels (daily, staging) where the channel feed filters the running CLI's package out of search results even though the feed can still restore it. But it also fired for the stable channel, where the filter does not apply. For a non-stable-shape CLI (PR build like '13.4.0-pr.X.gY' or a daily-shape preview) invoked with '--channel stable', it forced an unpublishable version into the generated apphost.cs, breaking the SmokeTests LatestCliCanStartStableChannelAppHost and LatestCliCanStartStableChannelTypeScriptAppHost. Exclude the stable channel from the new fallback so that case falls through to the OrderByDescending picker and the user gets the highest shipped stable package they explicitly asked for. The original prerelease-channel motivation ('Aspire.TypeSystem version mismatch when 13.4 CLI floats templates to a 13.5 daily preview') is preserved unchanged. Test updates: - NewCommandChannelResolutionTests.NewCommand_NoChannelArg_ResolvesTemplateFromIdentityChannel gets an expectedVersion theory parameter so the daily case still pins to the CLI version while the stable case asserts the highest shipped stable. - NewCommandChannelResolutionTests.NewCommand_ExplicitChannelArg_OverridesIdentityChannel asserts highest shipped stable (matching the SmokeTest contract). - New NewCommand_ExplicitStableChannel_NonStableCliVersion_FallsBackToHighestShippedStable regression test covers both daily-shape and PR-shape CLI identities. - NewCommandTests.NewCommandWithTypeScriptEmptyTemplatePassesResolvedVersionAndChannelToScaffolding reverts to its pre-#17564 assertion of '9.2.0' from the stable feed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… with legacy fallback (#17571) * Use KnownConfigNames for resource service endpoint URL with legacy fallback Remove hardcoded DOTNET_RESOURCE_SERVICE_ENDPOINT_URL constant from DashboardServiceHost and use KnownConfigNames.ResourceServiceEndpointUrl (ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL) with fallback to KnownConfigNames.Legacy.ResourceServiceEndpointUrl. * Add test for configured resource service endpoint URL --------- Co-authored-by: James Newton-King <james@newtonking.com>
* Fix VS Code AppHost launch path resolution * Use aspire ls for extension AppHost discovery * Refresh AppHost discovery consumers on changes * Use CLI language ids for AppHost discovery * Handle AppHost discovery failures in editor commands * Add TypeScript AppHost launch discovery coverage * Harden AppHost discovery process handling * Honor configured AppHosts in discovery * Consolidate extension AppHost discovery * Fix workspace test path separators * Fix AppHost configured path selection Ensure workspace AppHost selection checks all configured paths before falling back to the single discovered candidate, and add a regression test for multiple config files.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Keep extension-launched AppHost CLI alive Keep the Aspire CLI process alive after VS Code launches an AppHost so the CLI-owned backchannel remains available for the lifetime of the extension-managed debug session. Propagate extension backchannel startup failures instead of returning success. Also ignore generated .modules directories for polyglot AppHosts. * Update extension build and CLI debug logging * Address AppHost launch review feedback Keep extension-managed CLI runs alive only until the AppHost backchannel disconnects, align configured AppHost discovery UX with scanned candidates, restore dynamic debug fallbacks, and return no disposable for async workspace prompts. Restore Yarn 1 frozen install compatibility for extension CI and avoid the npx package-name/bin-name mismatch in localization export. * Address extension discovery review feedback * Stabilize pipeline unit tests without Docker Use the existing fake container runtime resolver in the pipeline unit test context so the built-in container runtime check doesn't depend on Docker availability on CI runners. * Use ordinal comparison in pipeline test provider Keep the fake container runtime service-provider lookup null-safe and explicit. * Revert pipeline test isolation changes --------- (cherry picked from commit 00eff9d) Co-authored-by: David Fowler <davidfowl@gmail.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…d field filter details (#17568) * Update --search option description to include aka.ms link and field filter details * Regenerate xlf files to match current resx values --------- Co-authored-by: James Newton-King <james@newtonking.com>
Graduate the ATS/polyglot surface by removing ASPIREATS001 attributes and obsolete suppressions now that TypeScript/polyglot support is GA for 13.4. Co-authored-by: Sebastien Ros <sebastienros@gmail.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…cribe` for resource streaming (#17579) Backport of #17479 to release/13.4 Conflict resolved in extension/src/views/AppHostDataRepository.ts dispose(): kept both release/13.4's _getAppHostsProcess cleanup and the PR's _stopAllGlobalDescribes() call. Reverted the extension/package.json bump (1.0.9 -> 1.10.0) so the 13.4 extension line stays on 1.0.x. Co-authored-by: adamint <adamint@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Revert the Corepack-specific Yarn invocation added to the extension build so internal Azure Pipelines builds use the configured Yarn executable instead of downloading Yarn from the public registry. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…17623) * Fix aspire stop falsely reporting failure on Unix The stop path treated the managing CLI PID as a success condition. On Unix the CLI process can remain observable (for example as an unreaped or briefly lingering process) after the AppHost has already stopped, so aspire stop reported '\u274c Failed to stop apphost.cs' even when shutdown completed successfully. Use the AppHost PID as the success condition, and keep the CLI PID as a shutdown handle that still gets force-killed when present so we never leave a true zombie CLI running after the AppHost is gone. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Signal AppHost directly on Unix and tree-terminate on force-stop The cascade path (signal launcher CLI, let it terminate 'dotnet run', and rely on that to terminate the AppHost) is racy on Unix: if the descendant walk inside 'dotnet run' misses the AppHost, the AppHost is orphaned to PID 1 and HasExited polling can't distinguish a zombie from a live process, so 'aspire stop' falsely reports failure after the full SIGTERM + SIGKILL timeout (~40s). On Unix we now: * Send SIGTERM directly to the AppHost PID so it shuts down through its own IHostApplicationLifetime path. The launcher CLI and dotnet run process exit naturally when their child exits. * Pass killEntireProcessTree:true when force-terminating on Unix. DCP is launched in a separate session there, so force-terminating the AppHost tree doesn't take DCP with it; DCP detects the parent gone and tears down its own children gracefully. Windows behavior is preserved: we keep cascading through the launcher CLI to DCP because DCP is an in-tree descendant of the AppHost on Windows, and a full tree termination would break DCP's orderly resource cleanup. Validation in the repo's Linux container (Ubuntu 24.04 ARM64): * Baseline: 5/25 failures (20%), failures hit the 40s timeout * CLI-visibility-only fix: 1/25 failures (4%) * This change: 0/30 failures, stop wall-time 0.7-2.3s Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: David Negstad <David.Negstad@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…templates (#17637) * Add failing tests for aspire-starter channel resolution on release/13.4 Reproduces the bug where 'aspire new aspire-starter' (and aspire-starter-csharp-typescript) silently resolve Aspire.ProjectTemplates from the Implicit (nuget.org) channel on a daily / staging / release-branch CLI, ignoring CliExecutionContext.IdentityChannel. Passing --channel works because that value is the only thing forwarded into TemplateInputs.Channel today. The new tests pin the contract for both DotNet- and CLI-runtime templates: NewCommand must forward IdentityChannel into inputs.Channel whenever --channel is not passed, so DotNetTemplateFactory.ApplyTemplateAsync uses the identity-matching channel when calling TemplateNuGetConfigService.ResolveTemplatePackageAsync. Coverage across the four shipping identities (pr-<N>, daily, staging, stable) plus three edge cases (unregistered identity falls back to null, explicit --channel overrides identity, --version still forwards identity into inputs.Channel). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Forward IdentityChannel to TemplateInputs.Channel for dotnet-runtime templates When 'aspire new' invoked a TemplateRuntime.DotNet template (e.g. aspire-starter, aspire-starter-csharp-typescript) without an explicit --channel argument, inputs.Channel was left null. That caused TemplateNuGetConfigService.ResolveTemplatePackageAsync to fall back to the Implicit (nuget.org) channel, ignoring the CLI's IdentityChannel. Daily / staging / pr builds would therefore resolve Aspire.ProjectTemplates from nuget.org instead of the channel matching the running CLI. This change mirrors the existing CLI-runtime contract: when --channel is absent and no version-resolution channel was selected, look up the identity channel in the packaging service and forward it to inputs.Channel only when it matches a registered Explicit channel (Implicit matches still resolve to null so the project inherits ambient NuGet configuration). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Consolidate channel precedence into a single resolvedChannelName Address review feedback: collapse the explicitChannelArg / resolvedChannelName / identityChannelName three-way coalesce on TemplateInputs.Channel into a single resolvedChannelName variable with a clear precedence chain (explicit --channel > resolver result > identity). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Explain why identity-channel fallback lives at the call site Document why ResolveIdentityChannelNameAsync is invoked at the TemplateInputs assembly site rather than folded into ResolveCliTemplateVersionAsync: the two paths that need the identity hint (TemplateRuntime.DotNet templates and --version short-circuit) are precisely the ones the resolver never runs on. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…7646) The signed-build verifier ran 'aspire new aspire-starter' after extracting the CLI archive, claiming to exercise 'template engine + bundle self-extraction without requiring a NuGet restore'. That claim was wrong: 'aspire new' resolves template versions via TemplateNuGetConfigService.ResolveTemplatePackageAsync, which always queries a NuGet feed. The step only ever succeeded on release branches because builds were mis-baked with AspireCliChannel=stable, which routed the implicit identity-channel lookup to nuget.org and found a previously-shipped Aspire.ProjectTemplates version. Once #17528 corrected the release-branch builds to bake AspireCliChannel=staging, the identity channel switched to a staging feed that is not reachable from the 1ES signed-build agent, and the step started failing with 'No template versions were found' in the internal build pipeline. This is the same egress reason the TypeScript starter check was already removed for (#17274, tracked in #17345). Re-adding meaningful starter coverage in the signed-build verifier requires either an internal NuGet mirror or a no-network template path. Drop the step (and the corresponding test assertion); the verifier still covers archive layout, sidecar contract, and 'aspire --version' execution. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Accept dev localhost resource service URLs Allow DashboardServiceHost to treat RFC-reserved .localhost subdomains as local resource service endpoints so polyglot AppHosts scaffolded with *.dev.localhost can run. Add unit coverage for local endpoint recognition and a CLI E2E regression test that scaffolds and runs an Express/React polyglot AppHost with dev-localhost URLs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review follow-up comments Co-authored-by: danegsta <50252651+danegsta@users.noreply.github.com> * Use release E2E terminal lifecycle Adapt the backported polyglot dev-localhost CLI E2E test to the release/13.4 test harness, which does not have CliE2ETestHelpers.StartRun. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: David Negstad <David.Negstad@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: danegsta <50252651+danegsta@users.noreply.github.com>
* Add TerminalRun IAsyncDisposable for consistent CLI E2E diagnostics capture (#17576) * Fix CLI Ctrl+C/SIGTERM shutdown: responsive cancellation and double-signal bug (#17588) * Fix CLI Ctrl+C shutdown taking too long during AppHost startup - Make ConsoleCancellationManager.Cancel() non-blocking so Ctrl+C handler returns immediately - Pass cancellation token through to WaitAsync in CancelAppHostStartupAsync so Ctrl+C exits promptly instead of waiting for the full 5s timeout - Support second Ctrl+C for immediate force exit (Environment.Exit) - Add logging support to ConsoleCancellationManager via SetLogger() - Add comprehensive unit tests for ConsoleCancellationManager - Add integration test for RunCommand cancellation during startup timeout Fixes #17569 * Fix review comments: volatile logger, accurate comments, clearer warning * Clean up * Use WaitForSuccessPromptFailFastAsync in CLI E2E tests Replace WaitForSuccessPromptAsync with WaitForSuccessPromptFailFastAsync across all CLI E2E tests. The fail-fast variant detects error prompts immediately and throws instead of hanging for up to 500s waiting for a success prompt that will never arrive. This prevents 10+ minute CI timeouts when a command fails with a non-zero exit code. * Fix double-signal bug and consolidate test helpers - Fix ConsoleCancellationManager double-signal bug: move Console.CancelKeyPress to else branch so it only registers on platforms without PosixSignalRegistration. Previously both handlers fired for the same SIGINT, causing immediate force-kill. - Add SIGQUIT/Ctrl+Break registration for Windows parity. - Remove old WaitForSuccessPromptAsync (no fail-fast) and rename WaitForSuccessPromptFailFastAsync to WaitForSuccessPromptAsync. - Remove duplicate RunCommandFailFastAsync (identical to RunCommandAsync). * Fix stale comment and restrict SIGQUIT to Windows only * Remove unused legacy builder methods and update E2E skill docs * Don't force when debugging * More logging
* Improve dashboard summary log formatting - Indent URL lines with 6 spaces and '- ' prefix so they align with the standard log output indentation - Move container warning to a separate log message with clearer text - Update tests to match new format * Update FrontendBrowserTokenAuthTests to assert new standalone container log message Co-authored-by: JamesNK <303201+JamesNK@users.noreply.github.com> --------- Co-authored-by: James Newton-King <james@newtonking.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: JamesNK <303201+JamesNK@users.noreply.github.com>
Co-authored-by: IEvangelist <7679720+IEvangelist@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Update Foundry hosted agent builder APIs
* Update Foundry hosted agent API surface
* Update Foundry hosted agent tests
* Remove commented-out health check URLs from hosted agent configuration
* Adjust Foundry hosted agent behavior
Consolidate AsHostedAgent usage, update Foundry icons and command rendering, and refresh playgrounds, samples, and tests.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix Foundry hosted-agent run and command icon behavior
Conditionally require/provision Foundry project ACR only for hosted-agent publish or explicit registry override, add regression tests for run/publish paths, and align PromptAgent Send Message icon with ChatSparkle.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Avoid default Foundry ACR in run mode
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Cache JsonSerializerOptions in HostedAgentResourceBuilderExtensions
Avoid allocating a fresh JsonSerializerOptions per Send Message command
invocation, which also defeats JsonSerializer's per-options metadata cache.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Make project positional and add HostedAgentOptions for polyglot
- AsHostedAgent(project, HostedAgentOptions?) is now the polyglot-exported overload
- Action<HostedAgentConfiguration> overload kept as .NET-only for advanced use
- HostedAgentOptions exposes Description, Cpu, Memory, Metadata, EnvironmentVariables
- Polyglot users now get .asHostedAgent(project, { ... }) instead of
.asHostedAgent({ project, configure: async cfg => ... })
- Updated TypeScript, Go, and Java polyglot apphost fixtures to new shape
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Make HostedAgentOptions and its overload internal (ATS-only)
HostedAgentOptions exists only to give polyglot SDK generators a clean
options-bag shape. .NET callers should keep using the richer
Action<HostedAgentConfiguration> overload, so both the DTO and the
overload that takes it are now internal.
To avoid C# overload ambiguity between '.AsHostedAgent(project)' (which
should bind to the public Action overload) and the internal options
overload, the internal method is renamed to AsHostedAgentForExport. The
polyglot-facing name stays as 'asHostedAgent' via [AspireExport(MethodName)].
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Clean up polyglot JSDoc for asHostedAgent
Remove <remarks> blocks from HostedAgentOptions and AsHostedAgentForExport
that were flowing into the generated TypeScript/Go/Java SDK JSDoc and
including C#-only implementation notes plus broken <see cref> renderings
(e.g. \`AsHostedAgent\`\`1). The polyglot codegen concatenates
<summary>+<remarks>, so any C#-implementation chatter pollutes the
generated SDK docs. Replace with plain // source comments that stay in C#.
Also fix the TypeScript polyglot fixture to match the actual generated
signature: when an extension method takes a single optional DTO parameter,
the codegen wraps it in an options bag, so the call shape is
asHostedAgent(project, { options: { ... } }) — not the flat
asHostedAgent(project, { ... }) shape.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix Foundry hosted agent options DTO generation
Mark HostedAgentOptions as an ATS DTO so polyglot SDK generation treats it as a JSON value object instead of a live exported handle. Update the TypeScript validation fixture to use the generated flat options shape.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix Foundry polyglot hosted agent fixtures
Update Go and Java Foundry polyglot AppHosts to match the generated HostedAgentOptions DTO and AsHostedAgent optional-parameter shapes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix Foundry Java hosted agent fixture
Use Double literals for hosted agent CPU and memory options so the generated Java DTO setters compile.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix Foundry API baselines
Regenerate the Foundry ATS and API baselines so the release branch backport exposes the hosted-agent options export and drops the stale withComputeEnvironmentExecutable surface.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: tommasodotnet <tstocchi@microsoft.com>
Co-authored-by: Maddy Montaquila <maleger@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Treat Win32Exception while inspecting process metadata as a stale or non-targetable process so stop monitoring does not fail when an AppHost exits during shutdown. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* [release/13.4] Mark Aspire.Hosting.Blazor as preview The 13.4.0 stable build ships gateway scripts only under buildTransitive/net8.0/Scripts/, while the TypeScript AppHost loader resolves Gateway.cs from lib/net8.0/Scripts/. This breaks the TS polyglot AppHost flow out of the box. Mark the package as preview-shaped via SuppressFinalPackageVersion so consumers don't pick it up as stable until the packaging/loader issue is fully addressed. Fixes #17685 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update src/Aspire.Hosting.Blazor/Aspire.Hosting.Blazor.csproj --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: James Newton-King <james@newtonking.com>
…7704) * Reference Foundry project from hosted agent target * Strengthen hosted agent Foundry reference test Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix Foundry hosted agent CI tests Seed Foundry project outputs in tests that directly invoke hosted-agent environment resolution, matching the provisioning state available during deployment. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Document Foundry project output seeding Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: tommasodotnet <tstocchi@microsoft.com> Co-authored-by: David Fowler <davidfowl@gmail.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix five `aspire ls` bugs from #17620 (L1–L5) Fixes #17615, #17620, #17621, #17624, #17626. - L1 (#17615): Remove the eager-migration block in ConfigurationHelper.RegisterSettingsFiles. Read commands like `aspire ls` no longer silently materialize an aspire.config.json next to a user's legacy .aspire/settings.json. Migration now happens lazily/explicitly via the existing write paths. - L2 (#17620): Drop the `silent` parameter from ProjectLocator.GetAppHostProjectFileFromSettingsAsync so the legacy branch unconditionally surfaces the migration warning, and surface the actual user-authored `.aspire/settings.json` path in the warning text rather than the auto-created `aspire.config.json` path. - L3 (#17621): Remove the dead post-emission `appHosts.Sort()` in LsCommand.FindAppHostsWithJsonStreamAsync (--stream emits candidates as they are discovered, so the sort had no effect on already-emitted output). Update the --stream option description and docs/specs/cli-output-formats.md to declare the arrival-ordered contract. - L4 (#17624): Add an IsValidConfiguredAppHostPath helper in ProjectLocator that rejects `\0` and Path.GetInvalidPathChars() before the path is passed to Path.IsPathRooted / Path.Combine. Wired into both the modern `aspire.config.json` (`appHost.path`) branch and the legacy `.aspire/settings.json` (`appHostPath`) branch. Validation is intentionally at the consumption point rather than in AspireConfigFile.Load, which has 12+ unrelated callers. Adds a new ConfiguredAppHostPathHasInvalidCharacters resource string and refreshes the xlf set via UpdateXlf. - L5 (#17626): Add PathNormalizer.ResolveSymlinks in src/Shared, a recursive segment-walker that canonicalizes intermediate symlinks (Directory.ResolveLinkTarget only reads exactly the path it is given, and returns the link target as stored on disk — so a single call on /tmp/x/y.cs does not unwrap /tmp -> /private/tmp, and following a link whose stored target is /var/.../app keeps the un-canonical /var prefix). The recursion has a hard depth limit of 40 and falls back to the un-resolved input on broken or circular links. Use it in AddSettingsAppHostCandidateAsync as a comparison key only — the surfaced AppHostProjectCandidate keeps its original FileInfo so the displayed path matches what the user authored in settings. Tests: 158 of 160 targeted tests pass (2 Windows-only skipped on macOS). New tests cover L1 (no migration on read), L2 (legacy warning references settings.json), L3 (arrival-order under --stream), L4 (NUL byte in modern and legacy branches), L5 (symlink dedupe via a node_modules-hosted link the discovery walk excludes), plus 5 unit tests on PathNormalizer.ResolveSymlinks itself. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address Aspire CLI PR feedback Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use constants for AppHost config keys Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Deduplicate AppHost config casing on macOS Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Handle duplicate ATS capabilities Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Revert duplicate ATS compatibility fix PR #17671 owns the Foundry ATS baseline update; this branch should only contain the AppHost and CLI fixes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: adamint <adamratzman1@gmail.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Adam Ratzman <adam@adamratzman.com>
…fuzzy auto-pick (#17724, #17725) (#17728) * fix(cli): restore implicit-channel discovery + guard non-interactive fuzzy auto-pick (#17724, #17725) ## #17725 — Prerelease-only integrations invisible on polyglot apphosts `IntegrationPackageSearchService.GetIntegrationPackagesWithChannelsAsync` used to narrow the channel set to whatever `configuredChannel` resolved to (from `aspire.config.json`'s `"channel"` field). For a polyglot apphost pinned to a `Quality.Stable` channel this dropped the implicit channel from discovery, so prerelease-only packages (e.g. `Aspire.Hosting.Foundry`, `Aspire.Hosting.Kubernetes`) became invisible. This narrowing was born 2026-01-13 in PR #13705 with a C#-only short-circuit in `GetConfiguredChannel`. It stayed dormant until PR #17452 (2026-05-26) started writing `"channel": "<identity>"` into the scaffolded `aspire.config.json` during `aspire init`. After #17452 every newly-init'd polyglot apphost in 13.4 had the field populated and tripped the narrowing. 13.3.5 users had no `"channel"` persisted, so the bug was invisible there — this is a 13.4 regression introduced by the activator, not the narrowing code itself. The fix removes the narrowing. The configured channel is still forwarded to `PackagingService.GetChannelsAsync` as `requestedChannelName` so out-of-tree apphost staging-channel synthesis keeps working — it just no longer constrains the post-retrieval filter pipeline. The filter pipeline is now byte-identical for C# and polyglot apphosts. ## #17724 — `aspire add <fuzzy> --non-interactive` silently picks first match `AddCommand` falls back to fuzzy search when there's no exact match. The fuzzy candidates were passed to `GetPackageByInteractiveFlow`, which in non-interactive mode auto-selected `distinctPackages.First()` and silently installed it. Combined with #17725, `aspire add kube --non-interactive` on a TS apphost silently installed `Aspire.Hosting.Azure`. The existing guard at AddCommand.cs:181 already refused this when `--version` was supplied. This change generalizes the guard: any non-interactive invocation without an exact match now fails with a new `NonInteractiveRequiresExactPackageMatch` resource message. Fuzzy fallback remains available in interactive mode. ## Tests - IntegrationSearchCommandFormatJsonWithTypeScriptAppHostPinnedToChannelAlsoSearchesImplicitChannel - IntegrationSearchCommandFormatJsonWithTypeScriptAppHostPinnedToStagingChannelAlsoSearchesImplicitChannel - IntegrationSearchCommandFormatJsonWithTypeScriptAppHostPinnedToStableChannelStillSurfacesPrereleaseOnlyPackages (primary regression test for #17725 — Foundry case) - IntegrationSearchCommandTypeScriptAppHostProducesSameResultRegardlessOfPersistedChannel (durable structural guard: parameterized over with/without `"channel"` in aspire.config.json; asserts the result is identical, proving the narrowing is gone) - AddCommand_NonInteractive_NoExactMatchWithoutVersion_FailsInsteadOfFuzzyAutoPick_Regression17724 (primary regression test for #17724) - AddCommand_NonInteractive_ExactMatchWithoutVersion_StillSucceeds (companion guard: exact-match happy path keeps working non-interactive) Two pre-existing AddCommandFuzzySearchTests were testing the buggy auto-pick behavior implicitly (they used `add postgre` / typo input under the default non-interactive test host). Updated to opt into an interactive host environment to assert the documented interactive-fuzzy-prompt behavior. Full Aspire.Cli.Tests suite: 3900 passed, 21 skipped, 0 failed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(cli): restore explicit-channel inclusion when polyglot apphost pins a channel Address review feedback on PR #17728. The first revision dropped too much. Removing the `|| !string.IsNullOrEmpty(configuredChannel)` half of the gate caused a NEW regression: a TS apphost pinned to "daily" / "staging" / a custom channel now searched only the implicit channel, losing access to packages that live on the pinned feed. Production change in IntegrationPackageSearchService: channels = hasHives || !string.IsNullOrEmpty(configuredChannel) ? allChannels : allChannels.Where(c => c.Type is PackageChannelType.Implicit); This preserves the #17725 fix (narrowing is still gone, so the implicit channel always participates and prerelease-only packages like Foundry remain discoverable when pinned to a Stable-quality channel) while keeping pinned explicit channels in the search. Tests strengthened with per-channel invocation counters so that "channel X was searched" is asserted directly rather than inferred from the dedupe outcome. The Theory test is reframed: both arms agree on the user-visible preferred result (Redis 1.0.0, implicit wins), but the with-channel arm additionally hits the daily channel and the without-channel arm does not. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test(cli): pin staging-shipping behavior for #17724 + #17725 Adds proof-by-test that the IPSS gate behaves identically when the CLI is shipped as staging (`IdentityChannel == "staging"`) as it does today with the PR dogfood build (where the channel name was `pr-17728`): 1. Adds `[InlineData("\"staging\"", true)]` to the existing theory `…PersistedChannelExpandsDiscoveryWithoutChangingPreferredResult`. This proves the IPSS gate (`hasHives || !string.IsNullOrEmpty( configuredChannel)`) is channel-name-opaque — `"staging"` and `"daily"` produce identical gate behavior. 2. Adds a new fact `IntegrationSearchCommandStagingStampedCliWithPinnedStagingApphost QueriesBothImplicitAndStagingChannelsAndSurfacesPrereleaseOnlyPackages` that exercises the exact shipping shape: * Real PackagingService (not the fake TestPackagingService) — so the real staging-channel synthesis path is exercised. * `IdentityChannel = Staging` — the CLI binary is stamped as the staging release identity, which is how shipped staging CLIs run. * `aspire.config.json` pins `"channel": "staging"` — which is what `aspire new` writes into polyglot apphosts on a staging-stamped CLI (see CliTemplateFactory.TypeScriptStarterTemplate). * No PR hives — this is a real installed CLI, not a dogfood build. Asserts both invariants: (i) Total cache call count >= 2, proving both implicit AND staging channels were queried. Pre-fix narrowing would have produced exactly 1 call. (ii) A prerelease-only package returned only when prerelease=true surfaces to the user — proving the #17725 fix holds on a real staging release, not just on a PR build. Together with the existing `…UsesConfiguredStagingChannelWithRealPackagingService` (apphost-pin triggers staging synthesis under Stable identity) and `…UnpinnedAppHostUsesImplicitChannelUnderStagingCli` (staging identity without pin correctly falls back to implicit-only), the staging quadrant is now fully covered. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix interactive fuzzy add confirmation Prompt before adding a single fuzzy or no-match fallback candidate in interactive aspire add flows, while preserving exact-match auto-selection. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: David Fowler <davidfowl@gmail.com>
* API review fixes for 13.4 (PR #17700) Addresses several issues found during API surface review: 1. Rename NetworkID -> NetworkId (and networkID -> networkId) on AllocatedEndpoint, EndpointAnnotation, EndpointReference, EndpointReferenceAnnotation, NetworkEndpointSnapshot, NetworkEndpointSnapshotList, and related methods/parameters. 2. Add [Experimental("ASPIREAZURE003")] to AzureRoleAssignmentResource. 3. Change EndpointReferenceAnnotation.EndpointNames from HashSet<string> to ISet<string> (backing field stays HashSet). 4. Add 'sealed' to new public resource classes that are not subclassed in the repo: KubernetesHelmChartResource, BlazorWasmAppResource, BunAppResource, NextJsAppResource, ViteAppResource, AzureNatGatewayResource, AzureNetworkSecurityGroupResource, AzureNetworkSecurityPerimeterResource, AzurePrivateEndpointResource, AzurePublicIPAddressResource, AzureSubnetResource, AzureVirtualNetworkResource. (GoAppResource and NodeAppResource left non-sealed because they are used as generic type constraints in the same assembly.) 5. Disambiguate WithHiddenOnCompletion overloads by removing the '= 0' default from the int overload, so calls with no argument resolve to the params overload. api/*.cs and api/*.ats.txt are intentionally not updated here - the API surface PR will regenerate them. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Revert breaking API changes; bump baseline to 13.3.5 Reverts the subset of API changes from the previous commit that would be binary-breaking against 13.3.5, and bumps PackageValidationBaselineVersion from 13.2.2 to 13.3.5 so pack validation runs against the latest shipped release. Reverts (binary-breaking against 13.3.5): - AllocatedEndpoint.NetworkID (kept ctor param 'networkId' - not breaking) - EndpointAnnotation.DefaultNetworkID (kept ctor param 'networkId') - EndpointReference.ContextNetworkID (kept ctor param 'contextNetworkId') - NetworkEndpointSnapshot.NetworkID record positional param - Removed 'sealed' from 9 shipped resource classes: - NextJsAppResource, ViteAppResource - AzureNatGatewayResource, AzureNetworkSecurityGroupResource, AzureNetworkSecurityPerimeterResource, AzurePrivateEndpointResource, AzurePublicIPAddressResource, AzureSubnetResource, AzureVirtualNetworkResource Kept (not binary-breaking): - All constructor/method parameter renames (networkID->networkId, etc.) - EndpointReferenceAnnotation.ContextNetworkId (new in 13.4) - EndpointNames type change (HashSet -> ISet) - WithHiddenOnCompletion overload disambiguation - [Experimental("ASPIREAZURE003")] on AzureRoleAssignmentResource - 'sealed' on KubernetesHelmChartResource, BlazorWasmAppResource, BunAppResource (new in 13.4) Package validation: - Bumped PackageValidationBaselineVersion 13.2.2 -> 13.3.5 - Regenerated CompatibilitySuppressions.xml in 4 projects: most legacy entries against 13.2.2 are no longer needed because those APIs already shipped in 13.3.x. The remaining suppression is PublishAsNpmScript in Aspire.Hosting.JavaScript (documented removal from PR #17382). --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ed with dynamic ports (#17731) When users set DisableDashboard = false on DistributedApplicationTestingBuilder, the TransportOptionsValidator rejected the HTTP URLs that the testing builder defaults (http://localhost:8080, http://localhost:4317) because ASPIRE_ALLOW_UNSECURED_TRANSPORT was not set. Fix: Set AllowUnsecuredTransport = true by default in PreConfigureBuilderOptions, since all URLs are already defaulted to HTTP. Add a regression test that enables the dashboard and verifies it becomes healthy. Fixes #17622 Co-authored-by: James Newton-King <james@newtonking.com>
* Add Foundry hosted agent protocol selection Support configuring Foundry hosted agent protocols for publish output and local run-mode dashboard commands, including TypeScript AppHost coverage for the exported DTO shape. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address Foundry hosted agent review feedback Improve hosted agent protocol validation parameter names and add run-mode context when configuration callbacks fail during protocol inference. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Sync Foundry hosted agent endpoint protocols Update hosted agent deployment to patch the Foundry agent endpoint protocols after creating a hosted-agent version, so endpoint routing matches the configured container protocol versions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Skip Foundry reserved hosted agent env vars Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…pe (#17743) * Route staging-identity CLI to its darc feed regardless of version shape The synthesized `staging` package channel derived its feed from the CLI build's version shape: a prerelease-shaped staging build (e.g. 13.4.0-preview.1.26280.6) routed Aspire.* to the shared dnceng/dotnet9 daily feed instead of its SHA-specific darc-pub-microsoft-aspire-<commit> feed. C# apphosts masked this because the darc feed is baked into their nuget.config, but polyglot (TypeScript) apphosts resolve solely through the channel's feed, so `aspire add <pkg>` offered the wrong versions. Decouple feed provenance (identity) from version filtering (quality): - Add `ShouldUseSharedStagingFeed(...)`: a staging-identity CLI always uses its own darc feed, any version shape. Override feeds and non-staging identities keep the prior quality-based routing. - Add an injectable `cliInformationalVersionProvider` constructor seam so the derived darc feed URL is deterministic and assertable in tests. - Correct the comments that incorrectly claimed darc feeds only exist for stable-shaped builds. Add tests covering prerelease-shaped staging -> darc, stable-shaped staging -> darc, and override-wins. The prerelease repro fails before the fix (resolves dotnet9) and passes after (resolves darc). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Strengthen staging feed-routing tests and warn on underivable feed Adds a decision-table theory across PR/daily/staging/stable channel configurations, drops the override-feed crutch from the staging-identity tests so they assert the real darc feed via an injected version seam, adds coverage for the underivable-feed warning path, and adds symmetry asserts for the stable-shaped staging case. Also logs a one-time warning in CreateStagingChannel when a staging channel is permitted but no staging feed URL can be derived, so the channel is omitted visibly instead of silently. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add diagnostic overrides to validate staging feed routing locally Adds two PackagingService-scoped diagnostic config overrides so a locally built CLI (baked identity 'local', unstamped version) can simulate a staging build and validate end-to-end that 'aspire add' resolves Aspire.* from the correct SHA-specific darc-pub-microsoft-aspire-<sha> feed: - overrideCliIdentityChannel: forces the identity used for staging-feed routing decisions only (validated via IdentityChannelReader.IsValidChannel; invalid values ignored). Does not change the global identity used for hive/packages-directory lookups, keeping blast radius limited. - overrideCliInformationalVersion: forces the version that both the SHA derivation and the stable-shape/quality predicate read. All staging-feed decision points now route through GetEffectiveIdentityChannel. A one-time warning is emitted whenever either override is active. Adds docs/cli-staging-validation.md with the local-validation recipe and nine PackagingServiceTests covering the override permutations. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add debug-staging/debug-stable scripts to simulate release-branch feed routing Add eng/scripts/debug-staging.{sh,ps1} and debug-stable.{sh,ps1} (plus the shared debug-aspire-channel core) that make an easy-to-get build (an installed PR build or a local build) resolve Aspire.* packages exactly like an official staging or stable release-branch build, so the feed-routing fix can be validated end-to-end. Each script targets identity 'staging' and the SHA-specific darc-pub-microsoft-aspire-<sha8> feed, differing only in version shape/quality (staging => prerelease/Both, #17744; stable => stable/Stable, #17527). Modes: - default: one-shot 'aspire add --debug' that asserts the darc feed resolves. - --print-env / -PrintEnv: emit export/$env lines to apply to the current shell. - --shell / -Shell: interactive subshell with overrides applied and the target CLI first on PATH, for a full 'aspire new'/'add'/run flow; overrides vanish on exit. Extend docs/cli-staging-validation.md with the helper-script usage, the interactive PR-build recipe, and a validation matrix; link it from docs/contributing.md. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Isolate NuGet package cache in debug-channel --shell mode When dropping into the interactive subshell (--shell / -Shell), point NUGET_PACKAGES at an isolated, per-sha directory so packages restored from the simulated staging darc feed can never contaminate the developer's real global package cache. Also commit the staging-override NOTE clarifying the overrides route to but do not create a feed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix staging-identity update test for identity-driven darc feed routing The staging identity now always routes to its build's SHA-specific darc-pub-microsoft-aspire-<sha> feed regardless of version shape, so the feed must be derivable from the CLI's +<commit> informational version. The test host assembly has no commit metadata, so the staging channel could not be synthesized and the test regressed. Stamp a staging-shaped informational version via the overrideCliInformationalVersion config so the derivation matches a real staging build. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ted agents (#17756) * Resolve cross-compute-environment endpoint references to Foundry hosted agents Fixes #17749. When a resource deployed to App Service, Azure Container Apps, or Kubernetes used WithReference() to reference a Foundry hosted agent, publishing failed because the publisher resolved the endpoint against its own local endpoint map, which does not contain the agent (deployed to the Foundry project compute environment). Introduce a shared ComputeEnvironmentEndpointResolver that, when an endpoint's owning resource is deployed to a different compute environment than the current publisher, delegates resolution to that owning environment's GetEndpointPropertyExpression. The three compute-environment publishers now call it in both the EndpointReference and EndpointReferenceExpression branches. Azure Front Door and the Foundry hosted-agent resolver are refactored onto the same shared lookup. AzureCognitiveServicesProjectResource gets a GetEndpointPropertyExpression override because the agent address is already a full https URL; the default scheme://host composition would produce a malformed double-scheme value. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add branch tests for ComputeEnvironmentEndpointResolver and correct misleading comment Add direct unit tests covering each branch of TryGetCrossEnvironmentEndpointExpression: cross-environment delegation, same-environment deployment target, WithComputeEnvironment binding backstop, no-compute-environment, bound multi-target (no throw), and unbound multi-target (throws). Correct the comment on the fast-path loop which incorrectly claimed it never throws on multi-target resources. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove redundant fast-path loop from ComputeEnvironmentEndpointResolver The first foreach loop using GetDeploymentTargetAnnotation(current) was redundant with TryGetEffectiveComputeEnvironment + the ReferenceEquals backstop for all well-formed inputs, and did not provide multi-target throw-safety. Remove it and keep the simpler resolve-then- compare flow. All six branch tests continue to pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Drop params and move out parameter last in cross-env endpoint resolver Replace the params IComputeEnvironmentResource?[] with an explicit IReadOnlyList parameter placed before the out, so the out parameter comes last per convention. Kubernetes still passes two current environments (its environment plus OwningComputeEnvironment) via a collection expression; ACA and AppService pass a single-element list. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add EndpointReference overload for cross-env endpoint resolver Add an overload taking EndpointReference that uses ep.Property(EndpointProperty.Url) internally, so the three EndpointReference call sites (ACA, AppService, Kubernetes) pass the endpoint directly instead of repeating the .Property(Url) projection. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use hosted-agent deployment name in cross-env Foundry agent URL Hosted-agent deployment creates the Foundry agent version using the wrapper AzureHostedAgentResource.Name (e.g. "agent-ha" for a target named "agent"). The published cross-environment endpoint path was built from the bare resource name, producing /agents/agent which does not match the deployed /agents/agent-ha. Resolve the hosted-agent deployment target and use its name when present, falling back to the resource name for non-hosted agents. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Auto-wire Azure AI User role for hosted-agent consumers When a compute resource references a Foundry hosted agent's node app via WithReference, automatically grant the consumer the Azure AI User role on the owning Foundry account and provision a managed identity, removing the two manual post-deploy `az role assignment create` steps. Introduces a public, experimental ReferenceRoleAssignmentAnnotation in Aspire.Hosting.Azure. A resource that "fronts" an Azure resource (without being an IAzureResource itself) carries this annotation; AzureResourcePreparer folds its (Target, Roles) into the same role-assignment path used for direct Azure references. Foundry's AsHostedAgent stamps the annotation on the agent's node app granting only the least-privilege Azure AI User role; account defaults and explicit WithRoleAssignments suppression remain owned by the preparer and are not reintroduced. GetAllRoleAssignments now dedupes roles per target to avoid colliding bicep role-assignment identifiers. Adds preparer end-to-end tests (suppression preserved, defaults preserved, dedup) and Foundry stamp tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Regenerate cross-env Foundry snapshots for RBAC auto-wiring The cross-compute-environment Foundry hosted-agent snapshots were committed before the RBAC auto-wiring change and never regenerated. With the consumer now receiving a managed identity (web-identity) plus AZURE_CLIENT_ID and AZURE_TOKEN_CREDENTIALS env vars, the generated bicep/json changed. CI failed because the verified baselines were stale; local runs masked it because Verify auto-accepts on developer machines. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 17804Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 17804" |
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Member
|
Closing in favor of #17817, which is the same merge re-opened from a non-protected branch so conflict resolutions and post-merge cleanups (revert |
pull Bot
pushed a commit
to tooniez/aspire
that referenced
this pull request
Jun 2, 2026
Brings 43 release-branch commits forward onto main now that 13.4.0 has shipped. This PR replaces the original automated merge (microsoft#17804) which had to be closed so that conflict resolution and post-merge cleanups could be made on a non-protected branch. Conflict resolution summary (33 files): * Equivalent backports (took main's commit identity): ChannelUpdateWorkflowTests, LoggingHelpersTests, the four extension test files, AspireEditorCommandProvider, appHostDiscovery. * Release-only forwards (preserved): microsoft#17732 / microsoft#17756 Foundry hosted-agent protocol selection and cross-compute-environment endpoint references, microsoft#17573 stabilize PrebuiltAppHostServer staging globalPackagesFolder path, microsoft#17743 staging-identity CLI darc feed routing. * Main-only forwards (preserved): microsoft#17506 Show discovered AppHosts in Aspire pane, microsoft#17547 Localize Aspire skills metadata errors, microsoft#17801 VS Code v1.12.0, microsoft#17297 Aspire CLI npm package release integration, microsoft#17576 TerminalRun IAsyncDisposable, microsoft#17721 / microsoft#17723 VS Code telemetry, microsoft#17671 ATS baseline fix (re-applied manually on top of Foundry source taken from release). * Hybrid (manually spliced): docs/contributing.md - kept main's restructured layout and inserted release's staging-validation paragraph; HostedAgentBuilder- Extension - took release base then re-applied microsoft#17671 asHostedAgent rename; UpdateCommandTests - took main and injected microsoft#17743's OverrideCliInformationalVersionConfigKey block. Post-merge cleanups included in this PR: * eng/Versions.props: revert StabilizePackageVersion to false (was flipped to true on release/13.4 by microsoft#17520 for shipping 13.4.0; main must stay in preview mode). * .github/workflows/generate-api-diffs.yml: retarget back to main (was pointed at release/13.4 by microsoft#17696 release prep). * .github/workflows/backmerge-release.yml: update from release/13.3 to release/13.4 (was stale - missed the 13.4 release-time bump). * .github/workflows/milestone-assignment.yml: audited - already correct (main -> 13.5, release/13.4 -> 13.4.x); no change. This merge commit must be preserved - do not squash on merge. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR merges the
release/13.4branch back tomainafter the v13.4.0 release.Checklist
Created automatically by the release workflow.