Repository navigation
Complete Go starter validation and polyglot scenario readiness - #21828
David Pine (IEvangelist) wants to merge 3 commits into
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 21828Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 21828" |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
🟡 Changes recommended
Windows/macOS Go validation lacks a usable container runtime, the Java smoke test cannot select its disabled template, and repository-mode restores bypass the pinned packages the stable-feed check is intended to verify.
3 open issues
What changed in this PR
This PR advances Go AppHost preview readiness by shipping build-ready starter dependencies and expanding validation across CLI scenarios, polyglot fixtures, and native runners. It also strengthens Java and TypeScript restore tests. The stabilization gate remains disabled, and several runtime scenarios still require CI execution.
Changes:
- Ship a tidy Go starter module and checksums, with build, health, and weather-response checks.
- Expand Go fixture coverage, runtime list-getter checks, and native-runner validation.
- Replace positional language selection and strengthen SDK regeneration and Kubernetes readiness assertions.
| File | Description |
|---|---|
tests/PolyglotAppHosts/Aspire.Hosting/Go/apphost.go |
Adds AKS node-pool and persistent-volume coverage. |
tests/PolyglotAppHosts/Aspire.Hosting.Foundry/Go/apphost.go |
Attaches Foundry tools to a prompt agent. |
tests/PolyglotAppHosts/Aspire.Hosting.EntityFrameworkCore/Go/go.mod |
Defines the new Go fixture module. |
tests/PolyglotAppHosts/Aspire.Hosting.EntityFrameworkCore/Go/aspire.config.json |
Configures EF Core fixture integrations. |
tests/PolyglotAppHosts/Aspire.Hosting.EntityFrameworkCore/Go/apphost.go |
Exercises migration configuration and publishing APIs. |
tests/Infrastructure.Tests/TestTriggerMap/TestTriggerMapTests.cs |
Checks Go starter runtime-package routing. |
tests/Aspire.Cli.EndToEnd.Tests/TypeScriptPublishTests.cs |
Selects TypeScript by name. |
tests/Aspire.Cli.EndToEnd.Tests/TypeScriptCodegenValidationTests.cs |
Restores stale SDK files before testing regeneration. |
tests/Aspire.Cli.EndToEnd.Tests/SecretTypeScriptAppHostTests.cs |
Uses named language selection. |
tests/Aspire.Cli.EndToEnd.Tests/LocalConfigMigrationTests.cs |
Uses named language selection. |
tests/Aspire.Cli.EndToEnd.Tests/KubernetesDeployTypeScriptTests.cs |
Waits for the application pod to become Ready. |
tests/Aspire.Cli.EndToEnd.Tests/JavaScriptPublishTests.cs |
Uses named language selection. |
tests/Aspire.Cli.EndToEnd.Tests/JavaPolyglotTests.cs |
Selects Java independently of picker order. |
tests/Aspire.Cli.EndToEnd.Tests/JavaPolyglotApphostDirectoryTests.cs |
Uses named Java selection. |
tests/Aspire.Cli.EndToEnd.Tests/JavaCodegenValidationTests.cs |
Tests restore from a stale SDK baseline. |
tests/Aspire.Cli.EndToEnd.Tests/Helpers/KubernetesDeployTestHelpers.cs |
Corrects the tool-installation comment. |
tests/Aspire.Cli.EndToEnd.Tests/Helpers/CliE2EAutomatorHelpers.cs |
Centralizes language selection by display name. |
tests/Aspire.Cli.EndToEnd.Tests/GoStarterReadinessTests.cs |
Checks starter dependencies, gitignore, and HTTP responses. |
tests/Aspire.Cli.EndToEnd.Tests/GoKubernetesDeployTests.cs |
Removes manual tidy and exercises Helm configuration. |
tests/Aspire.Cli.EndToEnd.Tests/GoEmptyAppHostTemplateTests.cs |
Checks the generated gitignore entry. |
src/Aspire.Cli/Templating/Templates/go-starter/api/go.sum |
Ships dependency checksums. |
src/Aspire.Cli/Templating/Templates/go-starter/api/go.mod |
Aligns dependency declarations with tidy output. |
eng/scripts/stabilization-smoke-init-restore.sh |
Adds Go/Java scaffolding and isolated-cache restore checks. |
eng/scripts/cli-starter-validation.ps1 |
Adds the Go starter and API/Redis readiness checks. |
eng/github-ci/test-trigger-map.yml |
Routes Go and Redis changes to starter validation. |
docs/ci/test-trigger-map.md |
Documents expanded validation coverage and gating. |
.github/workflows/polyglot-validation/test-go.sh |
Exercises configuration child-list decoding at runtime. |
.github/workflows/polyglot-validation/test-go-playground.sh |
Runs go vet on Go fixtures. |
.github/workflows/cli-starter-validation.yml |
Installs checksum-verified Go and increases timeouts. |
.github/workflows/ci.yml |
Updates comments describing stabilization smoke coverage. |
Review effort: Balanced
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
Honor the existing Redis opt-out for Go without changing its default. Keep Linux Redis readiness and exercise both generated starter variants. Restore the TypeScript SDK before snapshotting cache metadata. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
🔵 Needs a closer look
The Java smoke test cannot reach package-pin validation on a clean runner because the experimental Java feature flag is not enabled, causing scaffolding to fail.
2 open issues
1 resolved since last review
Review effort: Balanced
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Tests selector4 / 101 PR test projects · 4 PR jobs, from 37 changed files. Selected PR test projects (4 / 101)
Selected PR jobs (4)
How these were chosen — grouped by what changed📦 affected project 📄 📄 📄 📄 📄 🔧 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 🧪 Job reasons
Selection computed for commit |
There was a problem hiding this comment.
🟡 Changes recommended
The smoke script can select prerelease artifacts instead of stable packages, and partial test startup failures can bypass cleanup and leave a Docker container running.
2 open issues
2 resolved since last review
Review effort: Balanced
| # pull in the temp dir's NuGet.config and try to restore the CLI's own dependencies against | ||
| # our local-only feed). | ||
| # Pin the driver and generated projects to the SDK that the stabilized pack produced. | ||
| APPHOST_SDK_NUPKG=$(ls "$LOCAL_FEED"/Aspire.AppHost.Sdk.[0-9]*.[0-9]*.[0-9]*.nupkg 2>/dev/null | head -1) |
| await auto.AspireStartAsync(counter, startTimeout: TimeSpan.FromMinutes(4)); | ||
| try | ||
| { |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |


Description
Go starters should build from their shipped files without an initial
aspire runrepairing dependencies, and Go preview validation should exercise the same runtime and native-runner paths as other AppHosts.go.modand generatedgo.sum. Add starter scenarios checking gitignore, readonly API build, tidy stability, health and weather responses; remove the Kubernetes manual-tidy workaround.--use-redis-cache falseoption for Go. Omitted/true retains Redis; false omits the integration and resource. Cover all three scaffold choices with generated-source snapshots and both HTTP lifecycle variants with Docker E2E.go vetto Go polyglot fixtures, an EF Core fixture, and Foundry tool/AKS node-pool parity. Exercise configuration-section list getters in the real Go runtime smoke.aspire addso the followingaspire restoregenuinely tests regeneration. Establish the TypeScript baseline with an actual restore before reading cache metadata.Relates to #21202, #21206, #21209, #21210, #21201, and #21108.
User-facing usage
Both variants emit
api/go.sumand an already-tidy API module. Its API can build withgo build -mod=readonlywithout first running the AppHost's tidy resource.Dependencies and remaining acceptance
This PR is independent of #21823. Root-module brownfield E2E #21825 merged into the #21823 feature branch, not main; delivery still depends on the open #21823. #21806 independently covers other Go init/build/vet/stable-restore scenarios.
The existing stabilization gate remains disabled (
STABILIZATION_ENABLED: 'false'); enabling it needs a separate CI/policy decision. CurrentAspire.Hosting.Java.csprojstill setsSuppressFinalPackageVersion=truewhile the Java starter pins the requested Aspire version. The corrected smoke reaches actual NuGet restore and exposes that mismatch:Aspire.Hosting.Java (= 17.0.0)is unavailable, the nearest local package is17.0.0-dev, and nuget.org versions are not considered. No pin substitution or Java release-policy change is included.Native Linux validation built the genuine stabilized Release CLI/payload and proved cold Go/Redis package restore and C# restore. This is not a clean stabilization pass: the unsuppressed stable pack first reproduced NU5104 on existing .NET 11 preview dependencies. The diagnostic consumer feed downgraded only NU5104 with
WarningsNotAsErrors=NU5104; that exception is not committed. The final smoke correctly exits 1 with only Java in its failure list.The bounded shared-image fix is separate in #21849; this PR does not modify image Dockerfiles or the image-build implementation. Its
b8274fc8e0image job and all four uploads passed, and Infrastructure passed 2090/2090 including all 13 new image cases. That PR still has required-check failures in Windows extension fake-timer cleanup and Windows DCP Docker startup; its selected E2E follow-through is pending. Do not infer overall green CI or actual timeout/fallback execution from a healthy-mirror image pass.No action SHA is added or changed. No official Azure DevOps pipeline is modified. Parent's Go-minimum-version map rule/theory and the other owner's extension-e2e map block are untouched. The cache option uses existing embedded CLI inputs; no additional selector rule is required. The stabilization script remains advisory/disabled rather than being presented as a regular-PR gate.
This does not close #21108: live Azure Container Apps deployment and real missing/old-toolchain E2E remain uncovered here. Cross-language lifecycle redesigns are deferred.
CI failures diagnosed and fixed
Original-head run 42116644663 exposed two causes:
TypeScriptCodegenValidationTestsread.codegen-hashimmediately after init, which supplies SDK sources but not restore-cache metadata. An explicit baseline restore now precedes the snapshot and stale-cache assertions.Head
1ab3ad1e30: all six native starter lanes passed, including both Redis-enabled Ubuntu lanes and all four formerly failing Windows/macOS lanes, in run 42151619597. Packaged CI subsequently passed GoStarterReadinessTests (both cache choices), GoStarterTemplateTests, JavaCodegenValidationTests, and TypeScriptCodegenValidationTests. All originally failing targeted lanes/classes therefore have passing coverage.The shared image job first timed out at 45 minutes twice. Attempt 2 fetched 108 MB from Azure Ubuntu in 41 minutes 29 seconds (43.4 kB/s), versus a following GitHub download at 80.1 MB/s; GHA cache import also returned HTTP 400 service-unavailable responses. After #21849's same-input image control passed with all four uploads, one evidence-based product revalidation was started. Attempt 3's image job passed and admitted packaged E2E. No blind retries were made. The successful infrastructure control used a healthy primary mirror; it does not demonstrate timeout/fallback execution in that CI run.
Review corrections are pushed as
bd30794b9e. Its new-head CI run is not green: all six native starter lanes and Go/Java/TypeScript SDK validation passed, but the shared image job was canceled after 45 minutes 22 seconds with Azure Ubuntu apt downloads still running. All four uploads were skipped, so packaged Go/TypeScript scenarios were not admitted on this head. Cache import again returned HTTP 400. The separate Linux tree-actions failure checks a stale immutable Running snapshot before endpoint publication; its test-only readiness fix is open in #21854. That fix must merge and be incorporated into this PR before fresh checkout validation; retrying the unchanged checkout is not a fix. Aggregate result failures are derivative of these leaf failures.Per the user's explicit authorization, the coordinator enabled normal native squash auto-merge at 05:22:46Z on 2026-11-06, guarded to the approved
bd30794b9ehead and pending required checks. No admin bypass is authorized or used; the PR is not merged.Stabilization review corrections
The smoke now publishes a Release CLI with its real stabilized bundle outside the checkout, propagates stabilization into child payload builds, and clears inherited
ASPIRE_REPO_ROOTfor every consumer invocation. Consumer packages are isolated after the driver build so build-time extraction cannot hide a missing stable package. Successful guest restores must produce metadata for the exact hosting pins, including Redis for Go; provenance is retained in the output.The real run also exposed two stale smoke assumptions: a pre-owned parent feed mapping conflicts with scaffolding's project-local channel policy, and current C# file-based templates use
#:package Aspire.Hosting.AppHost@<version>, not the obsolete SDK directive. The smoke now lets the CLI establish its own authoritative project-scoped feed mapping and checks the current hosting-package contract. No customer NuGet policy is changed.Validation
.\restore.cmd- passed.dotnet build tests\Aspire.Cli.EndToEnd.Tests\Aspire.Cli.EndToEnd.Tests.csproj --no-restore --nologo -v quiet- passed, zero warnings/errors.dotnet test --project tests\Aspire.Cli.Tests\Aspire.Cli.Tests.csproj --no-launch-profile -- --filter-class '*.NewCommandTemplateConfigPersistenceTests' --filter-not-trait 'quarantined=true' --filter-not-trait 'outerloop=true'- passed, 59 tests including default/true/false Go package and generated-source assertions. Existing ILCompiler NU1903 advisory was emitted.ASPIRE_E2E_CLI_ARCHIVE_DIR=artifacts\readiness-ci\cli-archive-newandASPIRE_E2E_DOTNET_IMAGE=aspire-e2e-polyglot-base:latest,dotnet test --project tests\Aspire.Cli.EndToEnd.Tests\Aspire.Cli.EndToEnd.Tests.csproj --no-launch-profile -- --filter-method '*.RestoreGeneratesSdkFiles_WithConfiguredToolchain' --filter-not-trait 'quarantined=true' --filter-not-trait 'outerloop=true'- passed, all four npm/bun/yarn/pnpm cases against exact1ab3ad1e30Linux CLI/packages. The corresponding packaged CI class also passed above.ASPIRE_E2E_CLI_ARCHIVE_DIR=artifacts\readiness-ci\cli-archive-newandASPIRE_E2E_POLYGLOT_GO_IMAGE=aspire-go-e2e-6972:latest,dotnet test --project tests\Aspire.Cli.EndToEnd.Tests\Aspire.Cli.EndToEnd.Tests.csproj --no-launch-profile -- --filter-method '*.StarterShipsTidyApiAndServesRequests' --filter-not-trait 'quarantined=true' --filter-not-trait 'outerloop=true'- 1 passed/1 failed locally against exact1ab3ad1e30. Cache-free passed actual scaffolding, readonly API build, tidy check, API-up, health/weather and stop without a Docker socket. Redis timed out locally. The unchanged2859e199e2control reproduced the same timeout on this Docker Desktop host; no workaround or weaker assertion was added. Both cases subsequently passed packaged CI, linked above.dotnet test --project tests\Infrastructure.Tests\Infrastructure.Tests.csproj --no-launch-profile -- --filter-class '*.TestTriggerMapTests' --filter-not-trait 'quarantined=true' --filter-not-trait 'outerloop=true'- passed, 176 tests.dotnet run --project tools\SelectTests -- --changed-files artifacts\readiness-changed-files.txt --explain- passed against the real graph/map; Go hosting/codegen, Redis, starter checksum and EF Core fixture inputs select starter-validation/polyglot with zero unattributed files. Schedule-only deployment remains advisory.$env:DOTNET_ROOT = Join-Path $PWD '.dotnet'; $env:ASPIRE_REPO_ROOT = $PWD; .\artifacts\bin\Aspire.Cli\Debug\net11.0\aspire.exe restore --apphost tests\PolyglotAppHosts\<integration>\Go\apphost.go --non-interactive- passed separately forAspire.Hosting.EntityFrameworkCore,Aspire.Hosting.Foundry, andAspire.Hosting, generating actual SDK bindings.docker run --rm --entrypoint bash -v "${PWD}:/workspace" aspire-go-e2e-6972:latest -c 'set -e; for fixture in Aspire.Hosting.EntityFrameworkCore Aspire.Hosting.Foundry Aspire.Hosting; do cd "/workspace/tests/PolyglotAppHosts/$fixture/Go"; gofmt -w apphost.go; go build -buildvcs=false -o /tmp/fixture ./...; go vet ./...; done'- passed for all three fixtures.docker run --rm --entrypoint bash -v "${PWD}:/workspace:ro" aspire-go-e2e-6972:latest -c 'set -e; bash -n /workspace/.github/workflows/polyglot-validation/test-go.sh /workspace/.github/workflows/polyglot-validation/test-go-playground.sh /workspace/eng/scripts/stabilization-smoke-init-restore.sh; work=$(mktemp -d); trap "rm -rf $work" EXIT; cp /workspace/src/Aspire.Cli/Templating/Templates/go-starter/api/* "$work/"; cd "$work"; sed -i "s/{{projectNameLower}}/starter/g" go.mod; go build -mod=readonly -o /tmp/go-ready-api .; go mod tidy -diff; go vet ./...'- passed without a dependency-repair command../restore.sh -p:SkipTestProjects=true -p:SkipPlaygroundProjects=true- passed with the pinned SDK../dotnet.sh pack src/Aspire.Hosting.AppHost/Aspire.Hosting.AppHost.csproj -c Release -p:StabilizePackageVersion=true -p:SkipNativeBuild=true --nologo -v quiet- failed as expected on existing NU5104 preview dependencies; not counted as a stabilization pass.for project in Aspire.Hosting Aspire.Hosting.AppHost Aspire.Hosting.Dotnet Aspire.TypeSystem Aspire.Hosting.CodeGeneration.Go Aspire.Hosting.CodeGeneration.Java Aspire.Hosting.Go Aspire.Hosting.Redis Aspire.Hosting.Java Aspire.Hosting.JavaScript Aspire.AppHost.Sdk Aspire.ProjectTemplates; do ./dotnet.sh pack "src/$project/$project.csproj" -c Release -p:StabilizePackageVersion=true -p:SkipNativeBuild=true -p:WarningsNotAsErrors=NU5104 --nologo -v quiet; done- passed. No suppression is committed; Java remains17.0.0-devby existing policy.STABILIZATION_SMOKE_CONFIGURATION=Release ASPIRE_REPO_ROOT=/work/source bash eng/scripts/stabilization-smoke-init-restore.sh- built the genuine stabilized Release driver/payload and completed the consumer flow. Exit 1 is the expected Java policy failure, not an all-language pass. Go/Redis17.0.0metadata names/work/source/artifacts/packages/Release/Shipping; C#17.0.0restored; Java reached real NuGet restore and rejected its absent stable pin with no nuget.org fallback. Output assertions confirmed the final failure list is exactlyjava. Sources were1ab3ad1e30plus the final smoke correction; no mixed PR-stamped CLI was used.bash -n eng/scripts/stabilization-smoke-init-restore.sh, PowerShell parser validation ofeng\scripts\cli-starter-validation.ps1, andgit diff --check- passed.Infrastructure.Tests.TestTriggerMapnamespace was not passed on this Windows host: WSL'sbash.execannot find/bin/bash; a narrowed run also encountered readonly.gitcleanup failures. Not counted as successful validation.Checklist
<remarks />and<code />elements on your triple slash comments?