action.yml

  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
 60    - name: Analyze crash dumps
 61      if: always()
 62      shell: powershell
 63      run: |
 64        Write-Host "Checking for crash dumps..."
 65
 66        # Get the CI run start time from the environment
 67        $runStartTime = [DateTime]::new([long]$env:CI_RUN_START_TIME)
 68        Write-Host "Only analyzing dumps created after: $($runStartTime.ToString('yyyy-MM-dd HH:mm:ss'))"
 69
 70        # Check all possible crash dump locations
 71        $searchPaths = @(
 72            "$env:GITHUB_WORKSPACE\crash_dumps",
 73            "$env:LOCALAPPDATA\CrashDumps",
 74            "$env:TEMP",
 75            "$env:GITHUB_WORKSPACE",
 76            "$env:USERPROFILE\AppData\Local\CrashDumps",
 77            "C:\Windows\System32\config\systemprofile\AppData\Local\CrashDumps"
 78        )
 79
 80        $dumps = @()
 81        foreach ($path in $searchPaths) {
 82            if (Test-Path $path) {
 83                Write-Host "Searching in: $path"
 84                $found = Get-ChildItem "$path\*.dmp" -ErrorAction SilentlyContinue | Where-Object {
 85                    $_.CreationTime -gt $runStartTime
 86                }
 87                if ($found) {
 88                    $dumps += $found
 89                    Write-Host "  Found $($found.Count) dump(s) from this CI run"
 90                }
 91            }
 92        }
 93
 94        if ($dumps) {
 95          Write-Host "Found $($dumps.Count) crash dump(s)"
 96
 97          # Install debugging tools if not present
 98          $cdbPath = "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe"
 99          if (-not (Test-Path $cdbPath)) {
100            Write-Host "Installing Windows Debugging Tools..."
101            $url = "https://go.microsoft.com/fwlink/?linkid=2237387"
102            Invoke-WebRequest -Uri $url -OutFile winsdksetup.exe
103            Start-Process -Wait winsdksetup.exe -ArgumentList "/features OptionId.WindowsDesktopDebuggers /quiet"
104          }
105
106          foreach ($dump in $dumps) {
107            Write-Host "`n=================================="
108            Write-Host "Analyzing crash dump: $($dump.Name)"
109            Write-Host "Size: $([math]::Round($dump.Length / 1MB, 2)) MB"
110            Write-Host "Time: $($dump.CreationTime)"
111            Write-Host "=================================="
112
113            # Set symbol path
114            $env:_NT_SYMBOL_PATH = "srv*C:\symbols*https://msdl.microsoft.com/download/symbols"
115
116            # Run analysis
117            $analysisOutput = & $cdbPath -z $dump.FullName -c "!analyze -v; ~*k; lm; q" 2>&1 | Out-String
118
119            # Extract key information
120            if ($analysisOutput -match "ExceptionCode:\s*([\w]+)") {
121              Write-Host "Exception Code: $($Matches[1])"
122              if ($Matches[1] -eq "c0000005") {
123                Write-Host "Exception Type: ACCESS VIOLATION"
124              }
125            }
126
127            if ($analysisOutput -match "EXCEPTION_RECORD:\s*(.+)") {
128              Write-Host "Exception Record: $($Matches[1])"
129            }
130
131            if ($analysisOutput -match "FAULTING_IP:\s*\n(.+)") {
132              Write-Host "Faulting Instruction: $($Matches[1])"
133            }
134
135            # Save full analysis
136            $analysisFile = "$($dump.FullName).analysis.txt"
137            $analysisOutput | Out-File -FilePath $analysisFile
138            Write-Host "`nFull analysis saved to: $analysisFile"
139
140            # Print stack trace section
141            Write-Host "`n--- Stack Trace Preview ---"
142            $stackSection = $analysisOutput -split "STACK_TEXT:" | Select-Object -Last 1
143            $stackLines = $stackSection -split "`n" | Select-Object -First 20
144            $stackLines | ForEach-Object { Write-Host $_ }
145            Write-Host "--- End Stack Trace Preview ---"
146          }
147
148          Write-Host "`nāš ļø  Crash dumps detected! Download the 'crash-dumps' artifact for detailed analysis."
149
150          # Copy dumps to workspace for artifact upload
151          $artifactPath = "$env:GITHUB_WORKSPACE\crash_dumps_collected"
152          New-Item -ItemType Directory -Force -Path $artifactPath | Out-Null
153
154          foreach ($dump in $dumps) {
155            $destName = "$($dump.Directory.Name)_$($dump.Name)"
156            Copy-Item $dump.FullName -Destination "$artifactPath\$destName"
157            if (Test-Path "$($dump.FullName).analysis.txt") {
158              Copy-Item "$($dump.FullName).analysis.txt" -Destination "$artifactPath\$destName.analysis.txt"
159            }
160          }
161
162          Write-Host "Copied $($dumps.Count) dump(s) to artifact directory"
163        } else {
164          Write-Host "No crash dumps from this CI run found"
165        }
166
167    - name: Upload crash dumps
168      if: always()
169      uses: actions/upload-artifact@v4
170      with:
171        name: crash-dumps-${{ github.run_id }}-${{ github.run_attempt }}
172        path: |
173          crash_dumps_collected/*.dmp
174          crash_dumps_collected/*.txt
175        if-no-files-found: ignore
176        retention-days: 7
177
178    - name: Check test results
179      shell: powershell
180      working-directory: ${{ inputs.working-directory }}
181      run: |
182        # Re-check test results to fail the job if tests failed
183        if ($LASTEXITCODE -ne 0) {
184          Write-Host "Tests failed with exit code: $LASTEXITCODE"
185          exit $LASTEXITCODE
186        }