Skip to content

Isolate WinUI E2E design-time build outputs - #20116

Merged
Ella Hathaway (ellahathaway) merged 1 commit into
mainfrom
ellahathaway-winui-ci-failure
Sep 21, 2026
Merged

Ella Hathaway (ellahathaway) merged 1 commit into
mainfrom
ellahathaway-winui-ci-failure

Conversation

@ellahathaway

@ellahathaway Ella Hathaway (ellahathaway) commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Description

Prevent the WinUI extension E2E fixture's C# design-time builds from contending with Aspire's real XAML compilation. The one-time readiness barrier in #19947 does not cover later Roslyn watched-file reloads: run 34791816809 failed with an input.json sharing violation while such a reload overlapped the CLI build.

  • Give DesignTimeBuild=true its own intermediate directory under obj\design-time\. This separates the XAML compiler's JSON inputs/outputs, generated code, and saved state while preserving normal build outputs and the shared obj\project.assets.json restore assets.
  • Require the E2E definition probe to resolve InitializeComponent from that project's isolated directory, not the real build's output or another project's generated code.
  • Add fixture-generation and probe regression coverage and correct the contributor documentation. Keep the pinned debugger/WinUI dependencies and the actual build, debugger launch, and Application.OnLaunched proof unchanged.

Related to the concurrent XAML build failure recorded in #19935. The issue also lists run 34806422379, where the WinUI test passed and subsequent diagnostics collection failed copying a Dashboard .lock file. That distinct diagnostics-copy bug is addressed independently by #20127; neither fix depends on the other.

Before/after workflow reproduction

Ran the existing reproduce-flaky-tests.yml through an investigation-only MTP probe of the actual WinUI compiler: three Windows x64 runners, three executions per runner, for each version.

Tested generator Workflow run Actual result
Before: e4799ef9c44d5203f58cd193e41c4516fe433c83 34883271670 9/9 reproduce the intended XAML input.json sharing violation; no setup failures or skipped tests
Fixed: fbeab54212f092052a3f752ab50d30aef8486475 34884704921 9/9 pass, no failures or skipped tests; real XAML outputs regenerated in every execution

Each probe verifies restore and an unlocked capability build, runs design-time compilation, then holds its input.json exclusively while running the normal WinUI build. Before the fix, the real XAML compiler fails on that held file. After the fix, the normal build succeeds and regenerates its own XAML outputs while the design-time input remains locked. Evaluated properties confirm separate intermediate directories and the same NuGet assets file.

The probe is identical between phases: the only workflow-head difference is the selected generator source ref. Both workflow runs used attempt 1. Investigation code/configuration is not part of this PR.

This is a controlled reproduction of the file-contention mechanism, not a spontaneous Roslyn/UI timing reproduction or a measurement of the natural flake rate. The real debugger scenario is covered separately below.

Additional validation

Check Result
Windows x64 extension unit tests 2,974 passing, 8 pending; all four WinUI guards passed
Pinned Windows x64 WinUI E2E 1 real test passed, 0 pending, 0 failures; 61.5 seconds
Full PR CI Succeeded on attempt 3; only the Windows browser-debugger shard required reruns
Local Windows ARM64 Controlled before/after lock proof, reverse-direction lock proof, extension/CLI build, unit/E2E TypeScript compilation, ESLint, runner syntax, and focused Mocha tests passed

The WinUI E2E and unit jobs passed on CI attempt 1. Later attempts retained their original results and timestamps; they are not additional WinUI executions. The standard local VS Code unit host failed to load its workbench before running tests, so local source-only coverage used the installed Mocha runner; the standard Windows CI unit host subsequently passed. One initial local cold ExTester import exceeded its existing timeout and passed unchanged on the focused rerun.

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

This fix was developed using the fix-flaky-test skill.

Keep Roslyn XAML inputs, generated code, and saved state separate from Aspire's real build while preserving NuGet restore assets and normal outputs. Require the E2E definition probe to resolve the isolated generated source.

Related to #19935.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@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 -- 20116

Or

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

@github-actions

Copy link
Copy Markdown
Contributor

Tests selector

0 / 99 PR test projects · 2 PR jobs · 0 advisory-only targets, from 3 changed files.

Selected PR test projects (0 / 99)

none — no PR-gated .NET test projects run for this change.

Selected PR jobs (2)

extension-e2e, extension-unit

Advisory workflow impact (0)

none


