From 7cb79dcfd368e23649be5c71b65c8e630f697e59 Mon Sep 17 00:00:00 2001 From: MK Date: Tue, 7 Jul 2026 16:39:03 +0800 Subject: [PATCH 01/10] ci: run Windows jobs on Namespace runners Swap windows-latest -> namespace-profile-windows-x64-default for the movable Windows jobs in ci.yml, e2e-test.yml, and test-standalone-install.yml, matching how Linux and macOS already use Namespace profiles. Windows-specific if: conditions move from matrix.os == 'windows-latest' to the label-independent runner.os == 'Windows', and e2e-test's exclude rules follow the new label. Left on GitHub-hosted runners: the windows-11-arm install test (Namespace has no Windows ARM64) and reusable-release-build.yml (ships MSVC-native user binaries). Requires a namespace-profile-windows-x64-default profile (Windows Server 2022, amd64) in the Namespace dashboard. --- .github/workflows/ci.yml | 24 +++++++++---------- .github/workflows/e2e-test.yml | 16 ++++++------- .github/workflows/test-standalone-install.yml | 10 ++++---- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4553f66b2c..502f806cea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -230,7 +230,7 @@ jobs: test-windows: needs: build-windows-tests name: Test (Windows) - runs-on: windows-latest + runs-on: namespace-profile-windows-x64-default steps: - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 - uses: ./.github/actions/clone @@ -374,7 +374,7 @@ jobs: target: x86_64-unknown-linux-gnu - os: namespace-profile-mac-default target: aarch64-apple-darwin - - os: windows-latest + - os: namespace-profile-windows-x64-default target: x86_64-pc-windows-msvc runs-on: ${{ matrix.os }} steps: @@ -498,7 +498,7 @@ jobs: node --version - name: Test global package install (cmd) - if: ${{ matrix.os == 'windows-latest' }} + if: ${{ runner.os == 'Windows' }} shell: cmd run: | echo "PATH: %PATH%" @@ -682,7 +682,7 @@ jobs: } - name: Test upgrade (cmd) - if: ${{ matrix.os == 'windows-latest' }} + if: ${{ runner.os == 'Windows' }} shell: cmd run: | REM See bash block above for why we assert on the install dir basename. @@ -719,7 +719,7 @@ jobs: ) - name: Test same-version forced upgrade (Windows) - if: ${{ matrix.os == 'windows-latest' }} + if: ${{ runner.os == 'Windows' }} shell: pwsh run: | # Force-reinstall the published `latest` version rather than the local @@ -771,7 +771,7 @@ jobs: } - name: Test same-version forced upgrade (Unix) - if: ${{ matrix.os != 'windows-latest' }} + if: ${{ runner.os != 'Windows' }} shell: bash run: | # Unix mirror of the Windows same-version forced-upgrade test above. @@ -877,7 +877,7 @@ jobs: vp --version - name: Test implode (cmd) - if: ${{ matrix.os == 'windows-latest' }} + if: ${{ runner.os == 'Windows' }} shell: cmd run: | REM Retry — Windows file locks can cause transient "Access is denied" errors @@ -932,15 +932,15 @@ jobs: target: aarch64-apple-darwin shard: 3 shardTotal: 3 - - os: windows-latest + - os: namespace-profile-windows-x64-default target: x86_64-pc-windows-msvc shard: 1 shardTotal: 3 - - os: windows-latest + - os: namespace-profile-windows-x64-default target: x86_64-pc-windows-msvc shard: 2 shardTotal: 3 - - os: windows-latest + - os: namespace-profile-windows-x64-default target: x86_64-pc-windows-msvc shard: 3 shardTotal: 3 @@ -1099,7 +1099,7 @@ jobs: - download-previous-rolldown-binaries - build-windows-cli - build-windows-tests - runs-on: windows-latest + runs-on: namespace-profile-windows-x64-default steps: - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 - uses: ./.github/actions/clone @@ -1358,7 +1358,7 @@ jobs: sfw_asset: sfw-free-macos-arm64 vp_bin: vp vp_insecure_tls: '' - - os: windows-latest + - os: namespace-profile-windows-x64-default target: x86_64-pc-windows-msvc sfw_asset: sfw-free-windows-x86_64.exe # On Windows vp ships as `vp.exe`; sfw spawns its child process diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index f82bf786b3..ec87d991e9 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -101,7 +101,7 @@ jobs: include: - os: ubuntu-latest target: x86_64-unknown-linux-gnu - - os: windows-latest + - os: namespace-profile-windows-x64-default target: x86_64-pc-windows-msvc steps: - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 @@ -189,7 +189,7 @@ jobs: matrix: os: - ubuntu-latest - - windows-latest + - namespace-profile-windows-x64-default project: - name: vibe-dashboard node-version: 24 @@ -398,27 +398,27 @@ jobs: vp run test:coverage exclude: # frm-stack uses Docker (testcontainers) which doesn't work the same way on Windows - - os: windows-latest + - os: namespace-profile-windows-x64-default project: name: frm-stack # dify only runs on Linux for now - - os: windows-latest + - os: namespace-profile-windows-x64-default project: name: dify # vinext uses workerd native deps that don't build on Windows - - os: windows-latest + - os: namespace-profile-windows-x64-default project: name: vinext # yaak is a Tauri app with Rust/wasm deps - - os: windows-latest + - os: namespace-profile-windows-x64-default project: name: yaak # npmx.dev is a Nuxt app, ubuntu-only for now - - os: windows-latest + - os: namespace-profile-windows-x64-default project: name: npmx.dev # varlet upstream CI is ubuntu-only - - os: windows-latest + - os: namespace-profile-windows-x64-default project: name: varlet diff --git a/.github/workflows/test-standalone-install.yml b/.github/workflows/test-standalone-install.yml index b3ffbe8f12..b7800056fb 100644 --- a/.github/workflows/test-standalone-install.yml +++ b/.github/workflows/test-standalone-install.yml @@ -329,7 +329,7 @@ jobs: test-install-ps1-v5: name: Test install.ps1 (Windows x64, PowerShell 5.1) - runs-on: windows-latest + runs-on: namespace-profile-windows-x64-default permissions: contents: read steps: @@ -478,7 +478,7 @@ jobs: test-install-ps1-v76: name: Test install.ps1 (Windows x64, PowerShell 7.6) - runs-on: windows-latest + runs-on: namespace-profile-windows-x64-default permissions: contents: read steps: @@ -558,7 +558,7 @@ jobs: test-install-ps1-release-age: name: Test install.ps1 (minimum-release-age) - runs-on: windows-latest + runs-on: namespace-profile-windows-x64-default permissions: contents: read steps: @@ -636,7 +636,7 @@ jobs: test-install-ps1: name: Test install.ps1 (Windows x64) - runs-on: windows-latest + runs-on: namespace-profile-windows-x64-default permissions: contents: read steps: @@ -789,7 +789,7 @@ jobs: test-vp-setup-exe: name: Test vp-setup.exe (pwsh) - runs-on: windows-latest + runs-on: namespace-profile-windows-x64-default permissions: contents: read steps: From d7ce6e5bb5f4b6beab61bd8d747142fcf00f8dd4 Mon Sep 17 00:00:00 2001 From: MK Date: Tue, 7 Jul 2026 20:19:52 +0800 Subject: [PATCH 02/10] ci: use inline nscloud Windows runner label Switch the Windows runs-on labels from a namespace-profile-* label to the inline nscloud-windows-2022-amd64-8x16 form. Inline labels need no Namespace dashboard profile (they work as long as the repo is connected to Namespace), so this drops the one-time dashboard setup. Shape 8x16 (8 vCPU / 16 GB) matches windows-latest RAM and doubles the cores. --- .github/workflows/ci.yml | 14 +++++++------- .github/workflows/e2e-test.yml | 16 ++++++++-------- .github/workflows/test-standalone-install.yml | 10 +++++----- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 502f806cea..3bd5625924 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -230,7 +230,7 @@ jobs: test-windows: needs: build-windows-tests name: Test (Windows) - runs-on: namespace-profile-windows-x64-default + runs-on: nscloud-windows-2022-amd64-8x16 steps: - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 - uses: ./.github/actions/clone @@ -374,7 +374,7 @@ jobs: target: x86_64-unknown-linux-gnu - os: namespace-profile-mac-default target: aarch64-apple-darwin - - os: namespace-profile-windows-x64-default + - os: nscloud-windows-2022-amd64-8x16 target: x86_64-pc-windows-msvc runs-on: ${{ matrix.os }} steps: @@ -932,15 +932,15 @@ jobs: target: aarch64-apple-darwin shard: 3 shardTotal: 3 - - os: namespace-profile-windows-x64-default + - os: nscloud-windows-2022-amd64-8x16 target: x86_64-pc-windows-msvc shard: 1 shardTotal: 3 - - os: namespace-profile-windows-x64-default + - os: nscloud-windows-2022-amd64-8x16 target: x86_64-pc-windows-msvc shard: 2 shardTotal: 3 - - os: namespace-profile-windows-x64-default + - os: nscloud-windows-2022-amd64-8x16 target: x86_64-pc-windows-msvc shard: 3 shardTotal: 3 @@ -1099,7 +1099,7 @@ jobs: - download-previous-rolldown-binaries - build-windows-cli - build-windows-tests - runs-on: namespace-profile-windows-x64-default + runs-on: nscloud-windows-2022-amd64-8x16 steps: - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 - uses: ./.github/actions/clone @@ -1358,7 +1358,7 @@ jobs: sfw_asset: sfw-free-macos-arm64 vp_bin: vp vp_insecure_tls: '' - - os: namespace-profile-windows-x64-default + - os: nscloud-windows-2022-amd64-8x16 target: x86_64-pc-windows-msvc sfw_asset: sfw-free-windows-x86_64.exe # On Windows vp ships as `vp.exe`; sfw spawns its child process diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index ec87d991e9..5ae94aa91a 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -101,7 +101,7 @@ jobs: include: - os: ubuntu-latest target: x86_64-unknown-linux-gnu - - os: namespace-profile-windows-x64-default + - os: nscloud-windows-2022-amd64-8x16 target: x86_64-pc-windows-msvc steps: - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 @@ -189,7 +189,7 @@ jobs: matrix: os: - ubuntu-latest - - namespace-profile-windows-x64-default + - nscloud-windows-2022-amd64-8x16 project: - name: vibe-dashboard node-version: 24 @@ -398,27 +398,27 @@ jobs: vp run test:coverage exclude: # frm-stack uses Docker (testcontainers) which doesn't work the same way on Windows - - os: namespace-profile-windows-x64-default + - os: nscloud-windows-2022-amd64-8x16 project: name: frm-stack # dify only runs on Linux for now - - os: namespace-profile-windows-x64-default + - os: nscloud-windows-2022-amd64-8x16 project: name: dify # vinext uses workerd native deps that don't build on Windows - - os: namespace-profile-windows-x64-default + - os: nscloud-windows-2022-amd64-8x16 project: name: vinext # yaak is a Tauri app with Rust/wasm deps - - os: namespace-profile-windows-x64-default + - os: nscloud-windows-2022-amd64-8x16 project: name: yaak # npmx.dev is a Nuxt app, ubuntu-only for now - - os: namespace-profile-windows-x64-default + - os: nscloud-windows-2022-amd64-8x16 project: name: npmx.dev # varlet upstream CI is ubuntu-only - - os: namespace-profile-windows-x64-default + - os: nscloud-windows-2022-amd64-8x16 project: name: varlet diff --git a/.github/workflows/test-standalone-install.yml b/.github/workflows/test-standalone-install.yml index b7800056fb..523342a143 100644 --- a/.github/workflows/test-standalone-install.yml +++ b/.github/workflows/test-standalone-install.yml @@ -329,7 +329,7 @@ jobs: test-install-ps1-v5: name: Test install.ps1 (Windows x64, PowerShell 5.1) - runs-on: namespace-profile-windows-x64-default + runs-on: nscloud-windows-2022-amd64-8x16 permissions: contents: read steps: @@ -478,7 +478,7 @@ jobs: test-install-ps1-v76: name: Test install.ps1 (Windows x64, PowerShell 7.6) - runs-on: namespace-profile-windows-x64-default + runs-on: nscloud-windows-2022-amd64-8x16 permissions: contents: read steps: @@ -558,7 +558,7 @@ jobs: test-install-ps1-release-age: name: Test install.ps1 (minimum-release-age) - runs-on: namespace-profile-windows-x64-default + runs-on: nscloud-windows-2022-amd64-8x16 permissions: contents: read steps: @@ -636,7 +636,7 @@ jobs: test-install-ps1: name: Test install.ps1 (Windows x64) - runs-on: namespace-profile-windows-x64-default + runs-on: nscloud-windows-2022-amd64-8x16 permissions: contents: read steps: @@ -789,7 +789,7 @@ jobs: test-vp-setup-exe: name: Test vp-setup.exe (pwsh) - runs-on: namespace-profile-windows-x64-default + runs-on: nscloud-windows-2022-amd64-8x16 permissions: contents: read steps: From a36096593aa592581791a0bbdf19e45609e61519 Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 8 Jul 2026 17:14:20 +0800 Subject: [PATCH 03/10] ci: use namespace-profile-windows-4c-8g runner label Switch the Windows runs-on labels to the dashboard profile namespace-profile-windows-4c-8g (4 vCPU / 8 GB), matching the namespace-profile-* style already used for Linux and macOS. Requires that profile to exist in the Namespace dashboard. --- .github/workflows/ci.yml | 14 +++++++------- .github/workflows/e2e-test.yml | 16 ++++++++-------- .github/workflows/test-standalone-install.yml | 10 +++++----- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3bd5625924..3960db308b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -230,7 +230,7 @@ jobs: test-windows: needs: build-windows-tests name: Test (Windows) - runs-on: nscloud-windows-2022-amd64-8x16 + runs-on: namespace-profile-windows-4c-8g steps: - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 - uses: ./.github/actions/clone @@ -374,7 +374,7 @@ jobs: target: x86_64-unknown-linux-gnu - os: namespace-profile-mac-default target: aarch64-apple-darwin - - os: nscloud-windows-2022-amd64-8x16 + - os: namespace-profile-windows-4c-8g target: x86_64-pc-windows-msvc runs-on: ${{ matrix.os }} steps: @@ -932,15 +932,15 @@ jobs: target: aarch64-apple-darwin shard: 3 shardTotal: 3 - - os: nscloud-windows-2022-amd64-8x16 + - os: namespace-profile-windows-4c-8g target: x86_64-pc-windows-msvc shard: 1 shardTotal: 3 - - os: nscloud-windows-2022-amd64-8x16 + - os: namespace-profile-windows-4c-8g target: x86_64-pc-windows-msvc shard: 2 shardTotal: 3 - - os: nscloud-windows-2022-amd64-8x16 + - os: namespace-profile-windows-4c-8g target: x86_64-pc-windows-msvc shard: 3 shardTotal: 3 @@ -1099,7 +1099,7 @@ jobs: - download-previous-rolldown-binaries - build-windows-cli - build-windows-tests - runs-on: nscloud-windows-2022-amd64-8x16 + runs-on: namespace-profile-windows-4c-8g steps: - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 - uses: ./.github/actions/clone @@ -1358,7 +1358,7 @@ jobs: sfw_asset: sfw-free-macos-arm64 vp_bin: vp vp_insecure_tls: '' - - os: nscloud-windows-2022-amd64-8x16 + - os: namespace-profile-windows-4c-8g target: x86_64-pc-windows-msvc sfw_asset: sfw-free-windows-x86_64.exe # On Windows vp ships as `vp.exe`; sfw spawns its child process diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index 5ae94aa91a..e58c3e323d 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -101,7 +101,7 @@ jobs: include: - os: ubuntu-latest target: x86_64-unknown-linux-gnu - - os: nscloud-windows-2022-amd64-8x16 + - os: namespace-profile-windows-4c-8g target: x86_64-pc-windows-msvc steps: - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 @@ -189,7 +189,7 @@ jobs: matrix: os: - ubuntu-latest - - nscloud-windows-2022-amd64-8x16 + - namespace-profile-windows-4c-8g project: - name: vibe-dashboard node-version: 24 @@ -398,27 +398,27 @@ jobs: vp run test:coverage exclude: # frm-stack uses Docker (testcontainers) which doesn't work the same way on Windows - - os: nscloud-windows-2022-amd64-8x16 + - os: namespace-profile-windows-4c-8g project: name: frm-stack # dify only runs on Linux for now - - os: nscloud-windows-2022-amd64-8x16 + - os: namespace-profile-windows-4c-8g project: name: dify # vinext uses workerd native deps that don't build on Windows - - os: nscloud-windows-2022-amd64-8x16 + - os: namespace-profile-windows-4c-8g project: name: vinext # yaak is a Tauri app with Rust/wasm deps - - os: nscloud-windows-2022-amd64-8x16 + - os: namespace-profile-windows-4c-8g project: name: yaak # npmx.dev is a Nuxt app, ubuntu-only for now - - os: nscloud-windows-2022-amd64-8x16 + - os: namespace-profile-windows-4c-8g project: name: npmx.dev # varlet upstream CI is ubuntu-only - - os: nscloud-windows-2022-amd64-8x16 + - os: namespace-profile-windows-4c-8g project: name: varlet diff --git a/.github/workflows/test-standalone-install.yml b/.github/workflows/test-standalone-install.yml index 523342a143..3a0e357aae 100644 --- a/.github/workflows/test-standalone-install.yml +++ b/.github/workflows/test-standalone-install.yml @@ -329,7 +329,7 @@ jobs: test-install-ps1-v5: name: Test install.ps1 (Windows x64, PowerShell 5.1) - runs-on: nscloud-windows-2022-amd64-8x16 + runs-on: namespace-profile-windows-4c-8g permissions: contents: read steps: @@ -478,7 +478,7 @@ jobs: test-install-ps1-v76: name: Test install.ps1 (Windows x64, PowerShell 7.6) - runs-on: nscloud-windows-2022-amd64-8x16 + runs-on: namespace-profile-windows-4c-8g permissions: contents: read steps: @@ -558,7 +558,7 @@ jobs: test-install-ps1-release-age: name: Test install.ps1 (minimum-release-age) - runs-on: nscloud-windows-2022-amd64-8x16 + runs-on: namespace-profile-windows-4c-8g permissions: contents: read steps: @@ -636,7 +636,7 @@ jobs: test-install-ps1: name: Test install.ps1 (Windows x64) - runs-on: nscloud-windows-2022-amd64-8x16 + runs-on: namespace-profile-windows-4c-8g permissions: contents: read steps: @@ -789,7 +789,7 @@ jobs: test-vp-setup-exe: name: Test vp-setup.exe (pwsh) - runs-on: nscloud-windows-2022-amd64-8x16 + runs-on: namespace-profile-windows-4c-8g permissions: contents: read steps: From 50553e74a3b12cf76cfaa69eef2e432ffd44f23e Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 8 Jul 2026 17:17:12 +0800 Subject: [PATCH 04/10] ci(release): build Windows release binaries on Namespace runners Move reusable-release-build.yml's two Windows targets (x86_64 native, aarch64 cross-compiled on the amd64 host) from windows-latest to namespace-profile-windows-4c-8g. The release build needs the native MSVC toolchain (VS Build Tools + Windows SDK) on the runner image. --- .github/workflows/reusable-release-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/reusable-release-build.yml b/.github/workflows/reusable-release-build.yml index 5c5b6a26ec..35432573f5 100644 --- a/.github/workflows/reusable-release-build.yml +++ b/.github/workflows/reusable-release-build.yml @@ -42,9 +42,9 @@ jobs: - target: x86_64-unknown-linux-musl os: ubuntu-latest - target: x86_64-pc-windows-msvc - os: windows-latest + os: namespace-profile-windows-4c-8g - target: aarch64-pc-windows-msvc - os: windows-latest + os: namespace-profile-windows-4c-8g steps: - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 - uses: ./.github/actions/clone From 3e2373c59cad40668256d8ed0744796359043363 Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 8 Jul 2026 20:13:01 +0800 Subject: [PATCH 05/10] ci(windows): pin VP_HOME so Namespace service-account jobs install where tests check Namespace's Windows runners execute jobs under a service account whose real user profile (C:\Windows\system32\config\systemprofile) differs from %USERPROFILE% (C:\Users\runneradmin). vp resolves its home from the OS profile, so install.ps1 placed vp.exe under %USERPROFILE%\.vite-plus while 'vp env setup' wrote node/npm/npx shims into the systemprofile home, and the assertions checking %USERPROFILE%\.vite-plus\bin failed with 'Shim not found'. vp-setup.exe and the snapshot suite's VP_SNAP_* paths hit the same split. Pin VP_HOME to %USERPROFILE%\.vite-plus in the five affected jobs (test-install-ps1-v5/-v76/plain, test-vp-setup-exe, cli-snapshot-test-windows) so the install, generated shims, and assertions share one location. Also switch the PowerShell 7.6 job's 'dotnet tool install' from --global (resolves under the systemprofile) to an explicit --tool-path. --- .github/workflows/ci.yml | 8 ++++ .github/workflows/test-standalone-install.yml | 37 ++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3960db308b..7b75b060ee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1104,6 +1104,14 @@ jobs: - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 - uses: ./.github/actions/clone + - name: Pin VP_HOME to USERPROFILE + # Namespace's Windows runners run jobs under a service account whose real + # profile (C:\Windows\system32\config\systemprofile) differs from + # %USERPROFILE%; vp resolves its home from the OS profile. Pin VP_HOME so + # the seeded global vp/runtime land where VP_SNAP_* below point. + shell: bash + run: echo "VP_HOME=$USERPROFILE\.vite-plus" >> $GITHUB_ENV + # Same Dev Drive TEMP routing as cli-snap-test: staged fixture # workspaces live under os.tmpdir() and must resolve pnpm junction # reparse points cleanly (see that job for the full story). diff --git a/.github/workflows/test-standalone-install.yml b/.github/workflows/test-standalone-install.yml index 3a0e357aae..8db7d318cf 100644 --- a/.github/workflows/test-standalone-install.yml +++ b/.github/workflows/test-standalone-install.yml @@ -335,6 +335,14 @@ jobs: steps: - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 + - name: Pin VP_HOME to USERPROFILE + # Namespace's Windows runners run jobs under a service account whose real + # profile (C:\Windows\system32\config\systemprofile) differs from + # %USERPROFILE%; vp resolves its home from the OS profile. Pin VP_HOME so + # the install, generated shims, and these assertions share one location. + shell: bash + run: echo "VP_HOME=$USERPROFILE\.vite-plus" >> $GITHUB_ENV + - name: Assert PowerShell 5.x shell: powershell run: | @@ -484,10 +492,21 @@ jobs: steps: - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 + - name: Pin VP_HOME to USERPROFILE + # Namespace's Windows runners run jobs under a service account whose real + # profile (C:\Windows\system32\config\systemprofile) differs from + # %USERPROFILE%; vp resolves its home from the OS profile. Pin VP_HOME so + # the install, generated shims, and these assertions share one location. + shell: bash + run: echo "VP_HOME=$USERPROFILE\.vite-plus" >> $GITHUB_ENV + - name: Install PowerShell 7.6 shell: pwsh run: | - dotnet tool install --global PowerShell --version 7.6.0 + # --tool-path (not --global): a global tool install resolves the target + # under the OS user profile, which is the service-account systemprofile + # on Namespace, not %USERPROFILE%. An explicit path is account-independent. + dotnet tool install --tool-path "$env:USERPROFILE\.dotnet\tools" PowerShell --version 7.6.0 $pwsh76 = "$env:USERPROFILE\.dotnet\tools\pwsh.exe" echo "PWSH76=$pwsh76" >> $env:GITHUB_ENV $ver = & $pwsh76 -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' @@ -642,6 +661,14 @@ jobs: steps: - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 + - name: Pin VP_HOME to USERPROFILE + # Namespace's Windows runners run jobs under a service account whose real + # profile (C:\Windows\system32\config\systemprofile) differs from + # %USERPROFILE%; vp resolves its home from the OS profile. Pin VP_HOME so + # the install, generated shims, and these assertions share one location. + shell: bash + run: echo "VP_HOME=$USERPROFILE\.vite-plus" >> $GITHUB_ENV + - name: Run install.ps1 shell: pwsh run: | @@ -796,6 +823,14 @@ jobs: - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 - uses: ./.github/actions/clone + - name: Pin VP_HOME to USERPROFILE + # Namespace's Windows runners run jobs under a service account whose real + # profile (C:\Windows\system32\config\systemprofile) differs from + # %USERPROFILE%; vp-setup.exe installs into VP_HOME (falling back to the OS + # profile). Pin it so the install and these assertions share one location. + shell: bash + run: echo "VP_HOME=$USERPROFILE\.vite-plus" >> $GITHUB_ENV + - name: Setup Dev Drive uses: samypr100/setup-dev-drive@30f0f98ae5636b2b6501e181dfb3631b9974818d # v4.0.0 with: From 4c284ff2fb2f06346f002a81edb52045f8199a03 Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 8 Jul 2026 22:34:39 +0800 Subject: [PATCH 06/10] ci(windows): install latest instead of the stale alpha dist-tag The standalone-install tests pinned VP_VERSION to the alpha dist-tag, which is stale (0.1.21-alpha.7, published 2026-05-13) and predates the VP_HOME fix in #2029 (2026-07-05). On Namespace's service-account Windows runners that old binary's 'vp env doctor' ignores VP_HOME and resolves the systemprofile home, failing the plain test-install-ps1 job. Drop VP_VERSION entirely so install.ps1/install.sh/vp-setup.exe default to latest (a build that contains #2029), which also lets the tests track releases instead of a hardcoded version. --- .github/workflows/test-standalone-install.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/test-standalone-install.yml b/.github/workflows/test-standalone-install.yml index 8db7d318cf..4d473d2126 100644 --- a/.github/workflows/test-standalone-install.yml +++ b/.github/workflows/test-standalone-install.yml @@ -20,9 +20,6 @@ defaults: run: shell: bash -env: - VP_VERSION: alpha - jobs: test-install-sh: name: Test install.sh (${{ matrix.name }}) @@ -168,7 +165,6 @@ jobs: run: | docker run --rm --platform linux/arm64 \ -v "${{ github.workspace }}:/workspace" \ - -e VP_VERSION=alpha \ ubuntu:20.04 bash -c " ls -al ~/ apt-get update && apt-get install -y curl ca-certificates @@ -227,7 +223,6 @@ jobs: run: | docker run --rm \ -v "${{ github.workspace }}:/workspace" \ - -e VP_VERSION=alpha \ -e CI=true \ alpine:3.21 sh -c " # libstdc++: required by unofficial-builds Node.js musl binary @@ -285,7 +280,6 @@ jobs: run: | docker run --rm --platform linux/arm64 \ -v "${{ github.workspace }}:/workspace" \ - -e VP_VERSION=alpha \ -e CI=true \ alpine:3.21 sh -c " # libstdc++ is needed by unofficial-builds Node.js musl binary @@ -851,8 +845,6 @@ jobs: - name: Install via vp-setup.exe (silent) shell: pwsh run: ${{ format('{0}/target/release/vp-setup.exe', env.DEV_DRIVE) }} - env: - VP_VERSION: alpha - name: Set PATH shell: bash From 20bb3305c64690b511fd70a7fc633f939df3f9ec Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 8 Jul 2026 23:04:54 +0800 Subject: [PATCH 07/10] ci(debug): temporary workflow to reproduce the snapshot hang on Namespace Reproduces cli-snapshot-test-windows's 60s hangs on namespace-profile-windows-4c-8g with two instrumented probes: (1) bare vp --help under an isolated empty VP_HOME + VITE_LOG=trace with a hard 30s wait and a CPU sampler (empty VP_HOME is the variable the passing cli-e2e-test job doesn't exercise; distinguishes a self-exec spin from a blocked prompt), and (2) the single help::global case through the PTY runner with --no-capture. Trigger via push to this file or workflow_dispatch. Remove before merge. --- .github/workflows/debug-snapshot-hang.yml | 203 ++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 .github/workflows/debug-snapshot-hang.yml diff --git a/.github/workflows/debug-snapshot-hang.yml b/.github/workflows/debug-snapshot-hang.yml new file mode 100644 index 0000000000..6b86ae0fbd --- /dev/null +++ b/.github/workflows/debug-snapshot-hang.yml @@ -0,0 +1,203 @@ +# TEMPORARY debug workflow (remove before merge). +# +# Reproduces the `cli-snapshot-test-windows` hang on the Namespace Windows +# runner (18/28 PTY snapshot cases wedge to a 60s timeout, including +# `vp_help::help::global` = `vp --help`). It runs the exact same setup as the +# real job but replaces the full suite with two instrumented probes: +# +# 1. DIRECT (no PTY): run the seeded global vp with an *isolated empty* +# VP_HOME + VITE_LOG=trace, with a hard 30s wait. The empty VP_HOME is the +# one variable the passing `cli-e2e-test` job does not exercise. If this +# hangs, the wedge is in vp itself (not the PTY runner) and the trace shows +# where; a background sampler tells spinning (self-exec race) from blocked. +# 2. PTY: run just `help::global` through the snapshot runner with --no-capture +# and a process/CPU sampler, to confirm the faithful repro. +# +# Trigger: push a change to this file on the branch, or dispatch manually. +on: + workflow_dispatch: + push: + branches: [ci/namespace-windows-runners] + paths: ['.github/workflows/debug-snapshot-hang.yml'] + +permissions: + contents: read + +concurrency: + group: debug-snapshot-hang-${{ github.ref }} + cancel-in-progress: true + +jobs: + rolldown: + runs-on: ubuntu-latest + permissions: + contents: read + packages: read + steps: + - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 + - uses: ./.github/actions/download-rolldown-binaries + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + + build-windows-cli: + runs-on: namespace-profile-linux-x64-default + steps: + - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 + - uses: ./.github/actions/clone + - uses: ./.github/actions/build-windows-cli + with: + save-cache: false + + snapshot-archive: + runs-on: namespace-profile-linux-x64-default + env: + XWIN_ACCEPT_LICENSE: '1' + CXXFLAGS: -D_ALLOW_COMPILER_AND_STL_VERSION_MISMATCH + steps: + - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 + - uses: ./.github/actions/clone + - uses: ./.github/actions/setup-xwin + with: + save-cache: false + cache-key: windows-cross + tools: cargo-nextest + - name: Build snapshot test archive + run: | + eval "$(cargo xwin env --target x86_64-pc-windows-msvc | grep '^export ')" + unset RUSTFLAGS + cargo nextest archive -p vite_cli_snapshots \ + --target x86_64-pc-windows-msvc --archive-file windows-snapshot-tests.tar.zst + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: windows-snapshot-test-archive + path: windows-snapshot-tests.tar.zst + retention-days: 3 + + debug: + needs: [rolldown, build-windows-cli, snapshot-archive] + name: Debug snapshot hang (Windows) + runs-on: namespace-profile-windows-4c-8g + timeout-minutes: 25 + steps: + - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 + - uses: ./.github/actions/clone + + - name: Pin VP_HOME to USERPROFILE + shell: bash + run: echo "VP_HOME=$USERPROFILE\.vite-plus" >> $GITHUB_ENV + + - name: Setup Dev Drive + uses: samypr100/setup-dev-drive@30f0f98ae5636b2b6501e181dfb3631b9974818d # v4.0.0 + with: + drive-size: 12GB + drive-format: ReFS + env-mapping: | + TEMP,{{ DEV_DRIVE }}/Temp + TMP,{{ DEV_DRIVE }}/Temp + + - name: Create TEMP/TMP on Dev Drive + shell: bash + run: mkdir -p "$TEMP" "$TMP" + + - uses: oxc-project/setup-node@4c588e9266bd930b6ddc34307df0659ed511d187 # v1.3.1 + + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: rolldown-binaries + path: ./rolldown/packages/rolldown/src + merge-multiple: true + + - name: Download prebuilt Windows binaries + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: windows-cli-binaries + + - name: Build with upstream + uses: ./.github/actions/build-upstream + with: + target: x86_64-pc-windows-msvc + skip-native: true + + - name: Install Global CLI vp + shell: bash + run: pnpm bootstrap-cli:ci + + - name: Prewarm managed runtime + shell: bash + run: | + "$USERPROFILE/.vite-plus/bin/vp.exe" node --version \ + || echo "prewarm failed; the runtime will download on demand" + + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: windows-snapshot-test-archive + + - uses: taiki-e/install-action@c93ccc03e00cd0e08e494f5fd058a6c55a6a1907 # v2.82.8 + with: + tool: cargo-nextest + + # ---- Probe 1: bare vp with an ISOLATED EMPTY VP_HOME (no PTY) ---- + - name: 'Probe 1 — direct vp --help, empty VP_HOME, trace' + shell: pwsh + run: | + $ErrorActionPreference = "Continue" + $vp = Join-Path $env:USERPROFILE ".vite-plus\current\bin\vp.exe" + Write-Host "vp: $vp (exists: $(Test-Path $vp))" + + $iso = Join-Path $env:RUNNER_TEMP "iso-vphome" + Remove-Item -Recurse -Force $iso -ErrorAction SilentlyContinue + New-Item -ItemType Directory -Force -Path $iso | Out-Null + $out = Join-Path $env:RUNNER_TEMP "p1-out.txt" + $err = Join-Path $env:RUNNER_TEMP "p1-err.txt" + + # Run under the isolated, empty VP_HOME (the snapshot cases' condition). + $env:VP_HOME = $iso + $env:VITE_LOG = "trace" + Write-Host "=== $vp --help (VP_HOME=$iso) ===" + $p = Start-Process -FilePath $vp -ArgumentList "--help" -NoNewWindow -PassThru ` + -RedirectStandardOutput $out -RedirectStandardError $err + try { + Wait-Process -Id $p.Id -Timeout 30 -ErrorAction Stop + Write-Host "EXITED with code $($p.ExitCode)" + } catch { + Write-Host "::warning::Probe 1 HUNG: vp --help did not exit in 30s (repro WITHOUT a PTY)" + Write-Host "--- vp/node process tree ---" + Get-CimInstance Win32_Process -Filter "Name='vp.exe' OR Name='node.exe'" | + Select-Object ProcessId,ParentProcessId,CommandLine | Format-List | Out-String | Write-Host + Write-Host "--- CPU samples (rising CPU = busy/self-exec loop; flat = blocked) ---" + 1..3 | ForEach-Object { + Get-Process vp,node -ErrorAction SilentlyContinue | + Select-Object Id,ProcessName,CPU,@{n='WS_MB';e={[int]($_.WS/1MB)}} | + Format-Table -AutoSize | Out-String | Write-Host + Start-Sleep -Seconds 2 + } + Get-CimInstance Win32_Process -Filter "Name='vp.exe'" | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue } + } + Write-Host "=== STDOUT ==="; Get-Content $out -ErrorAction SilentlyContinue | Write-Host + Write-Host "=== STDERR / trace ==="; Get-Content $err -ErrorAction SilentlyContinue | Write-Host + exit 0 + + # ---- Probe 2: single case through the PTY snapshot runner ---- + - name: 'Probe 2 — help::global via PTY runner, trace + sampler' + shell: bash + env: + RUST_BACKTRACE: full + __COMPAT_LAYER: RunAsInvoker + run: | + set +e + export VP_SNAP_GLOBAL_VP="$USERPROFILE/.vite-plus/current/bin/vp.exe" + export VP_SNAP_JS_RUNTIME_DIR="$USERPROFILE/.vite-plus/js_runtime" + export VITE_LOG=trace + export RUST_LOG="vite_cli_snapshots=trace,debug" + + # Background sampler: watch vp/node/vpt CPU while the case runs. + powershell -NoProfile -Command "1..25 | ForEach-Object { Get-Process vp,node,vpt -ErrorAction SilentlyContinue | Select-Object Id,ProcessName,CPU,@{n='WSMB';e={[int](\$_.WS/1MB)}} | Format-Table -AutoSize | Out-String | Write-Host; Start-Sleep 3 }" & + MON=$! + + echo "=== nextest: help::global (single case, --no-capture) ===" + cargo-nextest nextest run --archive-file windows-snapshot-tests.tar.zst \ + --workspace-remap . -E 'test(help::global)' --no-capture --no-fail-fast + echo "nextest exit: $?" + + kill "$MON" 2>/dev/null || true + exit 0 From 593791091075089d9a13d573c7f364e31d0b497f Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 8 Jul 2026 23:12:08 +0800 Subject: [PATCH 08/10] ci(debug): sample vp CPU in foreground while the PTY case runs Probe 1 (bare vp --help, empty VP_HOME, no PTY) exits 0 with full help; Probe 2 (same case via the PTY runner) hangs 60s with ZERO output, before vp's first trace line, so vp wedges at ConPTY startup. Rework Probe 2 to launch nextest in the background and sample vp/node process count + CPU in the foreground (the earlier '&'-backgrounded sampler output was never captured), to distinguish a self-exec spin (rising CPU / many vp procs) from a blocked ConPTY read (flat CPU, one vp). --- .github/workflows/debug-snapshot-hang.yml | 59 ++++++++++++++--------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/.github/workflows/debug-snapshot-hang.yml b/.github/workflows/debug-snapshot-hang.yml index 6b86ae0fbd..8a42b911bc 100644 --- a/.github/workflows/debug-snapshot-hang.yml +++ b/.github/workflows/debug-snapshot-hang.yml @@ -177,27 +177,42 @@ jobs: Write-Host "=== STDERR / trace ==="; Get-Content $err -ErrorAction SilentlyContinue | Write-Host exit 0 - # ---- Probe 2: single case through the PTY snapshot runner ---- - - name: 'Probe 2 — help::global via PTY runner, trace + sampler' - shell: bash - env: - RUST_BACKTRACE: full - __COMPAT_LAYER: RunAsInvoker + # ---- Probe 2: single case through the PTY runner, foreground sampler ---- + - name: 'Probe 2 — help::global via PTY runner (spin-vs-blocked sampler)' + shell: pwsh run: | - set +e - export VP_SNAP_GLOBAL_VP="$USERPROFILE/.vite-plus/current/bin/vp.exe" - export VP_SNAP_JS_RUNTIME_DIR="$USERPROFILE/.vite-plus/js_runtime" - export VITE_LOG=trace - export RUST_LOG="vite_cli_snapshots=trace,debug" - - # Background sampler: watch vp/node/vpt CPU while the case runs. - powershell -NoProfile -Command "1..25 | ForEach-Object { Get-Process vp,node,vpt -ErrorAction SilentlyContinue | Select-Object Id,ProcessName,CPU,@{n='WSMB';e={[int](\$_.WS/1MB)}} | Format-Table -AutoSize | Out-String | Write-Host; Start-Sleep 3 }" & - MON=$! - - echo "=== nextest: help::global (single case, --no-capture) ===" - cargo-nextest nextest run --archive-file windows-snapshot-tests.tar.zst \ - --workspace-remap . -E 'test(help::global)' --no-capture --no-fail-fast - echo "nextest exit: $?" - - kill "$MON" 2>/dev/null || true + $ErrorActionPreference = "Continue" + $env:VP_SNAP_GLOBAL_VP = Join-Path $env:USERPROFILE ".vite-plus\current\bin\vp.exe" + $env:VP_SNAP_JS_RUNTIME_DIR = Join-Path $env:USERPROFILE ".vite-plus\js_runtime" + $env:VITE_LOG = "trace" + $env:RUST_LOG = "vite_cli_snapshots=trace,debug" + $env:RUST_BACKTRACE = "full" + $env:__COMPAT_LAYER = "RunAsInvoker" + + $log = Join-Path $env:RUNNER_TEMP "nextest-out.txt" + $elog = Join-Path $env:RUNNER_TEMP "nextest-err.txt" + $nargs = @("nextest","run","--archive-file","windows-snapshot-tests.tar.zst", + "--workspace-remap",".","-E","test(help::global)","--no-capture","--no-fail-fast") + Write-Host "=== launching nextest (help::global) in background ===" + $proc = Start-Process -FilePath "cargo-nextest" -ArgumentList $nargs -NoNewWindow -PassThru ` + -RedirectStandardOutput $log -RedirectStandardError $elog + + # Foreground sampler: rising CPU / many vp procs = spin (self-exec); + # flat CPU with one blocked vp = waiting (ConPTY read / terminal probe). + for ($i = 0; $i -lt 24; $i++) { + $vps = @(Get-Process vp -ErrorAction SilentlyContinue) + Write-Host ("--- t=" + ($i*3) + "s vp procs=" + $vps.Count + " ---") + Get-Process vp,node,vpt -ErrorAction SilentlyContinue | + Select-Object Id,ProcessName,CPU,@{n='WS_MB';e={[int]($_.WS/1MB)}} | + Format-Table -AutoSize | Out-String | Write-Host + if ($proc.HasExited) { Write-Host "nextest exited code $($proc.ExitCode)"; break } + Start-Sleep -Seconds 3 + } + if (-not $proc.HasExited) { + Write-Host "::warning::nextest still running after the sampling window; killing" + Get-CimInstance Win32_Process -Filter "Name='vp.exe' OR Name='cargo-nextest.exe'" | + ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue } + } + Write-Host "=== nextest STDOUT ==="; Get-Content $log -ErrorAction SilentlyContinue | Write-Host + Write-Host "=== nextest STDERR ==="; Get-Content $elog -ErrorAction SilentlyContinue | Write-Host exit 0 From e833057f2e9462c421d346ca2a4d9356743f90b1 Mon Sep 17 00:00:00 2001 From: MK Date: Wed, 8 Jul 2026 23:24:35 +0800 Subject: [PATCH 09/10] ci(windows): keep the PTY snapshot and doctor jobs on windows-latest Two Windows jobs cannot run on Namespace Session-0 service-account runners and move back to windows-latest, with code comments explaining why. cli-snapshot-test-windows is a PTY snapshot suite: the runner opens a ConPTY and spawns vp into it; under the Session-0 service account (no interactive console) that spawn blocks, vp never launches, and every case times out at 60s (verified: the vp process count stays 0 for the full 60s). test-install-ps1 (plain) runs vp env doctor under bash set -e; on the service account the installed vp resolves the systemprofile home rather than %USERPROFILE% even with VP_HOME set, so the doctor PATH check fails. The other install jobs stay on Namespace because they do not run doctor under set -e. Also removes the temporary debug-snapshot-hang.yml workflow used to diagnose the ConPTY hang. --- .github/workflows/ci.yml | 16 +- .github/workflows/debug-snapshot-hang.yml | 218 ------------------ .github/workflows/test-standalone-install.yml | 18 +- 3 files changed, 16 insertions(+), 236 deletions(-) delete mode 100644 .github/workflows/debug-snapshot-hang.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7b75b060ee..d0be52ea8d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1099,19 +1099,17 @@ jobs: - download-previous-rolldown-binaries - build-windows-cli - build-windows-tests - runs-on: namespace-profile-windows-4c-8g + # Stays on GitHub-hosted windows-latest, NOT the Namespace Windows runner: + # this is a PTY snapshot suite. The runner opens a pseudo-console (ConPTY) + # and spawns vp into it, but Namespace's Windows runners execute jobs under a + # Session-0 service account with no interactive console, where that ConPTY + # spawn blocks — vp is never launched and every case times out at 60s. + # windows-latest runs in a session where ConPTY works. + runs-on: windows-latest steps: - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 - uses: ./.github/actions/clone - - name: Pin VP_HOME to USERPROFILE - # Namespace's Windows runners run jobs under a service account whose real - # profile (C:\Windows\system32\config\systemprofile) differs from - # %USERPROFILE%; vp resolves its home from the OS profile. Pin VP_HOME so - # the seeded global vp/runtime land where VP_SNAP_* below point. - shell: bash - run: echo "VP_HOME=$USERPROFILE\.vite-plus" >> $GITHUB_ENV - # Same Dev Drive TEMP routing as cli-snap-test: staged fixture # workspaces live under os.tmpdir() and must resolve pnpm junction # reparse points cleanly (see that job for the full story). diff --git a/.github/workflows/debug-snapshot-hang.yml b/.github/workflows/debug-snapshot-hang.yml deleted file mode 100644 index 8a42b911bc..0000000000 --- a/.github/workflows/debug-snapshot-hang.yml +++ /dev/null @@ -1,218 +0,0 @@ -# TEMPORARY debug workflow (remove before merge). -# -# Reproduces the `cli-snapshot-test-windows` hang on the Namespace Windows -# runner (18/28 PTY snapshot cases wedge to a 60s timeout, including -# `vp_help::help::global` = `vp --help`). It runs the exact same setup as the -# real job but replaces the full suite with two instrumented probes: -# -# 1. DIRECT (no PTY): run the seeded global vp with an *isolated empty* -# VP_HOME + VITE_LOG=trace, with a hard 30s wait. The empty VP_HOME is the -# one variable the passing `cli-e2e-test` job does not exercise. If this -# hangs, the wedge is in vp itself (not the PTY runner) and the trace shows -# where; a background sampler tells spinning (self-exec race) from blocked. -# 2. PTY: run just `help::global` through the snapshot runner with --no-capture -# and a process/CPU sampler, to confirm the faithful repro. -# -# Trigger: push a change to this file on the branch, or dispatch manually. -on: - workflow_dispatch: - push: - branches: [ci/namespace-windows-runners] - paths: ['.github/workflows/debug-snapshot-hang.yml'] - -permissions: - contents: read - -concurrency: - group: debug-snapshot-hang-${{ github.ref }} - cancel-in-progress: true - -jobs: - rolldown: - runs-on: ubuntu-latest - permissions: - contents: read - packages: read - steps: - - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 - - uses: ./.github/actions/download-rolldown-binaries - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - - build-windows-cli: - runs-on: namespace-profile-linux-x64-default - steps: - - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 - - uses: ./.github/actions/clone - - uses: ./.github/actions/build-windows-cli - with: - save-cache: false - - snapshot-archive: - runs-on: namespace-profile-linux-x64-default - env: - XWIN_ACCEPT_LICENSE: '1' - CXXFLAGS: -D_ALLOW_COMPILER_AND_STL_VERSION_MISMATCH - steps: - - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 - - uses: ./.github/actions/clone - - uses: ./.github/actions/setup-xwin - with: - save-cache: false - cache-key: windows-cross - tools: cargo-nextest - - name: Build snapshot test archive - run: | - eval "$(cargo xwin env --target x86_64-pc-windows-msvc | grep '^export ')" - unset RUSTFLAGS - cargo nextest archive -p vite_cli_snapshots \ - --target x86_64-pc-windows-msvc --archive-file windows-snapshot-tests.tar.zst - - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: windows-snapshot-test-archive - path: windows-snapshot-tests.tar.zst - retention-days: 3 - - debug: - needs: [rolldown, build-windows-cli, snapshot-archive] - name: Debug snapshot hang (Windows) - runs-on: namespace-profile-windows-4c-8g - timeout-minutes: 25 - steps: - - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 - - uses: ./.github/actions/clone - - - name: Pin VP_HOME to USERPROFILE - shell: bash - run: echo "VP_HOME=$USERPROFILE\.vite-plus" >> $GITHUB_ENV - - - name: Setup Dev Drive - uses: samypr100/setup-dev-drive@30f0f98ae5636b2b6501e181dfb3631b9974818d # v4.0.0 - with: - drive-size: 12GB - drive-format: ReFS - env-mapping: | - TEMP,{{ DEV_DRIVE }}/Temp - TMP,{{ DEV_DRIVE }}/Temp - - - name: Create TEMP/TMP on Dev Drive - shell: bash - run: mkdir -p "$TEMP" "$TMP" - - - uses: oxc-project/setup-node@4c588e9266bd930b6ddc34307df0659ed511d187 # v1.3.1 - - - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: rolldown-binaries - path: ./rolldown/packages/rolldown/src - merge-multiple: true - - - name: Download prebuilt Windows binaries - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: windows-cli-binaries - - - name: Build with upstream - uses: ./.github/actions/build-upstream - with: - target: x86_64-pc-windows-msvc - skip-native: true - - - name: Install Global CLI vp - shell: bash - run: pnpm bootstrap-cli:ci - - - name: Prewarm managed runtime - shell: bash - run: | - "$USERPROFILE/.vite-plus/bin/vp.exe" node --version \ - || echo "prewarm failed; the runtime will download on demand" - - - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: windows-snapshot-test-archive - - - uses: taiki-e/install-action@c93ccc03e00cd0e08e494f5fd058a6c55a6a1907 # v2.82.8 - with: - tool: cargo-nextest - - # ---- Probe 1: bare vp with an ISOLATED EMPTY VP_HOME (no PTY) ---- - - name: 'Probe 1 — direct vp --help, empty VP_HOME, trace' - shell: pwsh - run: | - $ErrorActionPreference = "Continue" - $vp = Join-Path $env:USERPROFILE ".vite-plus\current\bin\vp.exe" - Write-Host "vp: $vp (exists: $(Test-Path $vp))" - - $iso = Join-Path $env:RUNNER_TEMP "iso-vphome" - Remove-Item -Recurse -Force $iso -ErrorAction SilentlyContinue - New-Item -ItemType Directory -Force -Path $iso | Out-Null - $out = Join-Path $env:RUNNER_TEMP "p1-out.txt" - $err = Join-Path $env:RUNNER_TEMP "p1-err.txt" - - # Run under the isolated, empty VP_HOME (the snapshot cases' condition). - $env:VP_HOME = $iso - $env:VITE_LOG = "trace" - Write-Host "=== $vp --help (VP_HOME=$iso) ===" - $p = Start-Process -FilePath $vp -ArgumentList "--help" -NoNewWindow -PassThru ` - -RedirectStandardOutput $out -RedirectStandardError $err - try { - Wait-Process -Id $p.Id -Timeout 30 -ErrorAction Stop - Write-Host "EXITED with code $($p.ExitCode)" - } catch { - Write-Host "::warning::Probe 1 HUNG: vp --help did not exit in 30s (repro WITHOUT a PTY)" - Write-Host "--- vp/node process tree ---" - Get-CimInstance Win32_Process -Filter "Name='vp.exe' OR Name='node.exe'" | - Select-Object ProcessId,ParentProcessId,CommandLine | Format-List | Out-String | Write-Host - Write-Host "--- CPU samples (rising CPU = busy/self-exec loop; flat = blocked) ---" - 1..3 | ForEach-Object { - Get-Process vp,node -ErrorAction SilentlyContinue | - Select-Object Id,ProcessName,CPU,@{n='WS_MB';e={[int]($_.WS/1MB)}} | - Format-Table -AutoSize | Out-String | Write-Host - Start-Sleep -Seconds 2 - } - Get-CimInstance Win32_Process -Filter "Name='vp.exe'" | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue } - } - Write-Host "=== STDOUT ==="; Get-Content $out -ErrorAction SilentlyContinue | Write-Host - Write-Host "=== STDERR / trace ==="; Get-Content $err -ErrorAction SilentlyContinue | Write-Host - exit 0 - - # ---- Probe 2: single case through the PTY runner, foreground sampler ---- - - name: 'Probe 2 — help::global via PTY runner (spin-vs-blocked sampler)' - shell: pwsh - run: | - $ErrorActionPreference = "Continue" - $env:VP_SNAP_GLOBAL_VP = Join-Path $env:USERPROFILE ".vite-plus\current\bin\vp.exe" - $env:VP_SNAP_JS_RUNTIME_DIR = Join-Path $env:USERPROFILE ".vite-plus\js_runtime" - $env:VITE_LOG = "trace" - $env:RUST_LOG = "vite_cli_snapshots=trace,debug" - $env:RUST_BACKTRACE = "full" - $env:__COMPAT_LAYER = "RunAsInvoker" - - $log = Join-Path $env:RUNNER_TEMP "nextest-out.txt" - $elog = Join-Path $env:RUNNER_TEMP "nextest-err.txt" - $nargs = @("nextest","run","--archive-file","windows-snapshot-tests.tar.zst", - "--workspace-remap",".","-E","test(help::global)","--no-capture","--no-fail-fast") - Write-Host "=== launching nextest (help::global) in background ===" - $proc = Start-Process -FilePath "cargo-nextest" -ArgumentList $nargs -NoNewWindow -PassThru ` - -RedirectStandardOutput $log -RedirectStandardError $elog - - # Foreground sampler: rising CPU / many vp procs = spin (self-exec); - # flat CPU with one blocked vp = waiting (ConPTY read / terminal probe). - for ($i = 0; $i -lt 24; $i++) { - $vps = @(Get-Process vp -ErrorAction SilentlyContinue) - Write-Host ("--- t=" + ($i*3) + "s vp procs=" + $vps.Count + " ---") - Get-Process vp,node,vpt -ErrorAction SilentlyContinue | - Select-Object Id,ProcessName,CPU,@{n='WS_MB';e={[int]($_.WS/1MB)}} | - Format-Table -AutoSize | Out-String | Write-Host - if ($proc.HasExited) { Write-Host "nextest exited code $($proc.ExitCode)"; break } - Start-Sleep -Seconds 3 - } - if (-not $proc.HasExited) { - Write-Host "::warning::nextest still running after the sampling window; killing" - Get-CimInstance Win32_Process -Filter "Name='vp.exe' OR Name='cargo-nextest.exe'" | - ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue } - } - Write-Host "=== nextest STDOUT ==="; Get-Content $log -ErrorAction SilentlyContinue | Write-Host - Write-Host "=== nextest STDERR ==="; Get-Content $elog -ErrorAction SilentlyContinue | Write-Host - exit 0 diff --git a/.github/workflows/test-standalone-install.yml b/.github/workflows/test-standalone-install.yml index 4d473d2126..f2d7cdcec1 100644 --- a/.github/workflows/test-standalone-install.yml +++ b/.github/workflows/test-standalone-install.yml @@ -649,20 +649,20 @@ jobs: test-install-ps1: name: Test install.ps1 (Windows x64) - runs-on: namespace-profile-windows-4c-8g + # Stays on GitHub-hosted windows-latest, NOT the Namespace Windows runner. + # This job runs `vp env doctor` under bash `set -e`, and doctor compares vp's + # resolved home against PATH. Namespace's Windows runners execute jobs under a + # Session-0 service account whose real profile is + # C:\Windows\system32\config\systemprofile, not %USERPROFILE%, so even with + # VP_HOME set the installed vp resolves the systemprofile home and doctor + # fails. The other install jobs pass on Namespace because they don't run + # `vp env doctor` under `set -e`. + runs-on: windows-latest permissions: contents: read steps: - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 - - name: Pin VP_HOME to USERPROFILE - # Namespace's Windows runners run jobs under a service account whose real - # profile (C:\Windows\system32\config\systemprofile) differs from - # %USERPROFILE%; vp resolves its home from the OS profile. Pin VP_HOME so - # the install, generated shims, and these assertions share one location. - shell: bash - run: echo "VP_HOME=$USERPROFILE\.vite-plus" >> $GITHUB_ENV - - name: Run install.ps1 shell: pwsh run: | From c9e4d346431ee92e1614079b63b26b40966da7b8 Mon Sep 17 00:00:00 2001 From: MK Date: Thu, 9 Jul 2026 00:03:52 +0800 Subject: [PATCH 10/10] ci(windows): note Dev Drive is verified working on the Namespace runner setup-dev-drive v4 mounts its ReFS VHD on namespace-profile-windows-4c-8g and all three cli-snap-test Windows shards pass with the step succeeding, so the shards stay on Namespace. Documents this inline in response to review feedback. --- .github/workflows/ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d0be52ea8d..89ba8c3a49 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -949,6 +949,11 @@ jobs: - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 - uses: ./.github/actions/clone + # Dev Drive works on the Namespace Windows runner: setup-dev-drive v4 + # creates and mounts its ReFS VHD on namespace-profile-windows-4c-8g, and + # all three Windows shards pass with this step succeeding (nested + # virtualization is available there). Only cli-snapshot-test-windows moved + # off Namespace, and for an unrelated reason (Session-0 ConPTY, see there). - name: Setup Dev Drive if: runner.os == 'Windows' uses: samypr100/setup-dev-drive@30f0f98ae5636b2b6501e181dfb3631b9974818d # v4.0.0