@@ -124,3 +124,105 @@ jobs:
124124 packages/b2c-tooling-sdk/coverage/
125125 packages/b2c-cli/coverage/
126126 retention-days : 30
127+
128+ test-windows :
129+ runs-on : windows-latest
130+ # Advisory rollout: Windows coverage is new; surface failures without
131+ # blocking Linux CI while remaining Windows-specific test issues are
132+ # addressed in follow-up PRs. Remove once Windows tests are green.
133+ continue-on-error : true
134+ defaults :
135+ run :
136+ shell : bash
137+ strategy :
138+ fail-fast : false
139+ matrix :
140+ node-version : [22.x, 24.x]
141+ steps :
142+ - name : Checkout code
143+ uses : actions/checkout@v6
144+ - name : Setup Windows machine
145+ uses : ./.github/actions/setup-windows
146+ with :
147+ node-version : ${{ matrix.node-version }}
148+ - name : Build packages
149+ run : pnpm -r run build
150+ - name : Run SDK tests
151+ id : sdk-test
152+ working-directory : packages/b2c-tooling-sdk
153+ run : pnpm run pretest && pnpm run test:ci && pnpm run lint
154+ - name : Run MCP tests
155+ id : mcp-test
156+ if : always() && steps.sdk-test.conclusion != 'cancelled'
157+ working-directory : packages/b2c-dx-mcp
158+ run : pnpm run pretest && pnpm run test:ci && pnpm run lint
159+ - name : Run CLI tests
160+ id : cli-test
161+ if : always() && steps.mcp-test.conclusion != 'cancelled'
162+ working-directory : packages/b2c-cli
163+ # Use the Windows-specific script (test:ci:win) to bypass c8's
164+ # coverage threshold check. V8 coverage on Windows double-counts
165+ # some TS source files (distinct URL casing emitted by the tsx
166+ # loader), which drops the reported function-coverage number below
167+ # the Linux-calibrated 70% threshold even though the tests pass.
168+ # Coverage is still generated and uploaded for inspection.
169+ run : pnpm run pretest && pnpm run test:ci:win && pnpm run lint
170+ - name : Run VS Extension checks
171+ if : always() && steps.cli-test.conclusion != 'cancelled'
172+ working-directory : packages/b2c-vs-extension
173+ run : pnpm run typecheck:agent && pnpm run lint
174+ - name : Print Windows test failures
175+ # Mocha's JSON reporter swallows stdout, so Windows-only failures are
176+ # invisible in the step log. Parse the per-package test-results.json
177+ # and echo failing test titles + error messages to the job log for triage.
178+ if : always() && steps.sdk-test.conclusion != 'cancelled'
179+ shell : bash
180+ run : |
181+ node -e "
182+ const fs = require('node:fs');
183+ const path = require('node:path');
184+ const reports = [
185+ 'packages/b2c-tooling-sdk/test-results.json',
186+ 'packages/b2c-dx-mcp/test-results.json',
187+ 'packages/b2c-cli/test-results.json',
188+ ];
189+ let totalFailures = 0;
190+ for (const report of reports) {
191+ if (!fs.existsSync(report)) continue;
192+ const data = JSON.parse(fs.readFileSync(report, 'utf8'));
193+ const failures = data.failures || [];
194+ if (failures.length === 0) continue;
195+ totalFailures += failures.length;
196+ console.log('\n=== ' + report + ' (' + failures.length + ' failures) ===');
197+ for (const f of failures) {
198+ console.log('\n✖ ' + f.fullTitle);
199+ if (f.err && f.err.message) console.log(' message: ' + f.err.message.split('\n')[0]);
200+ if (f.err && f.err.stack) console.log(' stack: ' + f.err.stack.split('\n').slice(0, 5).join('\n '));
201+ }
202+ }
203+ if (totalFailures === 0) console.log('No Windows test failures reported.');
204+ else console.log('\nTotal Windows failures: ' + totalFailures);
205+ "
206+ - name : Test Report
207+ uses : dorny/test-reporter@a43b3a5f7366b97d083190328d2c652e1a8b6aa2 # v3.0.0
208+ if : always() && steps.sdk-test.conclusion != 'cancelled'
209+ with :
210+ name : Test Results (Windows Node ${{ matrix.node-version }})
211+ path : ' packages/*/test-results.json'
212+ reporter : mocha-json
213+ - name : Upload test results (for Windows triage)
214+ if : always() && steps.sdk-test.conclusion != 'cancelled'
215+ uses : actions/upload-artifact@v7
216+ with :
217+ name : test-results-windows-node-${{ matrix.node-version }}
218+ path : ' packages/*/test-results.json'
219+ retention-days : 30
220+ - name : Upload coverage reports
221+ if : always() && steps.sdk-test.conclusion != 'cancelled'
222+ uses : actions/upload-artifact@v7
223+ with :
224+ name : coverage-reports-windows-node-${{ matrix.node-version }}
225+ path : |
226+ packages/b2c-tooling-sdk/coverage/
227+ packages/b2c-cli/coverage/
228+ retention-days : 30
0 commit comments