Skip to content

Expose Helm chart publishing results for deployment extensions - #21789

Draft
Mitch Denny (mitchdenny) wants to merge 1 commit into
mainfrom
mitchdenny-public-helm-publishing-apis
Draft

Mitch Denny (mitchdenny) wants to merge 1 commit into
mainfrom
mitchdenny-public-helm-publishing-apis

Conversation

@mitchdenny

Copy link
Copy Markdown
Member

Description

External deployment publishers can generate Aspire's Kubernetes Helm charts through public pipeline annotations, but cannot currently inspect the complete deferred-value mappings or access the actual chart-producing Kubernetes environment behind AKS.

This change exposes AzureKubernetesEnvironmentResource.KubernetesEnvironment with an internal setter and adds KubernetesEnvironmentResource.HelmChartPublishingResult. The result contains the chart output directory and read-only parameter, value-provider, image-resource, and composite-template mappings. Each mapping preserves its three path segments and original source object. Results are published only after chart generation succeeds; a new attempt clears the current result, and previously obtained metadata snapshots remain unchanged.

The publisher context, chart-writing method, capture lists, and deployment-engine factory remain internal. Existing publishing/deployment resolution behavior is unchanged. The result is a C# deployment-extension API, explicitly excluded from the polyglot AppHost authoring surface. Generated API release baselines are intentionally unchanged.

Fixes # (issue)

User-facing usage

var environment = builder.AddKubernetesEnvironment("k8s");
builder.Pipeline.AddStep("consume-chart", context =>
{
    var result = environment.Resource.HelmChartPublishingResult
        ?? throw new InvalidOperationException("The Helm chart has not been published.");
    // Consume result.OutputPath, Parameters, ValueProviders, Images, and CrossReferences.
    return Task.CompletedTask;
}, dependsOn: $"publish-{environment.Resource.Name}", requiredBy: "publish");

For AKS, obtain the same environment through aks.Resource.KubernetesEnvironment and depend on its publish-{Name} step. Resolve references only in the consuming publisher's appropriate deployment phase; the result does not clone resources or chart files.

Validation

  • Passed: dotnet test --project tests/Aspire.Hosting.Kubernetes.Tests/Aspire.Hosting.Kubernetes.Tests.csproj --no-launch-profile -- --filter-class '*.HelmChartPublishingResultTests' --filter-class '*.KubernetesPublisherTests' --filter-class '*.KubernetesDeployTests' --filter-not-trait 'quarantined=true' --filter-not-trait 'outerloop=true' — 176 tests.
  • Passed: dotnet test --project tests/Aspire.Hosting.Azure.Kubernetes.Tests/Aspire.Hosting.Azure.Kubernetes.Tests.csproj --no-launch-profile -- --filter-class '*.AzureKubernetesEnvironmentExtensionsTests' --filter-class '*.AzureKubernetesHelmChartTests' --filter-not-trait 'quarantined=true' --filter-not-trait 'outerloop=true' — 119 tests.
  • Passed: for project in Aspire.Hosting Aspire.Hosting.Azure Aspire.Hosting.Azure.ContainerRegistry Aspire.Hosting.Azure.Network Aspire.Hosting.Azure.OperationalInsights Aspire.Hosting.Kubernetes Aspire.Hosting.Azure.Kubernetes Aspire.Hosting.Dotnet Aspire.Hosting.AppHost; do dotnet pack "src/$project/$project.csproj" -c Release -p:VersionSuffix=preview.1.helm.gb7cbb35077 -p:DotNetFinalVersionKind=prerelease -o artifacts/helm-publishing-packages/b7cbb35077 --verbosity quiet || exit "$?"; done — nine local 17.0 packages, with matching dependency versions and repository commit metadata. These are local artifacts, not packages published to a remote feed.

No cloud provisioning or deployment was performed. Formal API review and downstream integration remain pending; this PR is intentionally a draft.

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 App <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Nov 5, 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 -- 21789

Or

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

@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Tests selector

8 / 101 PR test projects · 2 PR jobs, from 10 changed files.

Selected PR test projects (8 / 101)

Aspire.Cli.EndToEnd.Tests, Aspire.Hosting.Azure.Kubernetes.Tests, Aspire.Hosting.Azure.Tests, Aspire.Hosting.CodeGeneration.Python.Tests, Aspire.Hosting.CodeGeneration.TypeScript.Tests, Aspire.Hosting.Docker.Tests, Aspire.Hosting.Kubernetes.Tests, Aspire.Hosting.RemoteHost.Tests

