From 782bbf2a2c8e57602277627b0b9e77dc19706440 Mon Sep 17 00:00:00 2001 From: Michael Lively Date: Tue, 20 Oct 2026 17:34:41 -0700 Subject: [PATCH 01/10] ci: move PR checks to GitHub-hosted 8-core runners Replace the 1ES self-hosted pools in pr.yml, pr-win32-test.yml and pr-node-modules.yml with the vscode-large-runners-ubuntu-8-core and vscode-large-runners-windows-8-core pools, and move the Linux test and CLI jobs from the standard 4-core runners to the 8-core pool. The Electron cache version includes the absolute cache path, so update the runner home directories in detect-missing-caches to the GitHub-hosted ones (/home/runner, C:\Users\runneradmin). Refs: microsoft/vscode-engineering#4273 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/actions/detect-missing-caches/detect.ts | 4 ++-- .github/workflows/pr-linux-cli-test.yml | 2 +- .github/workflows/pr-linux-test.yml | 2 +- .github/workflows/pr-node-modules.yml | 10 +++++----- .github/workflows/pr-win32-test.yml | 3 +-- .github/workflows/pr.yml | 10 +++++----- build/lib/test/detectMissingCaches.test.ts | 4 ++-- 7 files changed, 17 insertions(+), 18 deletions(-) diff --git a/.github/actions/detect-missing-caches/detect.ts b/.github/actions/detect-missing-caches/detect.ts index 85bdb8ed4bf88f..120706ee11677f 100644 --- a/.github/actions/detect-missing-caches/detect.ts +++ b/.github/actions/detect-missing-caches/detect.ts @@ -110,9 +110,9 @@ export const cacheWarmingJobs: Readonly> = { * depends on the home directory of the runners and is part of the cache version. */ const electronCachePaths: Readonly> = { - Linux: '/home/cloudtest/.cache/electron', + Linux: '/home/runner/.cache/electron', macOS: '/Users/runner/Library/Caches/electron', - Windows: 'C:\\Users\\cloudtest\\AppData\\Local\\electron\\Cache', + Windows: 'C:\\Users\\runneradmin\\AppData\\Local\\electron\\Cache', }; /** diff --git a/.github/workflows/pr-linux-cli-test.yml b/.github/workflows/pr-linux-cli-test.yml index b266f440049fee..0c1ad94f122ce0 100644 --- a/.github/workflows/pr-linux-cli-test.yml +++ b/.github/workflows/pr-linux-cli-test.yml @@ -34,7 +34,7 @@ jobs: # Skip this job rather than the calling job: a skipped job still reports # " / ", which satisfies required status checks. if: ${{ inputs.affected }} - runs-on: ubuntu-24.04 + runs-on: vscode-large-runners-ubuntu-8-core env: RUSTUP_TOOLCHAIN: ${{ inputs.rustup_toolchain }} steps: diff --git a/.github/workflows/pr-linux-test.yml b/.github/workflows/pr-linux-test.yml index 40b8b644d6eae1..716dd03c487eb0 100644 --- a/.github/workflows/pr-linux-test.yml +++ b/.github/workflows/pr-linux-test.yml @@ -34,7 +34,7 @@ on: jobs: linux-test: name: ${{ inputs.job_name }} - runs-on: ubuntu-24.04 + runs-on: vscode-large-runners-ubuntu-8-core env: ARTIFACT_NAME: ${{ (inputs.electron_tests && 'electron') || (inputs.browser_tests && 'browser') || (inputs.remote_tests && 'remote') || 'unknown' }}${{ (inputs.unit_tests && !inputs.integration_tests && '-unit') || (!inputs.unit_tests && !inputs.integration_tests && inputs.smoke_tests && '-smoke') || '' }}${{ inputs.smoke_shard_total > 1 && format('-shard{0}', inputs.smoke_shard_index) || '' }} NPM_ARCH: x64 diff --git a/.github/workflows/pr-node-modules.yml b/.github/workflows/pr-node-modules.yml index 9eb1561b03d334..1cf2895d9e305e 100644 --- a/.github/workflows/pr-node-modules.yml +++ b/.github/workflows/pr-node-modules.yml @@ -48,7 +48,7 @@ jobs: name: Compile needs: caches if: ${{ !cancelled() && (needs.caches.result != 'success' || needs.caches.outputs.compile == 'true') }} - runs-on: [ self-hosted, 1ES.Pool=1es-vscode-oss-ubuntu-22.04-x64, "JobId=compile-${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }}" ] + runs-on: vscode-large-runners-ubuntu-8-core steps: - name: Checkout microsoft/vscode uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -119,7 +119,7 @@ jobs: name: Linux needs: caches if: ${{ !cancelled() && (needs.caches.result != 'success' || needs.caches.outputs.linux == 'true') }} - runs-on: [ self-hosted, 1ES.Pool=1es-vscode-oss-ubuntu-22.04-x64, "JobId=linux-${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }}" ] + runs-on: vscode-large-runners-ubuntu-8-core env: NPM_ARCH: x64 VSCODE_ARCH: x64 @@ -284,7 +284,7 @@ jobs: name: Windows needs: caches if: ${{ !cancelled() && (needs.caches.result != 'success' || needs.caches.outputs.windows == 'true') }} - runs-on: [ self-hosted, 1ES.Pool=1es-vscode-oss-windows-2022-x64, "JobId=windows-${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }}" ] + runs-on: vscode-large-runners-windows-8-core env: NPM_ARCH: x64 VSCODE_ARCH: x64 @@ -368,7 +368,7 @@ jobs: name: Copilot (Linux) needs: caches if: ${{ !cancelled() && (needs.caches.result != 'success' || needs.caches.outputs.copilot-linux == 'true') }} - runs-on: [ self-hosted, 1ES.Pool=1es-vscode-oss-ubuntu-22.04-x64, "JobId=copilot-linux-${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }}" ] + runs-on: vscode-large-runners-ubuntu-8-core steps: - name: Checkout microsoft/vscode uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -403,7 +403,7 @@ jobs: name: Copilot (Windows) needs: caches if: ${{ !cancelled() && (needs.caches.result != 'success' || needs.caches.outputs.copilot-windows == 'true') }} - runs-on: [ self-hosted, 1ES.Pool=1es-vscode-oss-windows-2022-x64, "JobId=copilot-windows-${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }}" ] + runs-on: vscode-large-runners-windows-8-core steps: - name: Checkout microsoft/vscode uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/.github/workflows/pr-win32-test.yml b/.github/workflows/pr-win32-test.yml index 8086a9302ee1b4..8079faeb488f60 100644 --- a/.github/workflows/pr-win32-test.yml +++ b/.github/workflows/pr-win32-test.yml @@ -34,8 +34,7 @@ on: jobs: windows-test: name: ${{ inputs.job_name }} - # JobId must be unique per job, so smoke test shards and the browser unit tests part add a suffix - runs-on: [ self-hosted, 1ES.Pool=1es-vscode-oss-windows-2022-x64, "JobId=windows-test-${{ inputs.job_name }}${{ (inputs.unit_tests && !inputs.integration_tests && '-unit') || '' }}${{ inputs.smoke_shard_total > 1 && format('-shard{0}', inputs.smoke_shard_index) || '' }}-${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }}" ] + runs-on: vscode-large-runners-windows-8-core env: ARTIFACT_NAME: ${{ (inputs.electron_tests && 'electron') || (inputs.browser_tests && 'browser') || (inputs.remote_tests && 'remote') || 'unknown' }}${{ (inputs.unit_tests && !inputs.integration_tests && '-unit') || (!inputs.unit_tests && !inputs.integration_tests && inputs.smoke_tests && '-smoke') || '' }}${{ inputs.smoke_shard_total > 1 && format('-shard{0}', inputs.smoke_shard_index) || '' }} NPM_ARCH: x64 diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 2245995803c7a7..41228cefb3f536 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -49,7 +49,7 @@ jobs: compile: name: Compile & Hygiene - runs-on: [ self-hosted, 1ES.Pool=1es-vscode-oss-ubuntu-22.04-x64, "JobId=compile-${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }}" ] + runs-on: vscode-large-runners-ubuntu-8-core steps: - name: Checkout microsoft/vscode uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -480,7 +480,7 @@ jobs: name: Copilot - Check Test Cache needs: changes if: ${{ !cancelled() && (needs.changes.result != 'success' || needs.changes.outputs.copilot == 'true') }} - runs-on: [ self-hosted, 1ES.Pool=1es-vscode-oss-ubuntu-22.04-x64, "JobId=copilot-check-test-cache-${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }}" ] + runs-on: vscode-large-runners-ubuntu-8-core permissions: contents: read pull-requests: read @@ -527,7 +527,7 @@ jobs: name: Copilot - Check Telemetry needs: changes if: ${{ !cancelled() && (needs.changes.result != 'success' || needs.changes.outputs.copilot == 'true') }} - runs-on: [ self-hosted, 1ES.Pool=1es-vscode-oss-ubuntu-22.04-x64, "JobId=copilot-check-telemetry-${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }}" ] + runs-on: vscode-large-runners-ubuntu-8-core permissions: contents: read steps: @@ -548,7 +548,7 @@ jobs: name: Copilot - Test (Linux) needs: changes if: ${{ !cancelled() && (needs.changes.result != 'success' || needs.changes.outputs.copilot == 'true') }} - runs-on: [ self-hosted, 1ES.Pool=1es-vscode-oss-ubuntu-22.04-x64, "JobId=copilot-linux-tests-${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }}" ] + runs-on: vscode-large-runners-ubuntu-8-core permissions: contents: read steps: @@ -648,7 +648,7 @@ jobs: name: Copilot - Test (Windows) needs: changes if: ${{ !cancelled() && (needs.changes.result != 'success' || needs.changes.outputs.copilot == 'true') }} - runs-on: [ self-hosted, 1ES.Pool=1es-vscode-oss-windows-2022-x64, "JobId=copilot-windows-tests-${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }}" ] + runs-on: vscode-large-runners-windows-8-core permissions: contents: read steps: diff --git a/build/lib/test/detectMissingCaches.test.ts b/build/lib/test/detectMissingCaches.test.ts index 8ceba9876b0ad9..c0cf030ffa1cfc 100644 --- a/build/lib/test/detectMissingCaches.test.ts +++ b/build/lib/test/detectMissingCaches.test.ts @@ -45,8 +45,8 @@ function readRepositoryFile(relativePath: string): Buffer { * The runners of the cache warming jobs, as the cache keys see them. */ const runners: Record = { - '1ES.Pool=1es-vscode-oss-ubuntu-22.04-x64': { platform: 'linux', arch: 'x64', os: 'Linux' }, - '1ES.Pool=1es-vscode-oss-windows-2022-x64': { platform: 'win32', arch: 'x64', os: 'Windows' }, + 'vscode-large-runners-ubuntu-8-core': { platform: 'linux', arch: 'x64', os: 'Linux' }, + 'vscode-large-runners-windows-8-core': { platform: 'win32', arch: 'x64', os: 'Windows' }, 'macos-26-xlarge': { platform: 'darwin', arch: 'arm64', os: 'macOS' }, }; From f3ef5841cf25b9bf28fa7a4fec4468017bb97870 Mon Sep 17 00:00:00 2001 From: Michael Lively Date: Tue, 20 Oct 2026 18:29:10 -0700 Subject: [PATCH 02/10] ci: TEMP add Windows runner disk diagnostics Temporary; will be removed before the PR is ready. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../workflows/tmp-runner-disk-diagnostics.yml | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 .github/workflows/tmp-runner-disk-diagnostics.yml diff --git a/.github/workflows/tmp-runner-disk-diagnostics.yml b/.github/workflows/tmp-runner-disk-diagnostics.yml new file mode 100644 index 00000000000000..d9b199371e426f --- /dev/null +++ b/.github/workflows/tmp-runner-disk-diagnostics.yml @@ -0,0 +1,75 @@ +name: TEMP Runner Disk Diagnostics + +on: pull_request + +permissions: + contents: read + +jobs: + diagnose: + name: Diagnose (${{ matrix.name }}) + strategy: + fail-fast: false + matrix: + include: + - name: large-8-core + runner: vscode-large-runners-windows-8-core + - name: windows-latest + runner: windows-latest + - name: 1es + runner: 1es + runs-on: ${{ matrix.runner == '1es' && fromJSON(format('["self-hosted", "1ES.Pool=1es-vscode-oss-windows-2022-x64", "JobId=diag-{0}-{1}"]', github.run_id, github.run_attempt)) || matrix.runner }} + steps: + - name: System + shell: pwsh + run: | + Get-CimInstance Win32_Processor | Select-Object Name, NumberOfCores, NumberOfLogicalProcessors | Format-List + Get-CimInstance Win32_ComputerSystem | Select-Object Model, TotalPhysicalMemory | Format-List + Get-Volume | Where-Object DriveLetter | Format-Table DriveLetter, FileSystem, FileSystemLabel, Size, SizeRemaining -AutoSize + Get-PhysicalDisk | Format-Table DeviceId, FriendlyName, MediaType, BusType, Size -AutoSize + Get-PhysicalDisk | ForEach-Object { Get-StorageAdvancedProperty -PhysicalDisk $_ } | Format-Table -AutoSize + Get-Partition | Where-Object DriveLetter | Format-Table DiskNumber, DriveLetter, Size -AutoSize + Get-MpComputerStatus | Select-Object AMRunningMode, AntivirusEnabled, RealTimeProtectionEnabled, OnAccessProtectionEnabled, IoavProtectionEnabled, BehaviorMonitorEnabled | Format-List + (Get-MpPreference).ExclusionPath + fltmc + "GITHUB_WORKSPACE=$env:GITHUB_WORKSPACE RUNNER_TEMP=$env:RUNNER_TEMP TEMP=$env:TEMP LOCALAPPDATA=$env:LOCALAPPDATA USERPROFILE=$env:USERPROFILE" + + - name: Benchmark + shell: pwsh + run: | + function Test-Directory([string] $Root) { + $dir = Join-Path $Root "fsbench-$([guid]::NewGuid().ToString('N'))" + New-Item -ItemType Directory -Path $dir | Out-Null + $bytes = [byte[]]::new(4096) + $sw = [Diagnostics.Stopwatch]::StartNew() + for ($i = 0; $i -lt 300; $i++) { + $fs = [IO.File]::Open("$dir\s$i", 'Create') + $fs.Write($bytes, 0, 4096) + $fs.Flush($true) + $fs.Dispose() + } + $fsync = $sw.Elapsed.TotalMilliseconds / 300 + $sw.Restart() + for ($i = 0; $i -lt 10000; $i++) { [IO.File]::WriteAllBytes("$dir\f$i", $bytes) } + $create = $sw.Elapsed.TotalMilliseconds / 10000 + $sw.Restart() + $big = [byte[]]::new(1GB) + $fs = [IO.File]::Open("$dir\big", 'Create') + $fs.Write($big, 0, $big.Length) + $fs.Flush($true) + $fs.Dispose() + $seq = 1024 / $sw.Elapsed.TotalSeconds + $sw.Restart() + Remove-Item -LiteralPath $dir -Recurse -Force + $delete = $sw.Elapsed.TotalMilliseconds + '{0,-45} fsync {1,7:N2} ms/file | create {2,6:N3} ms/file | 1 GB write+flush {3,6:N0} MB/s | delete 10301 files {4,6:N0} ms' -f $Root, $fsync, $create, $seq, $delete + } + foreach ($root in @($env:GITHUB_WORKSPACE, $env:RUNNER_TEMP, $env:TEMP, 'C:\', 'D:\') | Select-Object -Unique) { + if (Test-Path -LiteralPath $root) { Test-Directory $root } + } + $sw = [Diagnostics.Stopwatch]::StartNew() + for ($i = 0; $i -lt 50; $i++) { cmd.exe /c exit 0 } + 'spawn cmd.exe: {0:N1} ms' -f ($sw.Elapsed.TotalMilliseconds / 50) + $sw.Restart() + for ($i = 0; $i -lt 20; $i++) { node -e 0 } + 'spawn node.exe: {0:N1} ms' -f ($sw.Elapsed.TotalMilliseconds / 20) From b7475af2ed72938c913817bca8de16c37e481bb6 Mon Sep 17 00:00:00 2001 From: Michael Lively Date: Tue, 20 Oct 2026 18:33:14 -0700 Subject: [PATCH 03/10] ci: TEMP run Agent Host E2E experiments on Windows runners Temporary; will be removed before the PR is ready. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- ...tmp-agent-host-e2e-windows-experiments.yml | 118 ++++++++++++++++++ .../workflows/tmp-runner-disk-diagnostics.yml | 75 ----------- 2 files changed, 118 insertions(+), 75 deletions(-) create mode 100644 .github/workflows/tmp-agent-host-e2e-windows-experiments.yml delete mode 100644 .github/workflows/tmp-runner-disk-diagnostics.yml diff --git a/.github/workflows/tmp-agent-host-e2e-windows-experiments.yml b/.github/workflows/tmp-agent-host-e2e-windows-experiments.yml new file mode 100644 index 00000000000000..8f9a367ea236ab --- /dev/null +++ b/.github/workflows/tmp-agent-host-e2e-windows-experiments.yml @@ -0,0 +1,118 @@ +name: TEMP Agent Host E2E Windows Experiments + +on: pull_request + +permissions: + contents: read + +jobs: + experiment: + name: AH E2E (${{ matrix.name }}) + strategy: + fail-fast: false + matrix: + include: + - name: large-control + runner: vscode-large-runners-windows-8-core + devdrive: false + jobs: '' + - name: large-devdrive-temp + runner: vscode-large-runners-windows-8-core + devdrive: true + jobs: '' + - name: large-jobs3 + runner: vscode-large-runners-windows-8-core + devdrive: false + jobs: '--jobs 3' + - name: 1es-control + runner: 1es + devdrive: false + jobs: '' + runs-on: ${{ matrix.runner == '1es' && fromJSON(format('["self-hosted", "1ES.Pool=1es-vscode-oss-windows-2022-x64", "JobId=ahexp-{0}-{1}"]', github.run_id, github.run_attempt)) || matrix.runner }} + env: + VSCODE_ARCH: x64 + VSCODE_SKIP_PRELAUNCH: '1' + steps: + - name: Checkout microsoft/vscode + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + lfs: true + + - name: Create Dev Drive for TEMP + if: ${{ matrix.devdrive }} + shell: pwsh + run: | + $sw = [Diagnostics.Stopwatch]::StartNew() + $script = Join-Path $env:RUNNER_TEMP 'devdrive.txt' + "create vdisk file=`"C:\devdrive.vhdx`" maximum=61440 type=expandable`nattach vdisk`ncreate partition primary`nassign letter=R" | Out-File -Encoding ascii $script + diskpart /s $script + try { + Format-Volume -DriveLetter R -DevDrive -Confirm:$false -Force | Out-Null + 'Formatted R: as a Dev Drive' + } catch { + "Dev Drive format failed ($_); falling back to ReFS" + Format-Volume -DriveLetter R -FileSystem ReFS -Confirm:$false -Force | Out-Null + } + fsutil devdrv query R: 2>&1 + New-Item -ItemType Directory -Path R:\tmp | Out-Null + Add-Content -Path $env:GITHUB_ENV -Value "TEMP=R:\tmp" + Add-Content -Path $env:GITHUB_ENV -Value "TMP=R:\tmp" + "Dev Drive ready in $([int]$sw.Elapsed.TotalSeconds)s" + Get-Volume -DriveLetter R | Format-Table -AutoSize + + - name: Setup Node.js + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version-file: .nvmrc + + - name: Restore node_modules cache + id: cache-node-modules + uses: ./.github/actions/restore-node-modules + with: + key-prefix: node_modules-windows + key-args: "win32 ${{ env.VSCODE_ARCH }} $(node -p process.arch)" + + - name: Fail on node_modules cache miss + if: steps.cache-node-modules.outputs.cache-hit != 'true' + run: exit 1 + + - name: Transpile client and extensions + shell: pwsh + run: npm run gulp "transpile-client-esbuild" "transpile-extensions" + + - name: Setup Electron + uses: ./.github/actions/setup-electron + with: + arch: ${{ env.VSCODE_ARCH }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Run Agent Host E2E tests with performance counters + timeout-minutes: 45 + shell: pwsh + run: | + $csv = Join-Path $env:RUNNER_TEMP 'perf.csv' + $counters = @('\PhysicalDisk(_Total)\Avg. Disk sec/Write', '\PhysicalDisk(_Total)\Avg. Disk sec/Read', '\PhysicalDisk(_Total)\Disk Transfers/sec', '\PhysicalDisk(_Total)\Current Disk Queue Length', '\Processor(_Total)\% Processor Time', '\Memory\Available MBytes', '\System\Processor Queue Length') + $perf = Start-Process typeperf -ArgumentList (@($counters | ForEach-Object { "`"$_`"" }) + @('-si', '5', '-f', 'CSV', '-o', "`"$csv`"", '-y')) -PassThru -WindowStyle Hidden + "TEMP=$env:TEMP" + $sw = [Diagnostics.Stopwatch]::StartNew() + .\scripts\test-agent-host-e2e.bat --tfs "Integration Tests" $(if ($env:EXTRA_ARGS) { $env:EXTRA_ARGS -split ' ' }) + $exitCode = $LASTEXITCODE + "Agent Host E2E exit code $exitCode after $([math]::Round($sw.Elapsed.TotalMinutes, 1)) min" + Stop-Process -Id $perf.Id -Force -ErrorAction SilentlyContinue + Start-Sleep -Seconds 2 + $rows = Import-Csv $csv + $columns = $rows[0].PSObject.Properties.Name | Select-Object -Skip 1 + foreach ($column in $columns) { + $values = @($rows | ForEach-Object { $_.$column } | Where-Object { $_ -and $_.Trim() } | ForEach-Object { [double]$_ } | Sort-Object) + if ($values.Count -eq 0) { continue } + $avg = ($values | Measure-Object -Average).Average + $p95 = $values[[math]::Min($values.Count - 1, [math]::Floor($values.Count * 0.95))] + '{0,-70} avg {1,12:N4} p95 {2,12:N4} max {3,12:N4}' -f ($column -replace '^\\\\[^\\]+', ''), $avg, $p95, $values[-1] + } + exit $exitCode + env: + EXTRA_ARGS: ${{ matrix.jobs }} + VSCODE_SKIP_AGENT_HOST_E2E: '0' + AGENT_HOST_TEST_PROFILE: full + AGENT_HOST_TEST_PROFILE_REASON: Windows runner experiment diff --git a/.github/workflows/tmp-runner-disk-diagnostics.yml b/.github/workflows/tmp-runner-disk-diagnostics.yml deleted file mode 100644 index d9b199371e426f..00000000000000 --- a/.github/workflows/tmp-runner-disk-diagnostics.yml +++ /dev/null @@ -1,75 +0,0 @@ -name: TEMP Runner Disk Diagnostics - -on: pull_request - -permissions: - contents: read - -jobs: - diagnose: - name: Diagnose (${{ matrix.name }}) - strategy: - fail-fast: false - matrix: - include: - - name: large-8-core - runner: vscode-large-runners-windows-8-core - - name: windows-latest - runner: windows-latest - - name: 1es - runner: 1es - runs-on: ${{ matrix.runner == '1es' && fromJSON(format('["self-hosted", "1ES.Pool=1es-vscode-oss-windows-2022-x64", "JobId=diag-{0}-{1}"]', github.run_id, github.run_attempt)) || matrix.runner }} - steps: - - name: System - shell: pwsh - run: | - Get-CimInstance Win32_Processor | Select-Object Name, NumberOfCores, NumberOfLogicalProcessors | Format-List - Get-CimInstance Win32_ComputerSystem | Select-Object Model, TotalPhysicalMemory | Format-List - Get-Volume | Where-Object DriveLetter | Format-Table DriveLetter, FileSystem, FileSystemLabel, Size, SizeRemaining -AutoSize - Get-PhysicalDisk | Format-Table DeviceId, FriendlyName, MediaType, BusType, Size -AutoSize - Get-PhysicalDisk | ForEach-Object { Get-StorageAdvancedProperty -PhysicalDisk $_ } | Format-Table -AutoSize - Get-Partition | Where-Object DriveLetter | Format-Table DiskNumber, DriveLetter, Size -AutoSize - Get-MpComputerStatus | Select-Object AMRunningMode, AntivirusEnabled, RealTimeProtectionEnabled, OnAccessProtectionEnabled, IoavProtectionEnabled, BehaviorMonitorEnabled | Format-List - (Get-MpPreference).ExclusionPath - fltmc - "GITHUB_WORKSPACE=$env:GITHUB_WORKSPACE RUNNER_TEMP=$env:RUNNER_TEMP TEMP=$env:TEMP LOCALAPPDATA=$env:LOCALAPPDATA USERPROFILE=$env:USERPROFILE" - - - name: Benchmark - shell: pwsh - run: | - function Test-Directory([string] $Root) { - $dir = Join-Path $Root "fsbench-$([guid]::NewGuid().ToString('N'))" - New-Item -ItemType Directory -Path $dir | Out-Null - $bytes = [byte[]]::new(4096) - $sw = [Diagnostics.Stopwatch]::StartNew() - for ($i = 0; $i -lt 300; $i++) { - $fs = [IO.File]::Open("$dir\s$i", 'Create') - $fs.Write($bytes, 0, 4096) - $fs.Flush($true) - $fs.Dispose() - } - $fsync = $sw.Elapsed.TotalMilliseconds / 300 - $sw.Restart() - for ($i = 0; $i -lt 10000; $i++) { [IO.File]::WriteAllBytes("$dir\f$i", $bytes) } - $create = $sw.Elapsed.TotalMilliseconds / 10000 - $sw.Restart() - $big = [byte[]]::new(1GB) - $fs = [IO.File]::Open("$dir\big", 'Create') - $fs.Write($big, 0, $big.Length) - $fs.Flush($true) - $fs.Dispose() - $seq = 1024 / $sw.Elapsed.TotalSeconds - $sw.Restart() - Remove-Item -LiteralPath $dir -Recurse -Force - $delete = $sw.Elapsed.TotalMilliseconds - '{0,-45} fsync {1,7:N2} ms/file | create {2,6:N3} ms/file | 1 GB write+flush {3,6:N0} MB/s | delete 10301 files {4,6:N0} ms' -f $Root, $fsync, $create, $seq, $delete - } - foreach ($root in @($env:GITHUB_WORKSPACE, $env:RUNNER_TEMP, $env:TEMP, 'C:\', 'D:\') | Select-Object -Unique) { - if (Test-Path -LiteralPath $root) { Test-Directory $root } - } - $sw = [Diagnostics.Stopwatch]::StartNew() - for ($i = 0; $i -lt 50; $i++) { cmd.exe /c exit 0 } - 'spawn cmd.exe: {0:N1} ms' -f ($sw.Elapsed.TotalMilliseconds / 50) - $sw.Restart() - for ($i = 0; $i -lt 20; $i++) { node -e 0 } - 'spawn node.exe: {0:N1} ms' -f ($sw.Elapsed.TotalMilliseconds / 20) From 3f0b418246e99138f454e9163a513b236a9a27bc Mon Sep 17 00:00:00 2001 From: Michael Lively Date: Tue, 20 Oct 2026 19:13:39 -0700 Subject: [PATCH 04/10] ci: TEMP add Windows runner spawn diagnostics Temporary; will be removed before the PR is ready. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../tmp-runner-spawn-diagnostics.yml | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 .github/workflows/tmp-runner-spawn-diagnostics.yml diff --git a/.github/workflows/tmp-runner-spawn-diagnostics.yml b/.github/workflows/tmp-runner-spawn-diagnostics.yml new file mode 100644 index 00000000000000..a213a5e31ac697 --- /dev/null +++ b/.github/workflows/tmp-runner-spawn-diagnostics.yml @@ -0,0 +1,49 @@ +name: TEMP Runner Spawn Diagnostics + +on: pull_request + +permissions: + contents: read + +jobs: + diagnose: + name: Spawn (${{ matrix.name }}) + strategy: + fail-fast: false + matrix: + include: + - name: large-8-core + runner: vscode-large-runners-windows-8-core + - name: windows-latest + runner: windows-latest + - name: 1es + runner: 1es + runs-on: ${{ matrix.runner == '1es' && fromJSON(format('["self-hosted", "1ES.Pool=1es-vscode-oss-windows-2022-x64", "JobId=spawn-{0}-{1}"]', github.run_id, github.run_attempt)) || matrix.runner }} + steps: + - name: Diagnose + shell: pwsh + run: | + $dg = Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard + "VBS status: $($dg.VirtualizationBasedSecurityStatus) (0 off, 1 enabled, 2 running)" + "Security services running: $($dg.SecurityServicesRunning -join ',') (1 Credential Guard, 2 HVCI)" + "Security services configured: $($dg.SecurityServicesConfigured -join ',')" + "Hypervisor present: $((Get-CimInstance Win32_ComputerSystem).HypervisorPresent)" + (Get-CimInstance Win32_ComputerSystem).Model + $node = (Get-Command node).Source + "node: $node" + foreach ($target in @('cmd.exe', $node)) { + for ($round = 0; $round -lt 2; $round++) { + $times = @(for ($i = 0; $i -lt 20; $i++) { + $sw = [Diagnostics.Stopwatch]::StartNew() + if ($target -eq 'cmd.exe') { cmd.exe /c exit 0 } else { & $target -e 0 } + $sw.Elapsed.TotalMilliseconds + }) | Sort-Object + '{0} round {1}: median {2:N1} ms, min {3:N1} ms' -f (Split-Path -Leaf $target), $round, $times[10], $times[0] + } + } + $sw = [Diagnostics.Stopwatch]::StartNew() + $x = 0; for ($i = 0; $i -lt 20000000; $i++) { $x += $i } + 'CPU loop: {0:N0} ms' -f $sw.Elapsed.TotalMilliseconds + $sw = [Diagnostics.Stopwatch]::StartNew() + node -e "let s=0; for (let i=0;i<3e8;i++) s+=i; console.log(s)" | Out-Null + 'node CPU loop: {0:N0} ms' -f $sw.Elapsed.TotalMilliseconds From 215eab0683e88a3420ae9155c13929f5cc56ce57 Mon Sep 17 00:00:00 2001 From: Michael Lively Date: Tue, 20 Oct 2026 19:18:10 -0700 Subject: [PATCH 05/10] ci: TEMP try Dev Drive workspace and flush suppression on Windows Temporary; will be removed before the PR is ready. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- ...tmp-agent-host-e2e-windows-experiments.yml | 97 +++++++++++++------ .../tmp-runner-spawn-diagnostics.yml | 49 ---------- 2 files changed, 69 insertions(+), 77 deletions(-) delete mode 100644 .github/workflows/tmp-runner-spawn-diagnostics.yml diff --git a/.github/workflows/tmp-agent-host-e2e-windows-experiments.yml b/.github/workflows/tmp-agent-host-e2e-windows-experiments.yml index 8f9a367ea236ab..c6e19aebc14c86 100644 --- a/.github/workflows/tmp-agent-host-e2e-windows-experiments.yml +++ b/.github/workflows/tmp-agent-host-e2e-windows-experiments.yml @@ -12,53 +12,94 @@ jobs: fail-fast: false matrix: include: - - name: large-control + - name: large-devdrive-workspace runner: vscode-large-runners-windows-8-core - devdrive: false + variant: devdrive jobs: '' - - name: large-devdrive-temp + - name: large-noflush runner: vscode-large-runners-windows-8-core - devdrive: true + variant: noflush jobs: '' - - name: large-jobs3 - runner: vscode-large-runners-windows-8-core - devdrive: false - jobs: '--jobs 3' - - name: 1es-control - runner: 1es - devdrive: false - jobs: '' - runs-on: ${{ matrix.runner == '1es' && fromJSON(format('["self-hosted", "1ES.Pool=1es-vscode-oss-windows-2022-x64", "JobId=ahexp-{0}-{1}"]', github.run_id, github.run_attempt)) || matrix.runner }} + runs-on: ${{ matrix.runner }} env: VSCODE_ARCH: x64 VSCODE_SKIP_PRELAUNCH: '1' steps: - - name: Checkout microsoft/vscode - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - lfs: true - - - name: Create Dev Drive for TEMP - if: ${{ matrix.devdrive }} + - name: Mount Dev Drive at the workspace and TEMP + if: ${{ matrix.variant == 'devdrive' }} shell: pwsh run: | $sw = [Diagnostics.Stopwatch]::StartNew() $script = Join-Path $env:RUNNER_TEMP 'devdrive.txt' - "create vdisk file=`"C:\devdrive.vhdx`" maximum=61440 type=expandable`nattach vdisk`ncreate partition primary`nassign letter=R" | Out-File -Encoding ascii $script + "create vdisk file=`"C:\devdrive.vhdx`" maximum=102400 type=expandable`nattach vdisk`ncreate partition primary`nassign letter=R" | Out-File -Encoding ascii $script diskpart /s $script - try { - Format-Volume -DriveLetter R -DevDrive -Confirm:$false -Force | Out-Null - 'Formatted R: as a Dev Drive' - } catch { - "Dev Drive format failed ($_); falling back to ReFS" - Format-Volume -DriveLetter R -FileSystem ReFS -Confirm:$false -Force | Out-Null - } + Format-Volume -DriveLetter R -DevDrive -Confirm:$false -Force | Out-Null fsutil devdrv query R: 2>&1 + New-Item -ItemType Directory -Force -Path $env:GITHUB_WORKSPACE | Out-Null + if (Get-ChildItem -Force -LiteralPath $env:GITHUB_WORKSPACE) { throw 'Workspace is not empty' } + Add-PartitionAccessPath -DriveLetter R -AccessPath $env:GITHUB_WORKSPACE New-Item -ItemType Directory -Path R:\tmp | Out-Null Add-Content -Path $env:GITHUB_ENV -Value "TEMP=R:\tmp" Add-Content -Path $env:GITHUB_ENV -Value "TMP=R:\tmp" "Dev Drive ready in $([int]$sw.Elapsed.TotalSeconds)s" Get-Volume -DriveLetter R | Format-Table -AutoSize + Get-Item -LiteralPath $env:GITHUB_WORKSPACE | Format-List FullName, Attributes, LinkType, Target + + - name: Suppress disk cache flushes + if: ${{ matrix.variant == 'noflush' }} + shell: pwsh + run: | + Add-Type -TypeDefinition @' + using System; + using System.ComponentModel; + using System.Runtime.InteropServices; + using Microsoft.Win32.SafeHandles; + public static class DiskCache { + [StructLayout(LayoutKind.Sequential)] + public struct DISK_CACHE_SETTING { public uint Version; public int State; [MarshalAs(UnmanagedType.U1)] public bool IsPowerProtected; } + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] + static extern SafeFileHandle CreateFile(string name, uint access, uint share, IntPtr sa, uint disposition, uint flags, IntPtr template); + [DllImport("kernel32.dll", SetLastError = true)] + static extern bool DeviceIoControl(SafeFileHandle h, uint code, ref DISK_CACHE_SETTING inBuf, int inSize, ref DISK_CACHE_SETTING outBuf, int outSize, out int returned, IntPtr overlapped); + public static string SetPowerProtected(int disk) { + using (var h = CreateFile(@"\\.\PhysicalDrive" + disk, 0xC0000000, 3, IntPtr.Zero, 3, 0, IntPtr.Zero)) { + if (h.IsInvalid) { throw new Win32Exception(); } + var s = new DISK_CACHE_SETTING(); + int size = Marshal.SizeOf(typeof(DISK_CACHE_SETTING)); + int r; + if (!DeviceIoControl(h, 0x740E0, ref s, 0, ref s, size, out r, IntPtr.Zero)) { throw new Win32Exception(); } + string before = "version=" + s.Version + " state=" + s.State + " powerProtected=" + s.IsPowerProtected; + s.Version = (uint)size; + s.IsPowerProtected = true; + if (!DeviceIoControl(h, 0x7C0E4, ref s, size, ref s, 0, out r, IntPtr.Zero)) { throw new Win32Exception(); } + return before; + } + } + } + '@ + function Test-Fsync([string] $Root) { + $dir = Join-Path $Root "fsbench-$([guid]::NewGuid().ToString('N'))" + New-Item -ItemType Directory -Path $dir | Out-Null + $bytes = [byte[]]::new(4096) + $sw = [Diagnostics.Stopwatch]::StartNew() + for ($i = 0; $i -lt 300; $i++) { $fs = [IO.File]::Open("$dir\s$i", 'Create'); $fs.Write($bytes, 0, 4096); $fs.Flush($true); $fs.Dispose() } + $fsync = $sw.Elapsed.TotalMilliseconds / 300 + $sw.Restart() + for ($i = 0; $i -lt 5000; $i++) { [IO.File]::WriteAllBytes("$dir\f$i", $bytes) } + $create = $sw.Elapsed.TotalMilliseconds / 5000 + Remove-Item -LiteralPath $dir -Recurse -Force + 'fsync {0:N2} ms/file, create {1:N3} ms/file' -f $fsync, $create + } + "Before: $(Test-Fsync $env:RUNNER_TEMP)" + $disk = (Get-Partition -DriveLetter C).DiskNumber + "Disk $disk cache setting before: $([DiskCache]::SetPowerProtected($disk))" + Get-PhysicalDisk | ForEach-Object { Get-StorageAdvancedProperty -PhysicalDisk $_ } | Format-Table -AutoSize + "After: $(Test-Fsync $env:RUNNER_TEMP)" + + - name: Checkout microsoft/vscode + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + lfs: true - name: Setup Node.js uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 diff --git a/.github/workflows/tmp-runner-spawn-diagnostics.yml b/.github/workflows/tmp-runner-spawn-diagnostics.yml deleted file mode 100644 index a213a5e31ac697..00000000000000 --- a/.github/workflows/tmp-runner-spawn-diagnostics.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: TEMP Runner Spawn Diagnostics - -on: pull_request - -permissions: - contents: read - -jobs: - diagnose: - name: Spawn (${{ matrix.name }}) - strategy: - fail-fast: false - matrix: - include: - - name: large-8-core - runner: vscode-large-runners-windows-8-core - - name: windows-latest - runner: windows-latest - - name: 1es - runner: 1es - runs-on: ${{ matrix.runner == '1es' && fromJSON(format('["self-hosted", "1ES.Pool=1es-vscode-oss-windows-2022-x64", "JobId=spawn-{0}-{1}"]', github.run_id, github.run_attempt)) || matrix.runner }} - steps: - - name: Diagnose - shell: pwsh - run: | - $dg = Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard - "VBS status: $($dg.VirtualizationBasedSecurityStatus) (0 off, 1 enabled, 2 running)" - "Security services running: $($dg.SecurityServicesRunning -join ',') (1 Credential Guard, 2 HVCI)" - "Security services configured: $($dg.SecurityServicesConfigured -join ',')" - "Hypervisor present: $((Get-CimInstance Win32_ComputerSystem).HypervisorPresent)" - (Get-CimInstance Win32_ComputerSystem).Model - $node = (Get-Command node).Source - "node: $node" - foreach ($target in @('cmd.exe', $node)) { - for ($round = 0; $round -lt 2; $round++) { - $times = @(for ($i = 0; $i -lt 20; $i++) { - $sw = [Diagnostics.Stopwatch]::StartNew() - if ($target -eq 'cmd.exe') { cmd.exe /c exit 0 } else { & $target -e 0 } - $sw.Elapsed.TotalMilliseconds - }) | Sort-Object - '{0} round {1}: median {2:N1} ms, min {3:N1} ms' -f (Split-Path -Leaf $target), $round, $times[10], $times[0] - } - } - $sw = [Diagnostics.Stopwatch]::StartNew() - $x = 0; for ($i = 0; $i -lt 20000000; $i++) { $x += $i } - 'CPU loop: {0:N0} ms' -f $sw.Elapsed.TotalMilliseconds - $sw = [Diagnostics.Stopwatch]::StartNew() - node -e "let s=0; for (let i=0;i<3e8;i++) s+=i; console.log(s)" | Out-Null - 'node CPU loop: {0:N0} ms' -f $sw.Elapsed.TotalMilliseconds From 186e38463121cf6f1c2f46e8ce859e62577acb7f Mon Sep 17 00:00:00 2001 From: Michael Lively Date: Tue, 20 Oct 2026 19:24:12 -0700 Subject: [PATCH 06/10] ci: TEMP mount the Dev Drive above the workspace Temporary; will be removed before the PR is ready. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../workflows/tmp-agent-host-e2e-windows-experiments.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tmp-agent-host-e2e-windows-experiments.yml b/.github/workflows/tmp-agent-host-e2e-windows-experiments.yml index c6e19aebc14c86..1ca5cc1702a793 100644 --- a/.github/workflows/tmp-agent-host-e2e-windows-experiments.yml +++ b/.github/workflows/tmp-agent-host-e2e-windows-experiments.yml @@ -37,13 +37,18 @@ jobs: fsutil devdrv query R: 2>&1 New-Item -ItemType Directory -Force -Path $env:GITHUB_WORKSPACE | Out-Null if (Get-ChildItem -Force -LiteralPath $env:GITHUB_WORKSPACE) { throw 'Workspace is not empty' } - Add-PartitionAccessPath -DriveLetter R -AccessPath $env:GITHUB_WORKSPACE + # Mount the volume above the workspace so that actions/checkout does not try to clean the volume root. + $parent = Split-Path -Parent $env:GITHUB_WORKSPACE + if (@(Get-ChildItem -Force -LiteralPath $parent).Count -ne 1) { throw 'Workspace parent has other entries' } + Remove-Item -LiteralPath $env:GITHUB_WORKSPACE + Add-PartitionAccessPath -DriveLetter R -AccessPath $parent + New-Item -ItemType Directory -Path $env:GITHUB_WORKSPACE | Out-Null New-Item -ItemType Directory -Path R:\tmp | Out-Null Add-Content -Path $env:GITHUB_ENV -Value "TEMP=R:\tmp" Add-Content -Path $env:GITHUB_ENV -Value "TMP=R:\tmp" "Dev Drive ready in $([int]$sw.Elapsed.TotalSeconds)s" Get-Volume -DriveLetter R | Format-Table -AutoSize - Get-Item -LiteralPath $env:GITHUB_WORKSPACE | Format-List FullName, Attributes, LinkType, Target + Get-Item -LiteralPath $parent | Format-List FullName, Attributes, LinkType, Target - name: Suppress disk cache flushes if: ${{ matrix.variant == 'noflush' }} From b82e2ae6e000988534612199335cb9073e194ab9 Mon Sep 17 00:00:00 2001 From: Michael Lively Date: Tue, 20 Oct 2026 19:49:40 -0700 Subject: [PATCH 07/10] ci: TEMP attribute Agent Host E2E disk I/O on Windows Temporary; will be removed before the PR is ready. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- ...tmp-agent-host-e2e-windows-experiments.yml | 131 +++++++----------- 1 file changed, 53 insertions(+), 78 deletions(-) diff --git a/.github/workflows/tmp-agent-host-e2e-windows-experiments.yml b/.github/workflows/tmp-agent-host-e2e-windows-experiments.yml index 1ca5cc1702a793..b9662533c1d97d 100644 --- a/.github/workflows/tmp-agent-host-e2e-windows-experiments.yml +++ b/.github/workflows/tmp-agent-host-e2e-windows-experiments.yml @@ -12,94 +12,45 @@ jobs: fail-fast: false matrix: include: - - name: large-devdrive-workspace + - name: large-devdrive-temp runner: vscode-large-runners-windows-8-core - variant: devdrive - jobs: '' - - name: large-noflush + variant: devdrive-temp + - name: large-devdrive-workspace runner: vscode-large-runners-windows-8-core - variant: noflush - jobs: '' - runs-on: ${{ matrix.runner }} + variant: devdrive-workspace + - name: 1es-control + runner: 1es + variant: control + runs-on: ${{ matrix.runner == '1es' && fromJSON(format('["self-hosted", "1ES.Pool=1es-vscode-oss-windows-2022-x64", "JobId=ahexp3-{0}-{1}"]', github.run_id, github.run_attempt)) || matrix.runner }} env: VSCODE_ARCH: x64 VSCODE_SKIP_PRELAUNCH: '1' steps: - - name: Mount Dev Drive at the workspace and TEMP - if: ${{ matrix.variant == 'devdrive' }} + - name: Create Dev Drive + if: ${{ matrix.variant != 'control' }} + working-directory: ${{ runner.temp }} shell: pwsh run: | $sw = [Diagnostics.Stopwatch]::StartNew() $script = Join-Path $env:RUNNER_TEMP 'devdrive.txt' "create vdisk file=`"C:\devdrive.vhdx`" maximum=102400 type=expandable`nattach vdisk`ncreate partition primary`nassign letter=R" | Out-File -Encoding ascii $script - diskpart /s $script + diskpart /s $script | Out-Null Format-Volume -DriveLetter R -DevDrive -Confirm:$false -Force | Out-Null - fsutil devdrv query R: 2>&1 - New-Item -ItemType Directory -Force -Path $env:GITHUB_WORKSPACE | Out-Null - if (Get-ChildItem -Force -LiteralPath $env:GITHUB_WORKSPACE) { throw 'Workspace is not empty' } - # Mount the volume above the workspace so that actions/checkout does not try to clean the volume root. - $parent = Split-Path -Parent $env:GITHUB_WORKSPACE - if (@(Get-ChildItem -Force -LiteralPath $parent).Count -ne 1) { throw 'Workspace parent has other entries' } - Remove-Item -LiteralPath $env:GITHUB_WORKSPACE - Add-PartitionAccessPath -DriveLetter R -AccessPath $parent - New-Item -ItemType Directory -Path $env:GITHUB_WORKSPACE | Out-Null New-Item -ItemType Directory -Path R:\tmp | Out-Null Add-Content -Path $env:GITHUB_ENV -Value "TEMP=R:\tmp" Add-Content -Path $env:GITHUB_ENV -Value "TMP=R:\tmp" - "Dev Drive ready in $([int]$sw.Elapsed.TotalSeconds)s" - Get-Volume -DriveLetter R | Format-Table -AutoSize - Get-Item -LiteralPath $parent | Format-List FullName, Attributes, LinkType, Target - - - name: Suppress disk cache flushes - if: ${{ matrix.variant == 'noflush' }} - shell: pwsh - run: | - Add-Type -TypeDefinition @' - using System; - using System.ComponentModel; - using System.Runtime.InteropServices; - using Microsoft.Win32.SafeHandles; - public static class DiskCache { - [StructLayout(LayoutKind.Sequential)] - public struct DISK_CACHE_SETTING { public uint Version; public int State; [MarshalAs(UnmanagedType.U1)] public bool IsPowerProtected; } - [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - static extern SafeFileHandle CreateFile(string name, uint access, uint share, IntPtr sa, uint disposition, uint flags, IntPtr template); - [DllImport("kernel32.dll", SetLastError = true)] - static extern bool DeviceIoControl(SafeFileHandle h, uint code, ref DISK_CACHE_SETTING inBuf, int inSize, ref DISK_CACHE_SETTING outBuf, int outSize, out int returned, IntPtr overlapped); - public static string SetPowerProtected(int disk) { - using (var h = CreateFile(@"\\.\PhysicalDrive" + disk, 0xC0000000, 3, IntPtr.Zero, 3, 0, IntPtr.Zero)) { - if (h.IsInvalid) { throw new Win32Exception(); } - var s = new DISK_CACHE_SETTING(); - int size = Marshal.SizeOf(typeof(DISK_CACHE_SETTING)); - int r; - if (!DeviceIoControl(h, 0x740E0, ref s, 0, ref s, size, out r, IntPtr.Zero)) { throw new Win32Exception(); } - string before = "version=" + s.Version + " state=" + s.State + " powerProtected=" + s.IsPowerProtected; - s.Version = (uint)size; - s.IsPowerProtected = true; - if (!DeviceIoControl(h, 0x7C0E4, ref s, size, ref s, 0, out r, IntPtr.Zero)) { throw new Win32Exception(); } - return before; - } - } + if ($env:VARIANT -eq 'devdrive-workspace') { + # Mount the volume above the workspace so that actions/checkout does not clean the volume root. + $parent = Split-Path -Parent $env:GITHUB_WORKSPACE + Get-ChildItem -Force -LiteralPath $parent | Format-Table FullName + Remove-Item -LiteralPath $env:GITHUB_WORKSPACE + if (Get-ChildItem -Force -LiteralPath $parent) { throw 'Workspace parent is not empty' } + Add-PartitionAccessPath -DriveLetter R -AccessPath $parent + New-Item -ItemType Directory -Path $env:GITHUB_WORKSPACE | Out-Null } - '@ - function Test-Fsync([string] $Root) { - $dir = Join-Path $Root "fsbench-$([guid]::NewGuid().ToString('N'))" - New-Item -ItemType Directory -Path $dir | Out-Null - $bytes = [byte[]]::new(4096) - $sw = [Diagnostics.Stopwatch]::StartNew() - for ($i = 0; $i -lt 300; $i++) { $fs = [IO.File]::Open("$dir\s$i", 'Create'); $fs.Write($bytes, 0, 4096); $fs.Flush($true); $fs.Dispose() } - $fsync = $sw.Elapsed.TotalMilliseconds / 300 - $sw.Restart() - for ($i = 0; $i -lt 5000; $i++) { [IO.File]::WriteAllBytes("$dir\f$i", $bytes) } - $create = $sw.Elapsed.TotalMilliseconds / 5000 - Remove-Item -LiteralPath $dir -Recurse -Force - 'fsync {0:N2} ms/file, create {1:N3} ms/file' -f $fsync, $create - } - "Before: $(Test-Fsync $env:RUNNER_TEMP)" - $disk = (Get-Partition -DriveLetter C).DiskNumber - "Disk $disk cache setting before: $([DiskCache]::SetPowerProtected($disk))" - Get-PhysicalDisk | ForEach-Object { Get-StorageAdvancedProperty -PhysicalDisk $_ } | Format-Table -AutoSize - "After: $(Test-Fsync $env:RUNNER_TEMP)" + "Dev Drive ready in $([int]$sw.Elapsed.TotalSeconds)s" + env: + VARIANT: ${{ matrix.variant }} - name: Checkout microsoft/vscode uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -133,19 +84,43 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Run Agent Host E2E tests with performance counters + - name: Run Agent Host E2E tests with I/O attribution timeout-minutes: 45 shell: pwsh run: | $csv = Join-Path $env:RUNNER_TEMP 'perf.csv' - $counters = @('\PhysicalDisk(_Total)\Avg. Disk sec/Write', '\PhysicalDisk(_Total)\Avg. Disk sec/Read', '\PhysicalDisk(_Total)\Disk Transfers/sec', '\PhysicalDisk(_Total)\Current Disk Queue Length', '\Processor(_Total)\% Processor Time', '\Memory\Available MBytes', '\System\Processor Queue Length') + $counters = @('\PhysicalDisk(_Total)\Avg. Disk sec/Write', '\PhysicalDisk(_Total)\Disk Writes/sec', '\PhysicalDisk(_Total)\Disk Write Bytes/sec', '\PhysicalDisk(_Total)\Disk Read Bytes/sec', '\PhysicalDisk(_Total)\Avg. Disk Bytes/Write', '\PhysicalDisk(_Total)\Current Disk Queue Length', '\Processor(_Total)\% Processor Time') $perf = Start-Process typeperf -ArgumentList (@($counters | ForEach-Object { "`"$_`"" }) + @('-si', '5', '-f', 'CSV', '-o', "`"$csv`"", '-y')) -PassThru -WindowStyle Hidden - "TEMP=$env:TEMP" + $stop = Join-Path $env:RUNNER_TEMP 'sampler.stop' + $out = Join-Path $env:RUNNER_TEMP 'sampler.csv' + $sampler = Join-Path $env:RUNNER_TEMP 'sampler.ps1' + @' + param($Stop, $Out) + $seen = @{} + while (-not (Test-Path $Stop)) { + foreach ($p in Get-CimInstance Win32_Process -Property ProcessId, Name, CreationDate, WriteTransferCount, WriteOperationCount, ReadTransferCount) { + $seen["$($p.ProcessId)|$($p.CreationDate)"] = $p + } + Start-Sleep -Milliseconds 1000 + } + $seen.Values | Group-Object Name | ForEach-Object { + [pscustomobject]@{ + Name = $_.Name; Processes = $_.Count + WriteMB = [math]::Round(($_.Group | Measure-Object WriteTransferCount -Sum).Sum / 1MB) + WriteOps = ($_.Group | Measure-Object WriteOperationCount -Sum).Sum + ReadMB = [math]::Round(($_.Group | Measure-Object ReadTransferCount -Sum).Sum / 1MB) + } + } | Sort-Object WriteMB -Descending | Export-Csv -NoTypeInformation $Out + '@ | Set-Content -Path $sampler + $samplerProcess = Start-Process pwsh -ArgumentList @('-NoProfile', '-File', $sampler, $stop, $out) -PassThru -WindowStyle Hidden + "TEMP=$env:TEMP WORKSPACE=$((Get-Item .).FullName)" $sw = [Diagnostics.Stopwatch]::StartNew() - .\scripts\test-agent-host-e2e.bat --tfs "Integration Tests" $(if ($env:EXTRA_ARGS) { $env:EXTRA_ARGS -split ' ' }) + .\scripts\test-agent-host-e2e.bat --tfs "Integration Tests" $exitCode = $LASTEXITCODE "Agent Host E2E exit code $exitCode after $([math]::Round($sw.Elapsed.TotalMinutes, 1)) min" Stop-Process -Id $perf.Id -Force -ErrorAction SilentlyContinue + New-Item -ItemType File -Path $stop | Out-Null + $samplerProcess.WaitForExit(60000) | Out-Null Start-Sleep -Seconds 2 $rows = Import-Csv $csv $columns = $rows[0].PSObject.Properties.Name | Select-Object -Skip 1 @@ -154,11 +129,11 @@ jobs: if ($values.Count -eq 0) { continue } $avg = ($values | Measure-Object -Average).Average $p95 = $values[[math]::Min($values.Count - 1, [math]::Floor($values.Count * 0.95))] - '{0,-70} avg {1,12:N4} p95 {2,12:N4} max {3,12:N4}' -f ($column -replace '^\\\\[^\\]+', ''), $avg, $p95, $values[-1] + 'COUNTER {0,-60} avg {1,14:N3} p95 {2,14:N3} max {3,14:N3}' -f ($column -replace '^\\\\[^\\]+', ''), $avg, $p95, $values[-1] } + Import-Csv $out | Select-Object -First 15 | ForEach-Object { 'WRITER {0,-30} n={1,5} writeMB={2,8} writeOps={3,10} readMB={4,8}' -f $_.Name, $_.Processes, $_.WriteMB, $_.WriteOps, $_.ReadMB } exit $exitCode env: - EXTRA_ARGS: ${{ matrix.jobs }} VSCODE_SKIP_AGENT_HOST_E2E: '0' AGENT_HOST_TEST_PROFILE: full AGENT_HOST_TEST_PROFILE_REASON: Windows runner experiment From 4e1b5a41e5db5d96fa237f8b539f320cef306c6b Mon Sep 17 00:00:00 2001 From: Michael Lively Date: Tue, 20 Oct 2026 20:31:59 -0700 Subject: [PATCH 08/10] ci: TEMP check RAM disk feasibility on Windows runners Temporary; will be removed before the PR is ready. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- ...tmp-agent-host-e2e-windows-experiments.yml | 139 ------------------ .github/workflows/tmp-ramdisk-feasibility.yml | 62 ++++++++ 2 files changed, 62 insertions(+), 139 deletions(-) delete mode 100644 .github/workflows/tmp-agent-host-e2e-windows-experiments.yml create mode 100644 .github/workflows/tmp-ramdisk-feasibility.yml diff --git a/.github/workflows/tmp-agent-host-e2e-windows-experiments.yml b/.github/workflows/tmp-agent-host-e2e-windows-experiments.yml deleted file mode 100644 index b9662533c1d97d..00000000000000 --- a/.github/workflows/tmp-agent-host-e2e-windows-experiments.yml +++ /dev/null @@ -1,139 +0,0 @@ -name: TEMP Agent Host E2E Windows Experiments - -on: pull_request - -permissions: - contents: read - -jobs: - experiment: - name: AH E2E (${{ matrix.name }}) - strategy: - fail-fast: false - matrix: - include: - - name: large-devdrive-temp - runner: vscode-large-runners-windows-8-core - variant: devdrive-temp - - name: large-devdrive-workspace - runner: vscode-large-runners-windows-8-core - variant: devdrive-workspace - - name: 1es-control - runner: 1es - variant: control - runs-on: ${{ matrix.runner == '1es' && fromJSON(format('["self-hosted", "1ES.Pool=1es-vscode-oss-windows-2022-x64", "JobId=ahexp3-{0}-{1}"]', github.run_id, github.run_attempt)) || matrix.runner }} - env: - VSCODE_ARCH: x64 - VSCODE_SKIP_PRELAUNCH: '1' - steps: - - name: Create Dev Drive - if: ${{ matrix.variant != 'control' }} - working-directory: ${{ runner.temp }} - shell: pwsh - run: | - $sw = [Diagnostics.Stopwatch]::StartNew() - $script = Join-Path $env:RUNNER_TEMP 'devdrive.txt' - "create vdisk file=`"C:\devdrive.vhdx`" maximum=102400 type=expandable`nattach vdisk`ncreate partition primary`nassign letter=R" | Out-File -Encoding ascii $script - diskpart /s $script | Out-Null - Format-Volume -DriveLetter R -DevDrive -Confirm:$false -Force | Out-Null - New-Item -ItemType Directory -Path R:\tmp | Out-Null - Add-Content -Path $env:GITHUB_ENV -Value "TEMP=R:\tmp" - Add-Content -Path $env:GITHUB_ENV -Value "TMP=R:\tmp" - if ($env:VARIANT -eq 'devdrive-workspace') { - # Mount the volume above the workspace so that actions/checkout does not clean the volume root. - $parent = Split-Path -Parent $env:GITHUB_WORKSPACE - Get-ChildItem -Force -LiteralPath $parent | Format-Table FullName - Remove-Item -LiteralPath $env:GITHUB_WORKSPACE - if (Get-ChildItem -Force -LiteralPath $parent) { throw 'Workspace parent is not empty' } - Add-PartitionAccessPath -DriveLetter R -AccessPath $parent - New-Item -ItemType Directory -Path $env:GITHUB_WORKSPACE | Out-Null - } - "Dev Drive ready in $([int]$sw.Elapsed.TotalSeconds)s" - env: - VARIANT: ${{ matrix.variant }} - - - name: Checkout microsoft/vscode - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - lfs: true - - - name: Setup Node.js - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 - with: - node-version-file: .nvmrc - - - name: Restore node_modules cache - id: cache-node-modules - uses: ./.github/actions/restore-node-modules - with: - key-prefix: node_modules-windows - key-args: "win32 ${{ env.VSCODE_ARCH }} $(node -p process.arch)" - - - name: Fail on node_modules cache miss - if: steps.cache-node-modules.outputs.cache-hit != 'true' - run: exit 1 - - - name: Transpile client and extensions - shell: pwsh - run: npm run gulp "transpile-client-esbuild" "transpile-extensions" - - - name: Setup Electron - uses: ./.github/actions/setup-electron - with: - arch: ${{ env.VSCODE_ARCH }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Run Agent Host E2E tests with I/O attribution - timeout-minutes: 45 - shell: pwsh - run: | - $csv = Join-Path $env:RUNNER_TEMP 'perf.csv' - $counters = @('\PhysicalDisk(_Total)\Avg. Disk sec/Write', '\PhysicalDisk(_Total)\Disk Writes/sec', '\PhysicalDisk(_Total)\Disk Write Bytes/sec', '\PhysicalDisk(_Total)\Disk Read Bytes/sec', '\PhysicalDisk(_Total)\Avg. Disk Bytes/Write', '\PhysicalDisk(_Total)\Current Disk Queue Length', '\Processor(_Total)\% Processor Time') - $perf = Start-Process typeperf -ArgumentList (@($counters | ForEach-Object { "`"$_`"" }) + @('-si', '5', '-f', 'CSV', '-o', "`"$csv`"", '-y')) -PassThru -WindowStyle Hidden - $stop = Join-Path $env:RUNNER_TEMP 'sampler.stop' - $out = Join-Path $env:RUNNER_TEMP 'sampler.csv' - $sampler = Join-Path $env:RUNNER_TEMP 'sampler.ps1' - @' - param($Stop, $Out) - $seen = @{} - while (-not (Test-Path $Stop)) { - foreach ($p in Get-CimInstance Win32_Process -Property ProcessId, Name, CreationDate, WriteTransferCount, WriteOperationCount, ReadTransferCount) { - $seen["$($p.ProcessId)|$($p.CreationDate)"] = $p - } - Start-Sleep -Milliseconds 1000 - } - $seen.Values | Group-Object Name | ForEach-Object { - [pscustomobject]@{ - Name = $_.Name; Processes = $_.Count - WriteMB = [math]::Round(($_.Group | Measure-Object WriteTransferCount -Sum).Sum / 1MB) - WriteOps = ($_.Group | Measure-Object WriteOperationCount -Sum).Sum - ReadMB = [math]::Round(($_.Group | Measure-Object ReadTransferCount -Sum).Sum / 1MB) - } - } | Sort-Object WriteMB -Descending | Export-Csv -NoTypeInformation $Out - '@ | Set-Content -Path $sampler - $samplerProcess = Start-Process pwsh -ArgumentList @('-NoProfile', '-File', $sampler, $stop, $out) -PassThru -WindowStyle Hidden - "TEMP=$env:TEMP WORKSPACE=$((Get-Item .).FullName)" - $sw = [Diagnostics.Stopwatch]::StartNew() - .\scripts\test-agent-host-e2e.bat --tfs "Integration Tests" - $exitCode = $LASTEXITCODE - "Agent Host E2E exit code $exitCode after $([math]::Round($sw.Elapsed.TotalMinutes, 1)) min" - Stop-Process -Id $perf.Id -Force -ErrorAction SilentlyContinue - New-Item -ItemType File -Path $stop | Out-Null - $samplerProcess.WaitForExit(60000) | Out-Null - Start-Sleep -Seconds 2 - $rows = Import-Csv $csv - $columns = $rows[0].PSObject.Properties.Name | Select-Object -Skip 1 - foreach ($column in $columns) { - $values = @($rows | ForEach-Object { $_.$column } | Where-Object { $_ -and $_.Trim() } | ForEach-Object { [double]$_ } | Sort-Object) - if ($values.Count -eq 0) { continue } - $avg = ($values | Measure-Object -Average).Average - $p95 = $values[[math]::Min($values.Count - 1, [math]::Floor($values.Count * 0.95))] - 'COUNTER {0,-60} avg {1,14:N3} p95 {2,14:N3} max {3,14:N3}' -f ($column -replace '^\\\\[^\\]+', ''), $avg, $p95, $values[-1] - } - Import-Csv $out | Select-Object -First 15 | ForEach-Object { 'WRITER {0,-30} n={1,5} writeMB={2,8} writeOps={3,10} readMB={4,8}' -f $_.Name, $_.Processes, $_.WriteMB, $_.WriteOps, $_.ReadMB } - exit $exitCode - env: - VSCODE_SKIP_AGENT_HOST_E2E: '0' - AGENT_HOST_TEST_PROFILE: full - AGENT_HOST_TEST_PROFILE_REASON: Windows runner experiment diff --git a/.github/workflows/tmp-ramdisk-feasibility.yml b/.github/workflows/tmp-ramdisk-feasibility.yml new file mode 100644 index 00000000000000..4c3592473bfb3d --- /dev/null +++ b/.github/workflows/tmp-ramdisk-feasibility.yml @@ -0,0 +1,62 @@ +name: TEMP RAM Disk Feasibility + +on: pull_request + +permissions: + contents: read + +jobs: + ramdisk: + name: RAM disk (large-8-core) + runs-on: vscode-large-runners-windows-8-core + steps: + - name: Create RAM disk + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + $sw = [Diagnostics.Stopwatch]::StartNew() + $feature = Install-WindowsFeature -Name FS-iSCSITarget-Server + "Install-WindowsFeature: success=$($feature.Success) restart=$($feature.RestartNeeded) after $([int]$sw.Elapsed.TotalSeconds)s" + Set-Service -Name MSiSCSI -StartupType Automatic + Start-Service -Name MSiSCSI + $initiator = (Get-InitiatorPort | Select-Object -First 1).NodeAddress + "Initiator: $initiator" + New-IscsiVirtualDisk -Path 'ramdisk:vscode-test.vhdx' -Size 16GB | Out-Null + New-IscsiServerTarget -TargetName vscode-test -InitiatorIds "IQN:$initiator" | Out-Null + Add-IscsiVirtualDiskTargetMapping -TargetName vscode-test -Path 'ramdisk:vscode-test.vhdx' + New-IscsiTargetPortal -TargetPortalAddress 127.0.0.1 | Out-Null + $target = Get-IscsiTarget | Where-Object NodeAddress -like '*vscode-test*' + Connect-IscsiTarget -NodeAddress $target.NodeAddress | Out-Null + $disk = $null + for ($i = 0; $i -lt 30 -and -not $disk; $i++) { $disk = Get-Disk | Where-Object BusType -eq 'iSCSI'; if (-not $disk) { Start-Sleep 1 } } + $disk | Initialize-Disk -PartitionStyle GPT -PassThru | New-Partition -DriveLetter T -UseMaximumSize | Format-Volume -FileSystem NTFS -Confirm:$false -Force | Out-Null + "RAM disk ready after $([int]$sw.Elapsed.TotalSeconds)s" + Get-Volume -DriveLetter T | Format-Table -AutoSize + Get-PhysicalDisk | Format-Table DeviceId, FriendlyName, BusType, Size -AutoSize + + - name: Benchmark + shell: pwsh + run: | + function Test-Directory([string] $Root) { + $dir = Join-Path $Root "fsbench-$([guid]::NewGuid().ToString('N'))" + New-Item -ItemType Directory -Path $dir | Out-Null + $bytes = [byte[]]::new(9000) + $jobs = 1..6 | ForEach-Object { + Start-ThreadJob -ArgumentList $dir, $_ -ScriptBlock { + param($dir, $n) + $bytes = [byte[]]::new(9000) + $sw = [Diagnostics.Stopwatch]::StartNew() + for ($i = 0; $i -lt 300; $i++) { $fs = [IO.File]::Open("$dir\s$n-$i", 'Create'); $fs.Write($bytes, 0, $bytes.Length); $fs.Flush($true); $fs.Dispose() } + $sw.Elapsed.TotalMilliseconds / 300 + } + } + $fsync = ($jobs | Receive-Job -Wait -AutoRemoveJob | Measure-Object -Average).Average + $sw = [Diagnostics.Stopwatch]::StartNew() + for ($i = 0; $i -lt 5000; $i++) { [IO.File]::WriteAllBytes("$dir\f$i", $bytes) } + $create = $sw.Elapsed.TotalMilliseconds / 5000 + Remove-Item -LiteralPath $dir -Recurse -Force + '{0,-40} 6x parallel write+fsync {1,7:N2} ms/file | create {2,6:N3} ms/file' -f $Root, $fsync, $create + } + Test-Directory $env:RUNNER_TEMP + Test-Directory $env:GITHUB_WORKSPACE + Test-Directory 'T:\' From 4eaff64759439046def2506f088fb25fd3256f59 Mon Sep 17 00:00:00 2001 From: Michael Lively Date: Tue, 20 Oct 2026 20:36:56 -0700 Subject: [PATCH 09/10] ci: TEMP force node_modules cache misses to validate npm ci Remove the temporary diagnostics workflow and change the node_modules cache key prefixes so that every job installs dependencies on the new runners. Will be reverted before the PR is ready. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/pr-linux-test.yml | 2 +- .github/workflows/pr-win32-test.yml | 2 +- .github/workflows/pr.yml | 8 +-- .github/workflows/tmp-ramdisk-feasibility.yml | 62 ------------------- 4 files changed, 6 insertions(+), 68 deletions(-) delete mode 100644 .github/workflows/tmp-ramdisk-feasibility.yml diff --git a/.github/workflows/pr-linux-test.yml b/.github/workflows/pr-linux-test.yml index 716dd03c487eb0..9fbf3e8683e2f7 100644 --- a/.github/workflows/pr-linux-test.yml +++ b/.github/workflows/pr-linux-test.yml @@ -84,7 +84,7 @@ jobs: id: cache-node-modules uses: ./.github/actions/restore-node-modules with: - key-prefix: node_modules-linux + key-prefix: node_modules-linux-validate-miss key-args: "linux ${{ env.VSCODE_ARCH }} $(node -p process.arch)" - name: Install build dependencies diff --git a/.github/workflows/pr-win32-test.yml b/.github/workflows/pr-win32-test.yml index 8079faeb488f60..d180259ada985d 100644 --- a/.github/workflows/pr-win32-test.yml +++ b/.github/workflows/pr-win32-test.yml @@ -77,7 +77,7 @@ jobs: id: cache-node-modules uses: ./.github/actions/restore-node-modules with: - key-prefix: node_modules-windows + key-prefix: node_modules-windows-validate-miss key-args: "win32 ${{ env.VSCODE_ARCH }} $(node -p process.arch)" - name: Install dependencies diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 41228cefb3f536..fc1a3d739472a1 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -63,7 +63,7 @@ jobs: id: cache-node-modules uses: ./.github/actions/restore-node-modules with: - key-prefix: node_modules-compile + key-prefix: node_modules-compile-validate-miss key-args: "compile $(node -p process.arch)" - name: Install build tools @@ -498,7 +498,7 @@ jobs: id: cache-node-modules uses: ./.github/actions/restore-node-modules with: - key-prefix: copilot-node_modules-linux + key-prefix: copilot-node_modules-linux-validate-miss key-args: "$(node -p process.platform) $(node -p process.arch)" - name: Install root dependencies @@ -585,7 +585,7 @@ jobs: id: cache-node-modules uses: ./.github/actions/restore-node-modules with: - key-prefix: copilot-node_modules-linux + key-prefix: copilot-node_modules-linux-validate-miss key-args: "$(node -p process.platform) $(node -p process.arch)" - name: Install root dependencies @@ -680,7 +680,7 @@ jobs: id: cache-node-modules uses: ./.github/actions/restore-node-modules with: - key-prefix: copilot-node_modules-windows + key-prefix: copilot-node_modules-windows-validate-miss key-args: "$(node -p process.platform) $(node -p process.arch)" - name: Install root dependencies diff --git a/.github/workflows/tmp-ramdisk-feasibility.yml b/.github/workflows/tmp-ramdisk-feasibility.yml deleted file mode 100644 index 4c3592473bfb3d..00000000000000 --- a/.github/workflows/tmp-ramdisk-feasibility.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: TEMP RAM Disk Feasibility - -on: pull_request - -permissions: - contents: read - -jobs: - ramdisk: - name: RAM disk (large-8-core) - runs-on: vscode-large-runners-windows-8-core - steps: - - name: Create RAM disk - shell: pwsh - run: | - $ErrorActionPreference = 'Stop' - $sw = [Diagnostics.Stopwatch]::StartNew() - $feature = Install-WindowsFeature -Name FS-iSCSITarget-Server - "Install-WindowsFeature: success=$($feature.Success) restart=$($feature.RestartNeeded) after $([int]$sw.Elapsed.TotalSeconds)s" - Set-Service -Name MSiSCSI -StartupType Automatic - Start-Service -Name MSiSCSI - $initiator = (Get-InitiatorPort | Select-Object -First 1).NodeAddress - "Initiator: $initiator" - New-IscsiVirtualDisk -Path 'ramdisk:vscode-test.vhdx' -Size 16GB | Out-Null - New-IscsiServerTarget -TargetName vscode-test -InitiatorIds "IQN:$initiator" | Out-Null - Add-IscsiVirtualDiskTargetMapping -TargetName vscode-test -Path 'ramdisk:vscode-test.vhdx' - New-IscsiTargetPortal -TargetPortalAddress 127.0.0.1 | Out-Null - $target = Get-IscsiTarget | Where-Object NodeAddress -like '*vscode-test*' - Connect-IscsiTarget -NodeAddress $target.NodeAddress | Out-Null - $disk = $null - for ($i = 0; $i -lt 30 -and -not $disk; $i++) { $disk = Get-Disk | Where-Object BusType -eq 'iSCSI'; if (-not $disk) { Start-Sleep 1 } } - $disk | Initialize-Disk -PartitionStyle GPT -PassThru | New-Partition -DriveLetter T -UseMaximumSize | Format-Volume -FileSystem NTFS -Confirm:$false -Force | Out-Null - "RAM disk ready after $([int]$sw.Elapsed.TotalSeconds)s" - Get-Volume -DriveLetter T | Format-Table -AutoSize - Get-PhysicalDisk | Format-Table DeviceId, FriendlyName, BusType, Size -AutoSize - - - name: Benchmark - shell: pwsh - run: | - function Test-Directory([string] $Root) { - $dir = Join-Path $Root "fsbench-$([guid]::NewGuid().ToString('N'))" - New-Item -ItemType Directory -Path $dir | Out-Null - $bytes = [byte[]]::new(9000) - $jobs = 1..6 | ForEach-Object { - Start-ThreadJob -ArgumentList $dir, $_ -ScriptBlock { - param($dir, $n) - $bytes = [byte[]]::new(9000) - $sw = [Diagnostics.Stopwatch]::StartNew() - for ($i = 0; $i -lt 300; $i++) { $fs = [IO.File]::Open("$dir\s$n-$i", 'Create'); $fs.Write($bytes, 0, $bytes.Length); $fs.Flush($true); $fs.Dispose() } - $sw.Elapsed.TotalMilliseconds / 300 - } - } - $fsync = ($jobs | Receive-Job -Wait -AutoRemoveJob | Measure-Object -Average).Average - $sw = [Diagnostics.Stopwatch]::StartNew() - for ($i = 0; $i -lt 5000; $i++) { [IO.File]::WriteAllBytes("$dir\f$i", $bytes) } - $create = $sw.Elapsed.TotalMilliseconds / 5000 - Remove-Item -LiteralPath $dir -Recurse -Force - '{0,-40} 6x parallel write+fsync {1,7:N2} ms/file | create {2,6:N3} ms/file' -f $Root, $fsync, $create - } - Test-Directory $env:RUNNER_TEMP - Test-Directory $env:GITHUB_WORKSPACE - Test-Directory 'T:\' From 6232879fa930746052d20cd962dc41337a31c15c Mon Sep 17 00:00:00 2001 From: Michael Lively Date: Tue, 20 Oct 2026 21:34:30 -0700 Subject: [PATCH 10/10] Revert "ci: TEMP force node_modules cache misses to validate npm ci" The cache-miss path was validated in run 39539559733. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/pr-linux-test.yml | 2 +- .github/workflows/pr-win32-test.yml | 2 +- .github/workflows/pr.yml | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/pr-linux-test.yml b/.github/workflows/pr-linux-test.yml index 9fbf3e8683e2f7..716dd03c487eb0 100644 --- a/.github/workflows/pr-linux-test.yml +++ b/.github/workflows/pr-linux-test.yml @@ -84,7 +84,7 @@ jobs: id: cache-node-modules uses: ./.github/actions/restore-node-modules with: - key-prefix: node_modules-linux-validate-miss + key-prefix: node_modules-linux key-args: "linux ${{ env.VSCODE_ARCH }} $(node -p process.arch)" - name: Install build dependencies diff --git a/.github/workflows/pr-win32-test.yml b/.github/workflows/pr-win32-test.yml index d180259ada985d..8079faeb488f60 100644 --- a/.github/workflows/pr-win32-test.yml +++ b/.github/workflows/pr-win32-test.yml @@ -77,7 +77,7 @@ jobs: id: cache-node-modules uses: ./.github/actions/restore-node-modules with: - key-prefix: node_modules-windows-validate-miss + key-prefix: node_modules-windows key-args: "win32 ${{ env.VSCODE_ARCH }} $(node -p process.arch)" - name: Install dependencies diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index fc1a3d739472a1..41228cefb3f536 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -63,7 +63,7 @@ jobs: id: cache-node-modules uses: ./.github/actions/restore-node-modules with: - key-prefix: node_modules-compile-validate-miss + key-prefix: node_modules-compile key-args: "compile $(node -p process.arch)" - name: Install build tools @@ -498,7 +498,7 @@ jobs: id: cache-node-modules uses: ./.github/actions/restore-node-modules with: - key-prefix: copilot-node_modules-linux-validate-miss + key-prefix: copilot-node_modules-linux key-args: "$(node -p process.platform) $(node -p process.arch)" - name: Install root dependencies @@ -585,7 +585,7 @@ jobs: id: cache-node-modules uses: ./.github/actions/restore-node-modules with: - key-prefix: copilot-node_modules-linux-validate-miss + key-prefix: copilot-node_modules-linux key-args: "$(node -p process.platform) $(node -p process.arch)" - name: Install root dependencies @@ -680,7 +680,7 @@ jobs: id: cache-node-modules uses: ./.github/actions/restore-node-modules with: - key-prefix: copilot-node_modules-windows-validate-miss + key-prefix: copilot-node_modules-windows key-args: "$(node -p process.platform) $(node -p process.arch)" - name: Install root dependencies