authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-09-03 19:30:37-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-03 19:30:37-07:00
logf96a220b5b154ea44c94bf43929c6362cd511699
tree49018363d85c498cd2c11dd6cdb0233b6ab54b46
parent4e547318b60031eb546d8cf2b84ad9fa0785a87a
signature Signed by PGP key B5690EEEBB952194

ci: add on-demand Windows test workflow (#9538)

Co-authored-by: Claude Code <noreply@anthropic.com>

3 files changed, 92 insertions(+), 1 deletions(-)

.github/workflows/windows-tests.yml created+81
......@@ -0,0 +1,81 @@
1# On-demand Windows test lane. Manual only: nothing in the suite passes on
2# Windows yet, so this exists to give contributors (and agents) a cloud Windows
3# box to iterate against. Once the suite is green here, fold it into ci.yml.
4#
5# gh workflow run windows-tests.yml --ref <branch> -f package=packages/shared
6# gh workflow run windows-tests.yml --ref <branch> -f package=apps/server \
7# -f files="src/process/externalLauncher.test.ts src/cli/theme.test.ts"
8# gh run watch && gh run view --log-failed
9name: Windows Tests
10
11on:
12 workflow_dispatch:
13 inputs:
14 package:
15 description: "Workspace directory to test, e.g. apps/server or packages/shared. Empty runs every package except apps/server."
16 type: string
17 default: ""
18 files:
19 description: "Space-separated test files relative to the package directory. Empty runs the package's whole suite. Requires package."
20 type: string
21 default: ""
22
23permissions:
24 contents: read
25
26jobs:
27 test:
28 name: Test (${{ inputs.package || 'all non-server' }})
29 runs-on: blacksmith-8vcpu-windows-2025
30 timeout-minutes: 45
31 steps:
32 - name: Checkout
33 uses: actions/checkout@v6
34 with:
35 sparse-checkout: |
36 /*
37 !/.repos/
38 sparse-checkout-cone-mode: false
39
40 # setup-vp's own cache restores a Linux-shaped store on Windows, which is
41 # slower than no cache (see #7975). Cache pnpm's Windows store directly.
42 - name: Setup Vite+
43 uses: voidzero-dev/setup-vp@v1
44 with:
45 node-version-file: package.json
46 cache: false
47 run-install: false
48
49 - name: Resolve package cache path
50 id: package_cache_path
51 shell: pwsh
52 run: '"path=$(vp pm cache dir)" >> $env:GITHUB_OUTPUT'
53
54 - name: Cache packages
55 uses: actions/cache@v6
56 with:
57 path: ${{ steps.package_cache_path.outputs.path }}
58 key: windows-tests-packages-v1-${{ hashFiles('pnpm-lock.yaml') }}
59
60 - name: Install
61 run: vp install
62
63 - name: Ensure Electron runtime is installed
64 if: inputs.package == '' || inputs.package == 'apps/desktop'
65 run: vp run --filter "@t3tools/desktop" ensure:electron
66
67 # `vp run ... test -- <files>` does not forward positional args to vitest,
68 # so file-scoped runs call `vp test run` inside the package instead.
69 - name: Test
70 shell: pwsh
71 run: |
72 $package = '${{ inputs.package }}'
73 $files = '${{ inputs.files }}'
74 if ($package -eq '') {
75 vp run --parallel --concurrency-limit 4 --filter '!t3' --filter '!@t3tools/monorepo' test
76 } elseif ($files -eq '') {
77 vp run --filter "./$package" test
78 } else {
79 Set-Location $package
80 vp test run $files.Split(' ')
81 }
apps/desktop/scripts/ensure-electron-runtime.mjs+3-1
......@@ -2,6 +2,7 @@ import * as NodeFS from "node:fs";
22import * as NodeModule from "node:module";
33import * as NodeOS from "node:os";
44import * as NodePath from "node:path";
5import * as NodeURL from "node:url";
56import * as NodeChildProcess from "node:child_process";
67
78const require = NodeModule.createRequire(import.meta.url);
......@@ -176,7 +177,8 @@ export function ensureElectronRuntime() {
176177 return electronPath;
177178}
178179
179if (import.meta.url === `file://${process.argv[1]}`) {
180// `file://${argv[1]}` never matches on Windows (drive letters need `file:///C:/`).
181if (process.argv[1] && NodeURL.pathToFileURL(process.argv[1]).href === import.meta.url) {
180182 const electronPath = ensureElectronRuntime();
181183 process.stdout.write(`${electronPath}\n`);
182184}
docs/internals/ci.md+8
......@@ -22,6 +22,14 @@ and pushes to `main`:
2222- **Release Smoke**: exercises release-only workflow steps through `scripts/release-smoke.ts`, so
2323 release breakage surfaces on PRs rather than at tag time.
2424
25[`.github/workflows/windows-tests.yml`](../../.github/workflows/windows-tests.yml) is a manual
26Windows lane (`workflow_dispatch` only) on a Blacksmith Windows 2025 runner. The suite does not
27pass on Windows yet, so it is not a required check; it exists so the work to get there can be
28iterated against a real Windows box without one on hand. Dispatch it with `gh workflow run
29windows-tests.yml --ref <branch>`, optionally with `-f package=<dir>` to run one workspace package
30and `-f files="<paths>"` to run specific test files inside it. Once it is green, fold it into
31`ci.yml`.
32
2533`.github/workflows/release.yml` builds macOS (`arm64` and `x64`), Linux (`x64`), and Windows (`x64`)
2634desktop artifacts from a single `v*.*.*` tag and publishes one GitHub release. It auto-enables
2735signing only when platform credentials are present. macOS passkey builds additionally require