How these were chosen — grouped by what changed

Job reasons

Job Triggered by
extension-e2e extension/scripts/run-e2e.js, extension/src/test-e2e/winUiDebug.e2e.test.ts, extension/src/test/e2eLaunchProfile.test.ts
extension-unit extension/scripts/run-e2e.js, extension/src/test-e2e/winUiDebug.e2e.test.ts, extension/src/test/e2eLaunchProfile.test.ts

Selection computed for commit fbeab54.

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.

🔵 Needs a closer look

The architecture-matching Windows x64 E2E validation remains pending and the PR is marked incomplete.

Pull request overview

Isolates WinUI E2E design-time intermediates to prevent XAML compiler contention.

Changes:

  • Routes design-time outputs to obj\design-time\.
  • Restricts readiness probes to isolated generated definitions.
  • Adds regression coverage and updates contributor guidance.
File summaries
File Description
extension/scripts/run-e2e.js Configures isolated intermediates.
extension/src/test-e2e/winUiDebug.e2e.test.ts Tightens definition probing.
extension/src/test/e2eLaunchProfile.test.ts Adds regression tests.
extension/CONTRIBUTING.md Documents isolation behavior.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 0
  • Review effort level: Balanced

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

@github-actions

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

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.

@ellahathaway
Ella Hathaway (ellahathaway) merged commit 2e90e5e into main Sep 21, 2026
242 of 248 checks passed
@github-actions github-actions Bot added this to the 13.6 milestone Sep 21, 2026
@aspire-repo-bot

Copy link
Copy Markdown
Contributor

✅ No documentation update needed.

Step 5 branch taken: docs_optional → internal_refactor

Triggered signals: none (signal_count: 0, triggered_signals: []). recommendation was docs_optional in .pr-docs-check/signals.json.

Changed-file evidence for the allowlist category:

  • extension/CONTRIBUTING.md — contributor-facing build/test instructions in the source repo, not user-facing product documentation shipped on microsoft/aspire.dev.
  • extension/scripts/run-e2e.js — internal E2E test runner script wiring, no new CLI/API surface.
  • extension/src/test-e2e/winUiDebug.e2e.test.ts — test-only change (adjusts the WinUI E2E fixture to use an isolated design-time build directory).
  • extension/src/test/e2eLaunchProfile.test.ts — new regression test coverage only.

All 4 changed files are test/build-tooling artifacts for the VS Code extension's E2E fixture generation (isolating DesignTimeBuild=true output into its own obj\design-time\ directory to avoid a file-locking race with the real XAML compiler during CI). The PR introduces no new public API, CLI option, MCP tool, dashboard page, container image, or other product-facing surface — it only changes internal build isolation and adds test coverage for it, confirmed by the PR title/body ("Isolate WinUI E2E design-time build outputs", fixing a flaky-test file-contention bug). This matches the internal_refactor / build_or_ci_only allowlist categories, so no microsoft/aspire.dev documentation update is warranted.

Ella Hathaway (ellahathaway) added a commit that referenced this pull request Sep 21, 2026
## Description

Related to the diagnostics-copy failure in #19935. This is independent
of the WinUI build-race fix in #20116.

E2E tests could pass but still fail CI when diagnostics collection tried
to copy live Dashboard or cache lock files. A failed copy also prevented
other useful logs from being collected.

This change:
- Collects intended logs, settings, AppHost metadata, screenshots, and
fixture sources instead of runtime caches and coordination files.
- Attempts each file/source independently and redacts text before saving
it. Unexpected errors remain visible without preventing collection of
the remaining diagnostics.
- Uploads the four prepared diagnostics directories, making the
collector the single place that decides which files to retain.

## Verification

