Skip to content

Pin published Aspire Dashboard image to a reproducible tag - #19249

Merged
Jose Perez Rodriguez (joperezr) merged 1 commit into
release/13.5from
dapine/fix-dashboard-image-pin
Aug 12, 2026
Merged

Jose Perez Rodriguez (joperezr) merged 1 commit into
release/13.5from
dapine/fix-dashboard-image-pin

Conversation

@IEvangelist

Copy link
Copy Markdown
Member

Description

aspire publish for Docker Compose and Kubernetes injected the Aspire Dashboard as mcr.microsoft.com/dotnet/nightly/aspire-dashboard without a tag. Both Docker and Kubernetes resolve an untagged image to the mutable :latest, so generated docker-compose.yaml files and Helm charts were not reproducible and could pull a nightly dashboard build that doesn't match the app's Aspire version.

This change adds a shared DashboardImage helper that pins the dashboard image to the app's Aspire major.minor version (for example 13.5), derived from the running assembly's informational version. Deriving major.minor at runtime:

  • always resolves to a tag that exists on the registry — including for prerelease/CI builds, where a full major.minor.patch-prerelease tag is never published;
  • keeps the dashboard on the same Aspire line that generated the manifest; and
  • is deterministic across builds, so publish snapshots stay stable (the build number never leaks into the tag).

Both the Docker Compose and Kubernetes dashboard resources now emit mcr.microsoft.com/dotnet/nightly/aspire-dashboard:13.5 on this release/13.5 line (the helper self-adjusts on other branches). Publish snapshots were regenerated accordingly, and a focused unit test covers the tag-resolution logic (prerelease, stable, 4-part assembly version, and the :latest fallback when no version is available).

Targets release/13.5 as requested.

Scope note: this is the minimal, low-risk fix for the reproducibility problem. The issue also suggested exposing the tag as an overridable Helm values.yaml key; that larger enhancement is intentionally not included here and can be a follow-up.

Fixes #19239.

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

The Docker Compose and Kubernetes publishers injected the dashboard as `mcr.microsoft.com/dotnet/nightly/aspire-dashboard` with no tag, which both runtimes resolve to the mutable `:latest`. Generated compose files and Helm charts were therefore not reproducible and could pull a dashboard build that does not match the app's Aspire version.

Add a shared `DashboardImage` helper that pins the image to the app's Aspire `major.minor` version (for example `13.5`), derived from the running assembly's informational version. `major.minor` always exists on the registry -- including for prerelease/CI builds where a full `major.minor.patch-prerelease` tag is not published -- and stays deterministic across builds so publish snapshots remain stable.

Fixes #19239.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings August 11, 2026 19:54
@github-actions github-actions Bot added the area-integrations Issues pertaining to Aspire Integrations packages label Aug 11, 2026
@github-actions

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 -- 19249

Or

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

@github-actions

Copy link
Copy Markdown
Contributor

Tests selector (audit mode)

The full test matrix and all jobs still run in audit mode. The tests and jobs below are what selective CI would run under enforcement.

5 / 100 test projects · 3 jobs, from 33 changed files.

Selected test projects (5 / 100)

Aspire.Hosting.Azure.Kubernetes.Tests, Aspire.Hosting.Docker.Tests, Aspire.Hosting.Kubernetes.Tests, Aspire.Hosting.Yarp.Tests, Aspire.Playground.Tests

Selected jobs (3)

deployment-e2e, extension-e2e, typescript-api-compat


How these were chosen — grouped by what changed

🔧 src/Aspire.Hosting.Docker/Aspire.Hosting.Docker.csproj (changed source)
1 directly: Aspire.Hosting.Docker.Tests
1 via the project graph: Aspire.Playground.Tests (2 hops)

🔧 src/Aspire.Hosting.Kubernetes/Aspire.Hosting.Kubernetes.csproj (changed source)
1 directly: Aspire.Hosting.Kubernetes.Tests
1 via the project graph: Aspire.Hosting.Azure.Kubernetes.Tests (2 hops)

🔧 src/Aspire.Hosting.Docker/DockerComposeAspireDashboardResourceBuilderExtensions.cs (changed source)
1 directly: Aspire.Hosting.Docker.Tests

🔧 src/Aspire.Hosting.Kubernetes/KubernetesAspireDashboardResourceBuilderExtensions.cs (changed source)
1 directly: Aspire.Hosting.Kubernetes.Tests

🧪 tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposePublisherTests.DockerComposeAppliesServiceCustomizations.verified.yaml (changed test)
1 directly: Aspire.Hosting.Docker.Tests

