Fix Windows CI path gating and capture UIA startup diagnostics - #506
Merged
Merged
Conversation
Fetch complete PR history before changed-path classification, retain fail-safe path mapping, and capture bounded UIA host and process evidence. Verify cleanup of process trees owned by validation before the live gate. Signed-off-by: Colin Neilens <coneilen@microsoft.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Two related defects, both of which amount to CI doing work it doesn't need to do, and then failing on it.
1. Path-based CI gating has never worked on pull requests
Every gated workflow classifies changed paths in a
changesjob that checks out with:This hits the GitHub Actions falsy-zero trap. On a pull request the expression evaluates
true && 0->0, and0is falsy in GHA expressions, so0 || 1->1. The intended full-history checkout never happened; the clone was always shallow.The consequence, from the classify job of run
36497626173(windows-shellon #505):The shallow clone does not contain the base commit, so
git diff base...headfails, andclassify-changes.shcorrectly fails safe by running every suite. The classifier was never the problem — the checkout was. Net effect: no pull request has ever skipped a gated suite by path classification. A one-file Markdown change paid for the full macOS, Linux and Windows suites.2. A UIA startup failure produces no usable diagnostics
The
windows-shellandwindows-spikesjobs have been intermittently failing at the Native UI Automation live gate — four occurrences across three pull requests, with an identical signature:0xC0000142isSTATUS_DLL_INIT_FAILED: the process is created but dies during loader/DLL initialisation, before reaching a message loop. Critically, the gate captured nothing — childstderrwasownership_unavailable,stdoutwasnot_captured, and the application log went unread. That is precisely why four failures yielded no root cause.The gate also already admitted its own teardown was unverified:
The two defects compound: because gating never worked, a documentation-only pull request was exposed to a Windows-only loader flake it had no way to trigger.
Change
Gating —
.github/workflows/{linux,macos-shared-regression,windows-hardening,windows-port-validation,windows-shell}.ymlchangesjob now uses a literalfetch-depth: 0, so the base commit is present and the diff computes.classify-changes.shfail-safe behaviour is unchanged: an unclassified path, an empty path list, or an uncomputable diff still runs every suite.Classifier —
Tools/ci/classify-changes.shTools/icon/*is classified as a macOS input, andinvestigation/macos-parity-evidence/evidence/*is classified as documentation.*.pngskipping was deliberately rejected as unsafe — icon sources and visual baselines are genuine suite inputs. An arbitrary unknown.pngstill falls through to "unclassified -> run everything".UIA diagnostics —
Tools/windows/uia-live-gate.ps1,Tools/windows/validate.ps1validate.ps1snapshots product processes at task entry and terminates — then verifies the termination of — only newly created matching processes under this worktree before the UIA gate launches.Tests —
Tools/ci/tests/classify-changes.test.sh,Tools/windows/Tests/ValidationRunner.Tests.ps1Test evidence
RED:
bash Tools/ci/tests/classify-changes.test.sh-> 50 passed, 5 failed; every classifierchangesjob still carried the falsy&& 0 || 1fetch-depth expression.GREEN:
bash Tools/ci/tests/classify-changes.test.sh-> 58 passed, 0 failed, including a synthetic full-history docs-only diff classifiedwindows=false macos=false linux=false.REGRESSION:
. .\.graphcode-tools\environment.ps1; & .\Tools\windows\Tests\ValidationRunner.Tests.ps1-> PASS, exercising bounded and redacted stderr/stdout/app-log capture, native session/window-station/desktop reporting, and verified cleanup of a controlled descendant tree;git diff --check origin/main...HEAD-> exit 0.Independently re-verified by the coordinator from a clean worktree of this branch: the suite reports
58 passed, 0 failed; the docs-only commitec2dda32classifieswindows=false macos=false linux=false;investigation/macos-parity-evidence/evidence/foo.pngclassifies as docs;some/random/thing.pngstill yieldswindows=true macos=true linux=truewithunclassified path ... running every suite; and an uncomputablebase...headdiff still fails safe to all suites.What this does not establish
Stated plainly, because the loader failure is the reason this branch exists:
Tools/ci/*is self-gating, so this branch correctly runs every suite and cannot demonstrate a skip. The fixed expression and the classifier tests are the evidence; the first real skip will only be observable on a later docs-only pull request.Checklist
git commit -s); DCO cleanRED:/GREEN:/REGRESSION:lines incommand -> resultform, from commands actually runinvestigation/ui-parity-matrix.mduntouched)graphcode-windows/src/**changes; no excluded surfaces touchedPATH