| Check | Result |
| --- | --- |
| [Windows x64 controlled
reproduction](https://github.com/microsoft/aspire/actions/runs/35036528090)
| Nine baseline executions reproduced the expected regressions. Nine
fixed executions passed all 18 tests: **162 passes, no failures or
skips**. The collector and test suite are unchanged in the current
revision. |
| [Normal CI at
`3489dec`](https://github.com/microsoft/aspire/actions/runs/35037142483)
| **2,990 unit tests passed**; 8 pending. Seven Windows/Linux E2E
scenarios passed. Five actual uploaded artifacts were inspected:
intended diagnostics and redaction were retained, without runtime caches
or leases. |
| Upload simplification at `e06beb05` | Compilation, lint, YAML checks,
and **19 focused local tests passed**. [New-head
CI](https://github.com/microsoft/aspire/actions/runs/35126760543) passed
at merge `809038ea`: **3,003 unit tests passed** (8 pending), plus seven
E2E scenario tests. Five Windows/Linux artifacts (340 files) retained
intended diagnostics and redaction without runtime caches or leases. |

<details>
<summary>PR checklist</summary>

## Checklist

- Is this feature complete?
  - [x] Yes. Ready to ship.
  - [ ] No. Follow-up changes expected.
- Are you including unit tests for the changes and scenario tests if
relevant?
  - [x] 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
  - [x] 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
  - [x] No

</details>

---------

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

Copy link
Copy Markdown
Contributor

⚠️ CI Failure Analysis: Possible Flaky Test(s)

The CI build failed due to test failure(s) that appear unrelated to the PR changes. These may be flaky tests.

Suspected flaky test(s):

  • Aspire.Hosting.Tests.DistributedApplicationTests.StartAsync_DashboardAuthConfig_PassedToDashboardProcess(tokenEnvVarName: "ASPIRE_DASHBOARD_FRONTEND_BROWSERTOKEN") in job Tests / No-package tests (collection, Aspire.Hosting.Tests, Hosting-1, Hosting-1, tests/Aspire.Hosting.Te... / Hosting-1 (8-core-ubuntu-latest)
    • Error: System.Threading.Tasks.TaskCanceledException : A task was canceled.
    • Stack Trace (first frames):
at Microsoft.Extensions.Hosting.Internal.Host.ForeachService[T](IEnumerable`1 services, CancellationToken token, Boolean concurrent, Boolean abortOnFirstException, List`1 exceptions, Func`3 operation)
   at Microsoft.Extensions.Hosting.Internal.Host.StopAsync(CancellationToken cancellationToken)
   at Aspire.Hosting.DistributedApplication.StopAsync(CancellationToken cancellationToken) in /_/src/Aspire.Hosting/DistributedApplication.cs:line 497
   at Microsoft.AspNetCore.InternalTesting.AsyncTestHelpers.TimeoutAfter(Task task, TimeSpan timeout, String filePath, Int32 lineNumber) in /home/runner/work/aspire/aspire/tests/Shared/AsyncTestHelpers.cs:line 190
   at Aspire.Hosting.Tests.DistributedApplicationTests.StartAsync_DashboardAuthConfig_PassedToDashboardProcess(String tokenEnvVarName) in /home/runner/work/aspire/aspire/tests/Aspire.Hosting.Tests/DistributedApplicationTests.cs:line 1402
  • Why likely flaky: The test times out during application shutdown (DistributedApplication.StopAsync), a symptom of CI resource contention/timing rather than any behavior touched by this PR, which only modifies VS Code extension E2E test files.
  • Aspire dynamic debug configuration E2E "after each" hook for "re-resolves the selected AppHost by dynamic configuration name in duplicate-alias workspaces" in job Tests / Run VS Code extension E2E tests / VS Code extension E2E (Windows, dynamic-debug-configuration)
    • Error: Dynamic debug configuration E2E teardown failed.
  1. Error: EBUSY: resource busy or locked, rmdir 'C:\Users\runneradmin\AppData\Local\Temp\aev-UJSZ5O\workspace.e2e-dynamic-debug\first'
  • Stack Trace (first frames):
AggregateError: Dynamic debug configuration E2E teardown failed.
1. Error: EBUSY: resource busy or locked, rmdir 'C:\Users\runneradmin\AppData\Local\Temp\aev-UJSZ5O\workspace\.e2e-dynamic-debug\first'
    at runE2eTeardown (out\test-e2e\test-e2e\helpers\fixtures.js:217:15)
    at async Context.<anonymous> (out\test-e2e\test-e2e\dynamicDebugConfiguration.e2e.test.js:62:9)
  • Why likely flaky: Exact match to a previously observed recurring Windows-only teardown failure (EBUSY on rmdir of temp workspace) that occurs across many unrelated PRs, indicating a file-lock race condition in test cleanup rather than a PR-introduced regression.

Suggested actions:

  • Re-run the failed CI jobs to confirm if the failure is intermittent
  • If the test continues to fail, consider quarantining it using /quarantine-test <test name> <issue URL>
  • Search existing issues to see if this test is already known to be flaky

You can re-run the failed jobs from the workflow run page.

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.

3 participants