1name: "Run tests on Windows"
2description: "Runs the tests on Windows"
3
4inputs:
5 working-directory:
6 description: "The working directory"
7 required: true
8 default: "."
9
10runs:
11 using: "composite"
12 steps:
13 - name: Install test runner
14 shell: powershell
15 working-directory: ${{ inputs.working-directory }}
16 run: cargo install cargo-nextest --locked
17
18 - name: Install Node
19 uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
20 with:
21 node-version: "18"
22
23 - name: Configure crash dumps
24 shell: powershell
25 run: |
26 # Record the start time for this CI run
27 $runStartTime = Get-Date
28 $runStartTimeStr = $runStartTime.ToString("yyyy-MM-dd HH:mm:ss")
29 Write-Host "CI run started at: $runStartTimeStr"
30
31 # Save the timestamp for later use
32 echo "CI_RUN_START_TIME=$($runStartTime.Ticks)" >> $env:GITHUB_ENV
33
34 # Create crash dump directory in workspace (non-persistent)
35 $dumpPath = "$env:GITHUB_WORKSPACE\crash_dumps"
36 New-Item -ItemType Directory -Force -Path $dumpPath | Out-Null
37
38 Write-Host "Setting up crash dump detection..."
39 Write-Host "Workspace dump path: $dumpPath"
40
41 # Note: We're NOT modifying registry on stateful runners
42 # Instead, we'll check default Windows crash locations after tests
43
44 - name: Run tests
45 shell: powershell
46 working-directory: ${{ inputs.working-directory }}
47 run: |
48 $env:RUST_BACKTRACE = "full"
49
50 # Enable Windows debugging features
51 $env:_NT_SYMBOL_PATH = "srv*https://msdl.microsoft.com/download/symbols"
52
53 # .NET crash dump environment variables (ephemeral)
54 $env:COMPlus_DbgEnableMiniDump = "1"
55 $env:COMPlus_DbgMiniDumpType = "4"
56 $env:COMPlus_CreateDumpDiagnostics = "1"
57
58 cargo nextest run --workspace --no-fail-fast
59 continue-on-error: true
60
61 - name: Analyze crash dumps
62 if: always()
63 shell: powershell
64 run: |
65 Write-Host "Checking for crash dumps..."
66
67 # Get the CI run start time from the environment
68 $runStartTime = [DateTime]::new([long]$env:CI_RUN_START_TIME)
69 Write-Host "Only analyzing dumps created after: $($runStartTime.ToString('yyyy-MM-dd HH:mm:ss'))"
70
71 # Check all possible crash dump locations
72 $searchPaths = @(
73 "$env:GITHUB_WORKSPACE\crash_dumps",
74 "$env:LOCALAPPDATA\CrashDumps",
75 "$env:TEMP",
76 "$env:GITHUB_WORKSPACE",
77 "$env:USERPROFILE\AppData\Local\CrashDumps",
78 "C:\Windows\System32\config\systemprofile\AppData\Local\CrashDumps"
79 )
80
81 $dumps = @()
82 foreach ($path in $searchPaths) {
83 if (Test-Path $path) {
84 Write-Host "Searching in: $path"
85 $found = Get-ChildItem "$path\*.dmp" -ErrorAction SilentlyContinue | Where-Object {
86 $_.CreationTime -gt $runStartTime
87 }
88 if ($found) {
89 $dumps += $found
90 Write-Host " Found $($found.Count) dump(s) from this CI run"
91 }
92 }
93 }
94
95 if ($dumps) {
96 Write-Host "Found $($dumps.Count) crash dump(s)"
97
98 # Install debugging tools if not present
99 $cdbPath = "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe"
100 if (-not (Test-Path $cdbPath)) {
101 Write-Host "Installing Windows Debugging Tools..."
102 $url = "https://go.microsoft.com/fwlink/?linkid=2237387"
103 Invoke-WebRequest -Uri $url -OutFile winsdksetup.exe
104 Start-Process -Wait winsdksetup.exe -ArgumentList "/features OptionId.WindowsDesktopDebuggers /quiet"
105 }
106
107 foreach ($dump in $dumps) {
108 Write-Host "`n=================================="
109 Write-Host "Analyzing crash dump: $($dump.Name)"
110 Write-Host "Size: $([math]::Round($dump.Length / 1MB, 2)) MB"
111 Write-Host "Time: $($dump.CreationTime)"
112 Write-Host "=================================="
113
114 # Set symbol path
115 $env:_NT_SYMBOL_PATH = "srv*C:\symbols*https://msdl.microsoft.com/download/symbols"
116
117 # Run analysis
118 $analysisOutput = & $cdbPath -z $dump.FullName -c "!analyze -v; ~*k; lm; q" 2>&1 | Out-String
119
120 # Extract key information
121 if ($analysisOutput -match "ExceptionCode:\s*([\w]+)") {
122 Write-Host "Exception Code: $($Matches[1])"
123 if ($Matches[1] -eq "c0000005") {
124 Write-Host "Exception Type: ACCESS VIOLATION"
125 }
126 }
127
128 if ($analysisOutput -match "EXCEPTION_RECORD:\s*(.+)") {
129 Write-Host "Exception Record: $($Matches[1])"
130 }
131
132 if ($analysisOutput -match "FAULTING_IP:\s*\n(.+)") {
133 Write-Host "Faulting Instruction: $($Matches[1])"
134 }
135
136 # Save full analysis
137 $analysisFile = "$($dump.FullName).analysis.txt"
138 $analysisOutput | Out-File -FilePath $analysisFile
139 Write-Host "`nFull analysis saved to: $analysisFile"
140
141 # Print stack trace section
142 Write-Host "`n--- Stack Trace Preview ---"
143 $stackSection = $analysisOutput -split "STACK_TEXT:" | Select-Object -Last 1
144 $stackLines = $stackSection -split "`n" | Select-Object -First 20
145 $stackLines | ForEach-Object { Write-Host $_ }
146 Write-Host "--- End Stack Trace Preview ---"
147 }
148
149 Write-Host "`nā ļø Crash dumps detected! Download the 'crash-dumps' artifact for detailed analysis."
150
151 # Copy dumps to workspace for artifact upload
152 $artifactPath = "$env:GITHUB_WORKSPACE\crash_dumps_collected"
153 New-Item -ItemType Directory -Force -Path $artifactPath | Out-Null
154
155 foreach ($dump in $dumps) {
156 $destName = "$($dump.Directory.Name)_$($dump.Name)"
157 Copy-Item $dump.FullName -Destination "$artifactPath\$destName"
158 if (Test-Path "$($dump.FullName).analysis.txt") {
159 Copy-Item "$($dump.FullName).analysis.txt" -Destination "$artifactPath\$destName.analysis.txt"
160 }
161 }
162
163 Write-Host "Copied $($dumps.Count) dump(s) to artifact directory"
164 } else {
165 Write-Host "No crash dumps from this CI run found"
166 }
167
168 - name: Upload crash dumps
169 if: always()
170 uses: actions/upload-artifact@v4
171 with:
172 name: crash-dumps-${{ github.run_id }}-${{ github.run_attempt }}
173 path: |
174 crash_dumps_collected/*.dmp
175 crash_dumps_collected/*.txt
176 if-no-files-found: ignore
177 retention-days: 7
178
179 - name: Check test results
180 shell: powershell
181 working-directory: ${{ inputs.working-directory }}
182 run: |
183 # Re-check test results to fail the job if tests failed
184 if ($LASTEXITCODE -ne 0) {
185 Write-Host "Tests failed with exit code: $LASTEXITCODE"
186 exit $LASTEXITCODE
187 }