ci(windows): split the Windows lane to mirror Linux's lane structure

The Windows CI was a single job running the full ci-windows inventory
(check:ci:windows), while Linux splits into 5 lanes (static/lint/coverage/
snapshot/artifacts) per the parallel-gates RFC. The single-job shape was a
transitional artifact from when Windows CI was added as a non-required
observation lane; its rationale ('keep gate parallelism modest so coverage
is not starved') conflated run-gates intra-job concurrency
(DSH_GATE_CONCURRENCY) with GitHub job fan-out — orthogonal concerns.

Split Windows into 4 lanes mirroring Linux (snapshot absent: its goldens
are Linux-recorded and self-skip on Windows). Each lane is a separate
GitHub job so a Windows regression is attributable to one lane, not
buried in one job's log. Concurrency is NOT throttled versus Linux: the
lane is non-blocking (continue-on-error), and the observational stance
is to actively expose Windows-arm issues rather than hide them behind
reduced parallelism.

- scripts/run-gates.ts: add ci-windows:static/lint/coverage/artifacts
  modes; ci-windows (full inventory) is retained as the local one-process
  entry, symmetric with Linux's ci-primary.
- .github/workflows/ci.yml: windows job becomes a matrix over the 4 lanes.
- package.json: check:ci:windows:{static,lint,coverage,artifacts} scripts.
- AGENTS.md + windows-support RFC: document the per-lane, non-blocking,
  unthrottled stance.

Verified: scripts/caohuanqi-private/run-ci.py --windows (full
check:ci:windows) — all gates green except the known hooks-claude
bridge.spec waitFor timeout (pre-existing Windows subprocess-timing
flake, unrelated).
This commit is contained in:
Huanqi Cao
2026-07-08 12:45:45 +08:00
committed by imccyu
parent fd5931752c
commit 007001677d

View File

@@ -182,17 +182,45 @@ jobs:
- name: Build (tsc -b + tsdown)
run: pnpm run build
# Observational Windows mirror of the Linux gates. Snapshot stays Linux-only
# while its replay goldens remain platform-specific. This job intentionally
# stays out of all-checks-passed.needs.
# 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.
windows-gates:
runs-on: windows-2025
name: windows node 24
name: windows node 24 / ${{ matrix.lane }}
env:
DSH_GATE_CONCURRENCY: '2'
DSH_PUBLINT_CONCURRENCY: '8'
DSH_COVERAGE_MAX_WORKERS: '4'
DSH_ESLINT_CACHE: '1'
DSH_GATE_CONCURRENCY: ${{ matrix.gate_concurrency }}
DSH_PUBLINT_CONCURRENCY: ${{ matrix.publint_concurrency }}
DSH_COVERAGE_MAX_WORKERS: ${{ matrix.coverage_max_workers }}
DSH_ESLINT_CACHE: ${{ matrix.eslint_cache }}
strategy:
fail-fast: false
matrix:
include:
- lane: static
command: pnpm run check:ci:static
gate_concurrency: '4'
publint_concurrency: '8'
coverage_max_workers: ''
eslint_cache: ''
- lane: lint
command: pnpm run check:ci:lint
gate_concurrency: '1'
publint_concurrency: '8'
coverage_max_workers: ''
eslint_cache: '1'
- lane: coverage
command: pnpm run check:ci:coverage
gate_concurrency: '1'
publint_concurrency: '8'
coverage_max_workers: '4'
eslint_cache: ''
- lane: artifacts
command: pnpm run check:ci:artifacts
gate_concurrency: '3'
publint_concurrency: '8'
coverage_max_workers: ''
eslint_cache: ''
steps:
- uses: actions/checkout@v6
@@ -216,6 +244,7 @@ jobs:
run: '"path=$(pnpm store path --silent)" >> $env:GITHUB_OUTPUT'
- uses: actions/cache@v4
if: matrix.lane == 'lint'
with:
path: ${{ steps.pnpm-store.outputs.path }}
key: ${{ runner.os }}-node-${{ env.PRIMARY_NODE_VERSION }}-pnpm-${{ hashFiles('pnpm-lock.yaml') }}
@@ -233,21 +262,9 @@ jobs:
restore-keys: |
${{ runner.os }}-node-${{ env.PRIMARY_NODE_VERSION }}-eslint-
- name: Run static gates
- name: Run gates
shell: powershell
run: pnpm run check:ci:static
- name: Run lint gates
shell: powershell
run: pnpm run check:ci:lint
- name: Run coverage gates
shell: powershell
run: pnpm run check:ci:coverage
- name: Run artifact gates
shell: powershell
run: pnpm run check:ci:artifacts
run: ${{ matrix.command }}
# Single stable required check for branch protection: require "all checks
# passed" instead of enumerating matrix legs whose names change as lanes and