ci(windows): run the observational gate wrapper in pwsh — an MSYS parent leaks into the suite

The lane-split merge moved the Run gates step to `shell: bash`, which
broke it twice over. First, GHA's bash shell runs with -e, so a failing
gate aborted the step before the ::warning::/exit 0 lines — the lane
went red X instead of the intended yellow warning. Second, and worse,
Git Bash as the PARENT of the gate run leaks MSYS environment into the
suite itself, producing 8 real test failures the pwsh-launched runs
(and the DSec VM runs) never saw:

- bash exports PWD; the MSYS runtime rewrites it to Windows form for
  native children, dsh-bash-local's adaptEnv passes it through, and the
  executor's MSYS bash adopts it — `pwd` prints `D:/a/...` where the
  tests (and the executor's MSYS dialect) expect `/d/a/...` (7 tests).
- cygwin enables SeBackupPrivilege on the runner's admin token; children
  inherit the enabled state, and libuv's FILE_FLAG_BACKUP_SEMANTICS read
  opens then pierce the dwShareMode=0 lock the jsonl EBUSY test holds —
  loadLive resolves instead of rejecting (1 test).

Evidence: run 28918325498 (pwsh step, pre-merge) failed only the two
hooks dispose tests since fixed by f8fd8c00; run 28921741006 (bash
step) fixed those and failed exactly the 8 above, with zero relevant
source diff between them.

Fix: run the wrapper in pwsh — a native command's failure doesn't abort
pwsh, so $LASTEXITCODE capture + ::warning:: + exit 0 works without an
errexit dance, and the gates start from a native Windows shell as they
do everywhere else Windows CI has been validated.

Docs: the windows-support RFC drops the stale continue-on-error wording
(replaced by the warning wrapper) and records the launch-environment
limitation — native shell required today; making an MSYS parent a
supported launch environment (PWD scrub in adaptEnv, privilege-explicit
tests) is a future improvement direction.
This commit is contained in:
Huanqi Cao
2026-07-08 14:57:20 +08:00
committed by imccyu
parent 007001677d
commit cb69ca80d6

View File

@@ -183,8 +183,8 @@ jobs:
run: pnpm run build
# Observational Windows mirror of the Linux gate lanes. Snapshot stays
# Linux-only while its replay goldens remain platform-specific. Splitting the
# lanes makes failures attributable without changing their non-gating role.
# Linux-only while its replay goldens remain platform-specific. The wrapper
# runs from native PowerShell 7 so an MSYS parent cannot leak into the suite.
windows-gates:
runs-on: windows-2025
name: windows node 24 / ${{ matrix.lane }}
@@ -225,7 +225,7 @@ jobs:
- uses: actions/checkout@v6
- name: Enable Developer Mode (symlink support)
shell: powershell
shell: pwsh
run: >-
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock"
/t REG_DWORD /f /v "AllowDevelopmentWithoutDevLicense" /d "1"
@@ -235,12 +235,12 @@ jobs:
node-version: ${{ env.PRIMARY_NODE_VERSION }}
- name: Enable corepack (pnpm)
shell: powershell
shell: pwsh
run: corepack enable
- name: Resolve pnpm store path
id: pnpm-store
shell: powershell
shell: pwsh
run: '"path=$(pnpm store path --silent)" >> $env:GITHUB_OUTPUT'
- uses: actions/cache@v4
@@ -252,7 +252,7 @@ jobs:
${{ runner.os }}-node-${{ env.PRIMARY_NODE_VERSION }}-pnpm-
- name: Install (immutable)
shell: powershell
shell: pwsh
run: pnpm install --frozen-lockfile
- uses: actions/cache@v4
@@ -263,8 +263,13 @@ jobs:
${{ runner.os }}-node-${{ env.PRIMARY_NODE_VERSION }}-eslint-
- name: Run gates
shell: powershell
run: ${{ matrix.command }}
shell: pwsh
run: |
${{ matrix.command }}
if ($LASTEXITCODE -ne 0) {
Write-Output "::warning::Windows lane '${{ matrix.lane }}' failed (exit $LASTEXITCODE) — observational, does not block merge. See logs above."
}
exit 0
# Single stable required check for branch protection: require "all checks
# passed" instead of enumerating matrix legs whose names change as lanes and