Selected PR jobs (2)

polyglot, typescript-api-compat


How these were chosen — grouped by what changed

🔧 src/Aspire.Hosting.Azure.Kubernetes/AzureKubernetesEnvironmentResource.cs (changed source)
→ 2 directly: Aspire.Hosting.Azure.Kubernetes.Tests, Aspire.Hosting.Azure.Tests
→ 3 via the project graph: Aspire.Hosting.CodeGeneration.Python.Tests, Aspire.Hosting.CodeGeneration.TypeScript.Tests, Aspire.Hosting.RemoteHost.Tests

🔧 src/Aspire.Hosting.Kubernetes/HelmChartPublishingResult.cs (changed source)
→ 1 directly: Aspire.Hosting.Kubernetes.Tests
→ 1 via the project graph: Aspire.Hosting.Docker.Tests

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

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

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

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

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

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

🧪 tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/HelmChartPublishingResultTests.ResultIsAvailableToDependentStepAndPreservesDeferredSources.verified.txt (changed test)
→ 1 directly: Aspire.Hosting.Kubernetes.Tests

🧪 tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/HelmChartPublishingResultTests.ResultIsAvailableToDependentStepAndPreservesDeferredSources.verified.yaml (changed test)
→ 1 directly: Aspire.Hosting.Kubernetes.Tests

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

Job reasons

Job Triggered by
polyglot • affected project Aspire.Hosting.Azure.Kubernetes
• affected project Aspire.Hosting.Azure.Provisioning.ContainerService
typescript-api-compat affected project Aspire.Hosting.Azure.Kubernetes

Selection computed for commit b7cbb35.

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.

🟡 Changes recommended

Capture lists persist across publishing attempts, exposing stale provider and image mappings for removed workloads and potentially causing unused source resolution or invalid overrides.

1 open issue
What changed in this PR

This PR exposes generated Helm chart metadata to C# deployment extensions, including access to the chart-producing Kubernetes environment behind AKS.

Changes:

  • Adds read-only publishing results with output paths and deferred-value mappings.
  • Publishes results after successful chart generation and clears them when a new attempt starts.
  • Adds usage documentation and tests for deferred sources, snapshot isolation, failure handling, and AKS access.
File Description
tests/​Aspire.Hosting.Kubernetes.Tests/​TestValueProvider.cs Tracks provider evaluations to verify deferred resolution.
tests/​Aspire.Hosting.Kubernetes.Tests/​Snapshots/​HelmChartPublishingResultTests.ResultIsAvailableToDependentStepAndPreservesDeferredSources.verified.yaml Records generated Helm values.
tests/​Aspire.Hosting.Kubernetes.Tests/​Snapshots/​HelmChartPublishingResultTests.ResultIsAvailableToDependentStepAndPreservesDeferredSources.verified.txt Records exposed mapping metadata.
tests/​Aspire.Hosting.Kubernetes.Tests/​HelmChartPublishingResultTests.cs Tests result availability, snapshots, failures, and run mode.
tests/​Aspire.Hosting.Azure.Kubernetes.Tests/​AzureKubernetesEnvironmentExtensionsTests.cs Tests access to AKS’s chart environment and publishing result.
src/​Aspire.Hosting.Kubernetes/​README.md Documents deployment-publisher consumption and result lifecycle.
src/​Aspire.Hosting.Kubernetes/​KubernetesPublishingContext.cs Clears and assigns publishing results around chart generation.
src/​Aspire.Hosting.Kubernetes/​KubernetesEnvironmentResource.cs Exposes the current publishing result.
src/​Aspire.Hosting.Kubernetes/​HelmValueMapping.cs Defines immutable mapping paths and source references.
src/​Aspire.Hosting.Kubernetes/​HelmChartPublishingResult.cs Captures read-only chart metadata and deferred mappings.
src/​Aspire.Hosting.Azure.Kubernetes/​AzureKubernetesEnvironmentResource.cs Makes the underlying Kubernetes environment publicly readable.

Review effort: Balanced

Comment on lines +27 to +31
ValueProviders = Array.AsReadOnly(environment.CapturedHelmValueProviders.Distinct()
.Select(value => new HelmValueMapping<IValueProvider>(value.Section, value.ResourceKey, value.ValueKey, value.ValueProvider))
.ToArray());
Images = Array.AsReadOnly(environment.CapturedHelmImageReferences.Distinct()
.Select(value => new HelmValueMapping<IResource>(value.Section, value.ResourceKey, value.ValueKey, value.Resource))

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants