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      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        }