🧪 tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposePublisherTests.DockerComposeCorrectlyEmitsPortMappings.verified.yaml (changed test)
1 directly: Aspire.Hosting.Docker.Tests

🧪 tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposePublisherTests.DockerComposeWithProjectResources.verified.yaml (changed test)
1 directly: Aspire.Hosting.Docker.Tests

🧪 tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposePublisherTests.PrepareStep_ResolvesArbitraryIValueProviderSource.verified.yaml (changed test)
1 directly: Aspire.Hosting.Docker.Tests

🧪 tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposePublisherTests.PublishAsync_GeneratesValidDockerComposeFile.verified.yaml (changed test)
1 directly: Aspire.Hosting.Docker.Tests

🧪 tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposePublisherTests.PublishAsync_HandlesConditionalReferenceExpression.verified.yaml (changed test)
1 directly: Aspire.Hosting.Docker.Tests

🧪 tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposePublisherTests.PublishAsync_HandlesConditionalReferenceExpressionWithParameterCondition.verified.yaml (changed test)
1 directly: Aspire.Hosting.Docker.Tests

🧪 tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposePublisherTests.PublishAsync_MultipleResourcesWithOtlp_ConfiguresAllForDashboard.verified.yaml (changed test)
1 directly: Aspire.Hosting.Docker.Tests

🧪 tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposePublisherTests.PublishAsync_WithDashboardEnabled_IncludesDashboardService.verified.yaml (changed test)
1 directly: Aspire.Hosting.Docker.Tests

🧪 tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposeTests.DashboardWithForwardedHeadersWritesEnvVar.verified.yaml (changed test)
1 directly: Aspire.Hosting.Docker.Tests

🧪 tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposeTests.DockerComposeOnlyExposesExternalEndpoints.verified.yaml (changed test)
1 directly: Aspire.Hosting.Docker.Tests

🧪 tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposeTests.DockerSwarmDeploymentLabelsSerializedCorrectly.verified.yaml (changed test)
1 directly: Aspire.Hosting.Docker.Tests

🧪 tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposeTests.DockerSwarmUpdateConfigSerializedCorrectly.verified.yaml (changed test)
1 directly: Aspire.Hosting.Docker.Tests

🧪 tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposeTests.MultipleDockerComposeEnvironmentsSupported/env1/docker-compose.verified.yaml (changed test)
1 directly: Aspire.Hosting.Docker.Tests

🧪 tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposeTests.MultipleDockerComposeEnvironmentsSupported/env2/docker-compose.verified.yaml (changed test)
1 directly: Aspire.Hosting.Docker.Tests

🧪 tests/Aspire.Hosting.Kubernetes.Tests/DashboardImageTests.cs (changed test)
1 directly: Aspire.Hosting.Kubernetes.Tests

🧪 tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesEnvironmentResourceTests.MultipleKubernetesEnvironmentsSupported/env1/templates/env1-dashboard/deployment.verified.yaml (changed test)
1 directly: Aspire.Hosting.Kubernetes.Tests

🧪 tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesEnvironmentResourceTests.MultipleKubernetesEnvironmentsSupported/env2/templates/env2-dashboard/deployment.verified.yaml (changed test)
1 directly: Aspire.Hosting.Kubernetes.Tests

🧪 tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#02.verified.yaml (changed test)
1 directly: Aspire.Hosting.Kubernetes.Tests

🧪 tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesWithProjectResources#02.verified.yaml (changed test)
1 directly: Aspire.Hosting.Kubernetes.Tests

🧪 tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.PublishAsync_ConditionalWithParameterBranch_UsesIfElseSyntax#02.verified.yaml (changed test)
1 directly: Aspire.Hosting.Kubernetes.Tests

🧪 tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.PublishAsync_CustomWorkloadAndResourceType#02.verified.yaml (changed test)
1 directly: Aspire.Hosting.Kubernetes.Tests

🧪 tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.PublishAsync_GeneratesValidHelmChart#02.verified.yaml (changed test)
1 directly: Aspire.Hosting.Kubernetes.Tests

🧪 tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.PublishAsync_HandlesConditionalReferenceExpression#02.verified.yaml (changed test)
1 directly: Aspire.Hosting.Kubernetes.Tests

🧪 tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.PublishAsync_HandlesConditionalReferenceExpressionWithParameterCondition#02.verified.yaml (changed test)
1 directly: Aspire.Hosting.Kubernetes.Tests

🧪 tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.PublishAsync_HandlesSpecialResourceName#02.verified.yaml (changed test)
1 directly: Aspire.Hosting.Kubernetes.Tests

🧪 tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.PublishAsync_ResourceWithProbes#00.verified.yaml (changed test)
1 directly: Aspire.Hosting.Kubernetes.Tests

🧪 tests/Aspire.Hosting.Yarp.Tests/Snapshots/YarpConfigGeneratorTests.GenerateEnvVariablesConfigurationDockerCompose.verified.env (changed test)
1 directly: Aspire.Hosting.Yarp.Tests

Job reasons

Job Triggered by
deployment-e2e affected project Aspire.Hosting.Azure.Kubernetes
extension-e2e src/Aspire.Hosting.Docker/Aspire.Hosting.Docker.csproj, src/Aspire.Hosting.Docker/DockerComposeAspireDashboardResourceBuilderExtensions.cs, src/Aspire.Hosting.Kubernetes/Aspire.Hosting.Kubernetes.csproj, src/Aspire.Hosting.Kubernetes/KubernetesAspireDashboardResourceBuilderExtensions.cs
• affected project Aspire.Hosting.Docker
typescript-api-compat affected project Aspire.Hosting.Docker

Selection computed for commit c21f171.

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.

Pull request overview

Attempts to improve dashboard image version alignment by replacing :latest with an Aspire major.minor tag.

Changes:

  • Adds shared dashboard tag-resolution logic.
  • Applies the tag to Docker Compose and Kubernetes publishing.
  • Updates unit tests and generated snapshots.

Reviewed changes

Copilot reviewed 33 out of 33 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/Shared/DashboardImage.cs Resolves the dashboard image tag.
src/Aspire.Hosting.Docker/DockerComposeAspireDashboardResourceBuilderExtensions.cs Applies the resolved Compose image tag.
src/Aspire.Hosting.Docker/Aspire.Hosting.Docker.csproj Includes the shared helper.
src/Aspire.Hosting.Kubernetes/KubernetesAspireDashboardResourceBuilderExtensions.cs Applies the resolved Kubernetes image tag.
src/Aspire.Hosting.Kubernetes/Aspire.Hosting.Kubernetes.csproj Includes the shared helper.
tests/Aspire.Hosting.Kubernetes.Tests/DashboardImageTests.cs Tests tag resolution and fallback behavior.
tests/Aspire.Hosting.Yarp.Tests/Snapshots/YarpConfigGeneratorTests.GenerateEnvVariablesConfigurationDockerCompose.verified.env Updates the YARP Compose snapshot.
tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.PublishAsync_ResourceWithProbes#00.verified.yaml Updates the dashboard image snapshot.
tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.PublishAsync_HandlesSpecialResourceName#02.verified.yaml Updates the dashboard image snapshot.
tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.PublishAsync_HandlesConditionalReferenceExpressionWithParameterCondition#02.verified.yaml Updates the dashboard image snapshot.
tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.PublishAsync_HandlesConditionalReferenceExpression#02.verified.yaml Updates the dashboard image snapshot.
tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.PublishAsync_GeneratesValidHelmChart#02.verified.yaml Updates the Helm chart snapshot.
tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.PublishAsync_CustomWorkloadAndResourceType#02.verified.yaml Updates the dashboard image snapshot.
tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.PublishAsync_ConditionalWithParameterBranch_UsesIfElseSyntax#02.verified.yaml Updates the dashboard image snapshot.
tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesWithProjectResources#02.verified.yaml Updates the dashboard image snapshot.
tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#02.verified.yaml Updates the dashboard image snapshot.
tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesEnvironmentResourceTests.MultipleKubernetesEnvironmentsSupported/env2/templates/env2-dashboard/deployment.verified.yaml Updates the second environment snapshot.
tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesEnvironmentResourceTests.MultipleKubernetesEnvironmentsSupported/env1/templates/env1-dashboard/deployment.verified.yaml Updates the first environment snapshot.
tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposeTests.MultipleDockerComposeEnvironmentsSupported/env2/docker-compose.verified.yaml Updates the second Compose environment snapshot.
tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposeTests.MultipleDockerComposeEnvironmentsSupported/env1/docker-compose.verified.yaml Updates the first Compose environment snapshot.
tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposeTests.DockerSwarmUpdateConfigSerializedCorrectly.verified.yaml Updates the Swarm snapshot.
tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposeTests.DockerSwarmDeploymentLabelsSerializedCorrectly.verified.yaml Updates the Swarm labels snapshot.
tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposeTests.DockerComposeOnlyExposesExternalEndpoints.verified.yaml Updates the endpoint snapshot.
tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposeTests.DashboardWithForwardedHeadersWritesEnvVar.verified.yaml Updates the forwarded-headers snapshot.
tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposePublisherTests.PublishAsync_WithDashboardEnabled_IncludesDashboardService.verified.yaml Updates the dashboard service snapshot.
tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposePublisherTests.PublishAsync_MultipleResourcesWithOtlp_ConfiguresAllForDashboard.verified.yaml Updates the OTLP snapshot.
tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposePublisherTests.PublishAsync_HandlesConditionalReferenceExpressionWithParameterCondition.verified.yaml Updates the conditional snapshot.
tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposePublisherTests.PublishAsync_HandlesConditionalReferenceExpression.verified.yaml Updates the conditional snapshot.
tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposePublisherTests.PublishAsync_GeneratesValidDockerComposeFile.verified.yaml Updates the primary Compose snapshot.
tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposePublisherTests.PrepareStep_ResolvesArbitraryIValueProviderSource.verified.yaml Updates the value-provider snapshot.
tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposePublisherTests.DockerComposeWithProjectResources.verified.yaml Updates the project resources snapshot.
tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposePublisherTests.DockerComposeCorrectlyEmitsPortMappings.verified.yaml Updates the port mappings snapshot.
tests/Aspire.Hosting.Docker.Tests/Snapshots/DockerComposePublisherTests.DockerComposeAppliesServiceCustomizations.verified.yaml Updates the customization snapshot.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +28 to +31
/// let the dashboard drift away from the app's Aspire version. Pinning to <c>major.minor</c> keeps
/// the dashboard on the same Aspire line that generated the manifest and always resolves to a tag
/// that exists on the registry — including for prerelease/CI builds, where a full
/// <c>major.minor.patch-prerelease</c> tag is not published.
@IEvangelist

Copy link
Copy Markdown
Member Author

PR Testing Report

PR Information

  • PR Number: Pin published Aspire Dashboard image to a reproducible tag #19249
  • Title: Pin published Aspire Dashboard image to a reproducible tag
  • Author: IEvangelist (David Pine)
  • Target branch: release/13.5
  • Head Commit: c21f171126b515e01ec3285d3a762863f02fe443
  • Tested At: 2026-08-11 (local, Windows / PowerShell 7.6, .NET SDK 10.0.302)

Artifact Version Verification

Changes Analyzed

Files Changed (source)

  • src/Shared/DashboardImage.csAdded. Shared helper: Name (untagged image) + ResolveTag() that derives the app's Aspire major.minor from AssemblyInformationalVersion (falls back to 4‑part assembly version, then latest).
  • src/Aspire.Hosting.Docker/DockerComposeAspireDashboardResourceBuilderExtensions.cs.WithImage(DashboardImage.Name, DashboardImage.ResolveTag()) instead of the untagged literal.
  • src/Aspire.Hosting.Kubernetes/KubernetesAspireDashboardResourceBuilderExtensions.cs — same change for the K8s dashboard resource.
  • src/Aspire.Hosting.Docker/*.csproj, src/Aspire.Hosting.Kubernetes/*.csproj — link the shared DashboardImage.cs.
  • tests/Aspire.Hosting.Kubernetes.Tests/DashboardImageTests.csAdded unit tests for the resolver.
  • 30 regenerated publish snapshots (Docker Compose, Kubernetes, Yarp) — dashboard image line now …/aspire-dashboard:13.5.

Change Categories

  • CLI changes
  • Hosting integration changes (Docker Compose + Kubernetes publishers)
  • Dashboard UI changes (image reference only)
  • Template changes
  • Client/Component changes
  • Test changes (unit + snapshots)
  • CI infrastructure changes

Test Scenarios Executed

Scenario 1: Version verification

Objective: Confirm the installed dogfood CLI corresponds to the PR head commit.
Coverage Type: Happy path
Status: ✅ Passed

Evidence:

  • aspire --version13.5.0-pr.19249.gc21f1711
  • Hive contains Aspire.Hosting.Docker, Aspire.Hosting.Kubernetes at 13.5.0-pr.19249.gc21f1711.

Observations: Version suffix gc21f1711 matches PR head c21f171…. Expected dashboard tag on this line is 13.5.


Scenario 2: Docker Compose publish (happy path)

Objective: Verify aspire publish for a Docker Compose environment pins the dashboard image.
Coverage Type: Happy path
Status: ✅ Passed

Steps:

  1. aspire new aspire-empty from the PR hive.
  2. apphost.cs: builder.AddDockerComposeEnvironment("compose"); builder.AddContainer("web", "nginx");
  3. aspire publish --apphost apphost.cs -o aspire-output

Evidence (docker-compose.yaml):

compose-dashboard:
  image: "mcr.microsoft.com/dotnet/nightly/aspire-dashboard:13.5"

Observations: Dashboard pinned to :13.5. The user's untagged web/nginx still renders nginx:latest, confirming only the dashboard is deliberately pinned (untagged user images are unchanged).


Scenario 3: Kubernetes publish (happy path)

Objective: Verify aspire publish for a Kubernetes environment pins the dashboard image in the Helm chart.
Coverage Type: Happy path
Status: ✅ Passed

Steps:

  1. aspire new aspire-empty from the PR hive.
  2. apphost.cs: builder.AddKubernetesEnvironment("k8s"); builder.AddContainer("web", "nginx");
  3. aspire publish --apphost apphost.cs -o aspire-output

Evidence (templates/k8s-dashboard/deployment.yaml):

containers:
  - image: "mcr.microsoft.com/dotnet/nightly/aspire-dashboard:13.5"
    name: "k8s-dashboard"

Observations: Dashboard pinned to :13.5.


Scenario 4: Reproducibility / boundary

Objective: Confirm the pinned tag is deterministic and never regresses to :latest.
Coverage Type: Boundary / negative
Status: ✅ Passed

Steps: Published each app a second time to a fresh output directory and compared the dashboard image line.

Assertions (all True):

  • Compose deterministic across runs (run1 == run2)
  • Kubernetes deterministic across runs (run1 == run2)
  • Compose tag == Kubernetes tag (13.5)
  • Tag matches ^\d+\.\d+$
  • Tag is not latest
  • Tag == CLI major.minor (13.5)

Expected Unhappy-Path Outcome: Prevents the pre-fix regressions — non-reproducible drift and the mutable :latest resolution. Both confirmed absent; the build number never leaks into the tag.


Scenario 5: Resolver unit-test logic (edge cases)

Objective: Cover the resolver branches that publish cannot reach (assembly-version fallback, unparseable input, no-version → latest).
Coverage Type: Unhappy path / boundary
Status: ✅ Passed

Steps: Compiled the PR's exact src/Shared/DashboardImage.cs and the PR's exact DashboardImageTests.cs into a standalone net10.0 xUnit project and ran dotnet test. (The compiled artifact's happy path was already validated end-to-end by Scenarios 2–4; this isolates the fallback branches.)

Evidence: Passed! - Failed: 0, Passed: 10, Skipped: 0, Total: 10 covering:

  • SemVer prerelease + build metadata → major.minor (e.g. 13.5.0-preview…+sha13.5)
  • Stable and -dev prerelease → major.minor
  • Missing/empty informational version → 4‑part assembly-version fallback (13.5.0.013.5)
  • Unparseable informational version → assembly-version fallback (10.3.0.010.3)
  • No parseable version at all → latest
  • Running assembly → real ^\d+\.\d+$ tag (never latest)

Summary

Scenario Status Notes
1. Version verification ✅ Passed 13.5.0-pr.19249.gc21f1711 matches head c21f171
2. Docker Compose publish ✅ Passed aspire-dashboard:13.5 in docker-compose.yaml
3. Kubernetes publish ✅ Passed aspire-dashboard:13.5 in Helm deployment.yaml
4. Reproducibility / boundary ✅ Passed Deterministic, ^\d+\.\d+$, never :latest
5. Resolver unit tests ✅ Passed 10/10, all fallback branches covered

Overall Result

✅ PR VERIFIED

The Docker Compose and Kubernetes publishers now emit the Aspire Dashboard image pinned to the app's Aspire major.minor (mcr.microsoft.com/dotnet/nightly/aspire-dashboard:13.5) instead of an untagged/:latest reference. Output is deterministic across runs and the tag matches the CLI's version line. The resolver's fallback logic (assembly version, then latest) is covered by passing unit tests.

Recommendations

  • None blocking. Behavior matches the PR description and the regenerated snapshots.
  • As already noted in the PR, exposing the tag as an overridable Helm values.yaml key remains a reasonable follow-up (out of scope here).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I was kind of on the fence on this one since we own the image ourselves, so technically we do want to stay on latest specially since we try to keep backward compat, but I think that this is a good change anyway.

@joperezr Jose Perez Rodriguez (joperezr) added the Servicing-approved Approved for servicing release label Aug 12, 2026
@joperezr
Jose Perez Rodriguez (joperezr) merged commit 42d56ff into release/13.5 Aug 12, 2026
350 checks passed
@joperezr
Jose Perez Rodriguez (joperezr) deleted the dapine/fix-dashboard-image-pin branch August 12, 2026 21:31
@microsoft-github-policy-service microsoft-github-policy-service Bot added this to the 13.5 milestone Aug 12, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 12, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-integrations Issues pertaining to Aspire Integrations packages Servicing-approved Approved for servicing release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants