Skip to content

Make ResourceUrlAnnotation.DisplayOrder a non-obsolete property - #20637

Merged
Eric Erhardt (eerhardt) merged 2 commits into
mainfrom
jamesnk/resource-url-display-order-property
Oct 1, 2026
Merged

Eric Erhardt (eerhardt) merged 2 commits into
mainfrom
jamesnk/resource-url-display-order-property

Conversation

@JamesNK

Copy link
Copy Markdown
Member

Description

ResourceUrlAnnotation.DisplayOrder was exposed as an obsolete field with a promise to replace it with a property. This change makes it a nullable read/write property and removes the obsolete attribute, so consumers can configure URL ordering without obsolete warnings. Higher values still sort URLs higher in the dashboard.

  • Remove the obsolete remarks and warning suppressions from hosting, integration, and test call sites.
  • Preserve display order when copying an annotation to associate it with an endpoint, with coverage for null, negative, zero, and positive values.
  • Update the TypeScript and Go generation snapshots to include the newly exposed DTO property.

No new dependencies are required.

User-facing usage

For a resource with a test endpoint:

resource.WithUrlForEndpoint("test", url =>
{
    url.DisplayOrder = 1000;
});

The generated TypeScript DTO now includes displayOrder?: number | null, and the generated Go DTO includes DisplayOrder *float64.

Breaking changes

Replacing a public field with a property is a binary compatibility change for consumers compiled against the old field. Rebuild those consumers against the updated package. Normal C# reads, assignments, and object initializers retain the same syntax; reflection-based consumers must look up a property instead of a field.

Validation

The following commands passed locally on Windows:

  • .\restore.cmd - passed.
  • dotnet test --project .\tests\Aspire.Hosting.Tests\Aspire.Hosting.Tests.csproj --no-launch-profile -p:SkipNativeBuild=true -- --filter-method '*.WithEndpointPreservesDisplayOrder' --filter-not-trait 'quarantined=true' --filter-not-trait 'outerloop=true' - passed, 4 cases.
  • dotnet test --project .\tests\Aspire.Hosting.CodeGeneration.TypeScript.Tests\Aspire.Hosting.CodeGeneration.TypeScript.Tests.csproj --no-build --no-launch-profile -- --filter-method '*.TwoPassScanning_GeneratesWithEnvironmentOnTestRedisBuilder' --filter-not-trait 'quarantined=true' --filter-not-trait 'outerloop=true' - passed, 1 test after reviewing the regenerated snapshot.
  • dotnet test --project .\tests\Aspire.Hosting.CodeGeneration.Go.Tests\Aspire.Hosting.CodeGeneration.Go.Tests.csproj --no-build --no-launch-profile -- --filter-method '*.TwoPassScanning_GeneratesWithEnvironmentOnTestRedisBuilder' --filter-not-trait 'quarantined=true' --filter-not-trait 'outerloop=true' - passed, 1 test after reviewing the regenerated snapshot.
  • git --no-pager diff --check - passed.

The code-generation projects were built by their initial test runs before the --no-build verification runs. A full repository build and full test suite were not run.

Fixes # (issue)

Checklist

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

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

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 20637

Or

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

@aspire-repo-bot
aspire-repo-bot Bot requested a balanced review from Copilot October 1, 2026 00:28
@github-actions github-actions Bot added the area-app-model Issues pertaining to the APIs in Aspire.Hosting, e.g. DistributedApplication label Oct 1, 2026
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Java, Python, and Rust generated snapshots must also be regenerated for the exported DTO property.

Review effort: Balanced
Findings: 1 High severity

Open (1)
What changed in this PR

Converts ResourceUrlAnnotation.DisplayOrder from an obsolete field to a public property while preserving URL ordering behavior.

Changes:

  • Replaces the field and removes obsolete-warning suppressions.
  • Verifies endpoint association preserves display order.
  • Updates TypeScript and Go DTO snapshots, but omits Java, Python, and Rust snapshots.
File Description
tests/​Aspire.Hosting.Tests/​WithUrlsTests.cs Tests display-order preservation.
tests/​Aspire.Hosting.CodeGeneration.TypeScript.Tests/​Snapshots/​TwoPassScanningGeneratedAspire.verified.ts Adds the TypeScript property.
tests/​Aspire.Hosting.CodeGeneration.Go.Tests/​Snapshots/​TwoPassScanningGeneratedAspire.verified.go Adds the Go property.
src/​Aspire.Hosting/​Orchestrator/​ApplicationOrchestrator.cs Removes obsolete suppression.
src/​Aspire.Hosting/​Dcp/​ResourceSnapshotBuilder.cs Removes obsolete suppressions.
src/​Aspire.Hosting/​Dashboard/​DashboardEventHandlers.cs Removes obsolete suppression.
src/​Aspire.Hosting/​ApplicationModel/​ResourceUrlAnnotation.cs Converts the field into a property.
src/​Aspire.Hosting.Redis/​RedisBuilderExtensions.cs Removes obsolete suppression.
src/​Aspire.Hosting.RabbitMQ/​RabbitMQBuilderExtensions.cs Removes obsolete suppression.
src/​Aspire.Hosting.Qdrant/​QdrantBuilderExtensions.cs Removes obsolete suppression.
src/​Aspire.Hosting.PostgreSQL/​PostgresBuilderExtensions.cs Removes obsolete suppression.
src/​Aspire.Hosting.MySql/​MySqlBuilderExtensions.cs Removes obsolete suppression.
src/​Aspire.Hosting.MongoDB/​MongoDBBuilderExtensions.cs Removes obsolete suppression.
src/​Aspire.Hosting.Milvus/​MilvusBuilderExtensions.cs Removes obsolete suppression.
src/​Aspire.Hosting.Kafka/​KafkaBuilderExtensions.cs Removes obsolete suppression.
src/​Aspire.Hosting.Azure.Functions/​DurableTask/​DurableTaskResourceExtensions.cs Removes obsolete suppression.
src/​Aspire.Hosting.Azure.CosmosDB/​AzureCosmosDBExtensions.cs Removes obsolete suppression.

Comment thread src/Aspire.Hosting/ApplicationModel/ResourceUrlAnnotation.cs
@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

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

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

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Tests selector

50 / 97 PR test projects · 4 PR jobs, from 20 changed files.

Selected PR test projects (50 / 97)

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

Selected PR jobs (4)

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


How these were chosen — grouped by what changed

⚠️ 25 of the 50 selected test projects come from a single change — src/Aspire.Hosting/ApplicationModel/ResourceUrlAnnotation.cs.

🔧 src/Aspire.Hosting/ApplicationModel/ResourceUrlAnnotation.cs (changed source)
→ 25 via the project graph

show 25

Aspire.Hosting.Analyzers.Tests (2 hops), Aspire.Hosting.Azure.Kusto.Tests (2 hops), Aspire.Hosting.Azure.Provisioning.Tests (3 hops), Aspire.Hosting.Browsers.Tests (2 hops), Aspire.Hosting.Containers.Tests (2 hops), Aspire.Hosting.DevTunnels.Tests (2 hops), Aspire.Hosting.DotnetTool.Tests (2 hops), Aspire.Hosting.Garnet.Tests (2 hops), Aspire.Hosting.Go.Tests (2 hops), Aspire.Hosting.Java.Tests (2 hops), Aspire.Hosting.JavaScript.Tests (2 hops), Aspire.Hosting.Keycloak.Tests (2 hops), Aspire.Hosting.Maui.Tests, Aspire.Hosting.Nats.Tests (2 hops), Aspire.Hosting.OpenAI.Tests (2 hops), Aspire.Hosting.Oracle.Tests (2 hops), Aspire.Hosting.Orleans.Tests (2 hops), Aspire.Hosting.Python.Tests (2 hops), Aspire.Hosting.RemoteHost.Tests, Aspire.Hosting.Rust.Tests (2 hops), Aspire.Hosting.Seq.Tests (2 hops), Aspire.Hosting.SqlServer.Tests (2 hops), Aspire.Hosting.Valkey.Tests (2 hops), Aspire.Hosting.Yarp.Tests (2 hops), Aspire.Playground.Tests

🔧 src/Aspire.Hosting.PostgreSQL/PostgresBuilderExtensions.cs (changed source)
→ 1 directly: Aspire.Hosting.PostgreSQL.Tests
→ 4 via the project graph: Aspire.Hosting.Docker.Tests (2 hops), Aspire.Hosting.EntityFrameworkCore.Tests (2 hops), Aspire.Hosting.Kubernetes.Tests (2 hops), Aspire.Hosting.Testing.Tests (2 hops)

🔧 src/Aspire.Hosting.Azure.CosmosDB/AzureCosmosDBExtensions.cs (changed source)
→ 1 directly: Aspire.Hosting.Azure.Tests
→ 2 via the project graph: Aspire.Hosting.Azure.Kubernetes.Tests (2 hops), Aspire.Hosting.Foundry.Tests (2 hops)

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

🔧 src/Aspire.Hosting.MongoDB/MongoDBBuilderExtensions.cs (changed source)
→ 1 directly: Aspire.Hosting.MongoDB.Tests
→ 1 via the project graph: Aspire.Hosting.Radius.Tests

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

🔧 src/Aspire.Hosting.Azure.Functions/DurableTask/DurableTaskResourceExtensions.cs (changed source)
→ 1 directly: Aspire.Hosting.Azure.Tests

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

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

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

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

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

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

🧪 tests/Aspire.Hosting.CodeGeneration.Go.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.go (changed test)
→ 1 directly: Aspire.Hosting.CodeGeneration.Go.Tests

🧪 tests/Aspire.Hosting.CodeGeneration.Java.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.java (changed test)
→ 1 directly: Aspire.Hosting.CodeGeneration.Java.Tests

🧪 tests/Aspire.Hosting.CodeGeneration.Python.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.py (changed test)
→ 1 directly: Aspire.Hosting.CodeGeneration.Python.Tests

🧪 tests/Aspire.Hosting.CodeGeneration.Rust.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.rs (changed test)
→ 1 directly: Aspire.Hosting.CodeGeneration.Rust.Tests

🧪 tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts (changed test)
→ 1 directly: Aspire.Hosting.CodeGeneration.TypeScript.Tests

Job reasons

Job Triggered by
cli-starter-validation affected project Aspire.Hosting.PostgreSQL
extension-e2e • src/Aspire.Hosting.Azure.Functions/DurableTask/DurableTaskResourceExtensions.cs, src/Aspire.Hosting.Redis/RedisBuilderExtensions.cs, src/Aspire.Hosting/ApplicationModel/ResourceUrlAnnotation.cs, src/Aspire.Hosting/Dashboard/DashboardEventHandlers.cs, src/Aspire.Hosting/Dcp/ResourceSnapshotBuilder.cs, src/Aspire.Hosting/Orchestrator/ApplicationOrchestrator.cs
• affected project Aspire.Hosting.Azure.Functions
polyglot • affected project Aspire.Hosting.Azure.CosmosDB
• affected project Aspire.Hosting.Azure.Provisioning.CosmosDB
typescript-api-compat affected project Aspire.Hosting.Azure.CosmosDB

Selection computed for commit 594346d.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

The binary-breaking field removal lacks explicit major-version and package-validation handling.

Review effort: Balanced
Findings: 2 High severity

Open (2)

Comment thread src/Aspire.Hosting/ApplicationModel/ResourceUrlAnnotation.cs
@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

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

@eerhardt
Eric Erhardt (eerhardt) merged commit b428b74 into main Oct 1, 2026
582 of 585 checks passed
@eerhardt
Eric Erhardt (eerhardt) deleted the jamesnk/resource-url-display-order-property branch October 1, 2026 18:28
@microsoft-github-policy-service microsoft-github-policy-service Bot added this to the 17.0 milestone Oct 1, 2026
aspire-repo-bot Bot added a commit to microsoft/aspire.dev that referenced this pull request Oct 1, 2026
Documents changes from microsoft/aspire#20637

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@aspire-repo-bot

Copy link
Copy Markdown
Contributor

Pull request created: #1806

Generated by PR Documentation Check · copilot · auto · 43 AIC · ⌖ 12.8 AIC · ⊞ 20.3K

@aspire-repo-bot

Copy link
Copy Markdown
Contributor

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

Documented the newly non-obsolete ResourceUrlAnnotation.DisplayOrder property in fundamentals/custom-resource-urls.mdx with a new "Control URL display order" subsection and a code example using WithUrlForEndpoint, matching the PR body's "User-facing usage" example (url.DisplayOrder = 1000;). Triggered signals: pr_body_has_user_facing_section (PR body's "### User-facing usage" example using WithUrlForEndpoint), pr_body_has_deprecation_marker (PR body states DisplayOrder "was exposed as an obsolete field"), pr_label_breaking_change (PR carries breaking-change label since replacing a field with a property is a binary-compat change, though source syntax is unaffected), pr_body_has_cli_flag_mention (false positive — matched --filter-method CLI test invocation text in the PR body's Validation section, not an actual CLI flag; no CLI surface changed).

Note

This draft PR needs human review before merging.

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

Labels

area-app-model Issues pertaining to the APIs in Aspire.Hosting, e.g. DistributedApplication breaking-change Issue or PR that represents a breaking API or functional change over a prerelease.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants