Run QA Test #2946
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Run QA Test # Runs automated tests on self-hosted QA machines | |
| permissions: | |
| contents: read | |
| on: | |
| workflow_run: | |
| workflows: ["Build"] | |
| types: | |
| - completed | |
| workflow_dispatch: | |
| inputs: | |
| build_id: | |
| description: 'Build workflow run ID (e.g. For github.com/secondlife/viewer/actions/runs/1234567890 the ID is 1234567890)' | |
| required: true | |
| default: '14806728332' | |
| jobs: | |
| debug-workflow: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Debug Workflow Variables | |
| run: | | |
| echo "Workflow Conclusion: ${{ github.event.workflow_run.conclusion }}" | |
| echo "Workflow Head Branch: ${{ github.event.workflow_run.head_branch }}" | |
| echo "Workflow Run ID: ${{ github.event.workflow_run.id }}" | |
| echo "Head Commit Message: ${{ github.event.workflow_run.head_commit.message }}" | |
| echo "GitHub Ref: ${{ github.ref }}" | |
| echo "GitHub Ref Name: ${{ github.ref_name }}" | |
| echo "GitHub Event Name: ${{ github.event_name }}" | |
| echo "GitHub Workflow Name: ${{ github.workflow }}" | |
| install-viewer-and-run-tests: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ matrix.runner }} | |
| cancel-in-progress: false # Prevents cancellation of in-progress jobs | |
| strategy: | |
| matrix: | |
| include: | |
| - os: windows | |
| runner: qa-windows-atlas | |
| artifact: Windows-installer | |
| install-path: 'C:\viewer-automation-main' | |
| - os: windows | |
| runner: qa-windows-asus-dan | |
| artifact: Windows-installer | |
| install-path: 'C:\viewer-automation-main' | |
| - os: windows | |
| runner: qa-windows-kurt | |
| artifact: Windows-installer | |
| install-path: 'C:\viewer-automation-main' | |
| - os: mac | |
| runner: qa-mac-dan | |
| artifact: macOS-installer | |
| install-path: '$HOME/Documents/viewer-automation' | |
| - os: mac | |
| runner: qa-mac-atlas | |
| artifact: macOS-installer | |
| install-path: '$HOME/Documents/viewer-automation' | |
| - os: mac | |
| runner: qa-mac-caleb | |
| artifact: macOS-installer | |
| install-path: '$HOME/Documents/viewer-automation' | |
| fail-fast: false | |
| runs-on: [self-hosted, "${{ matrix.runner }}"] | |
| # Run test only on successful builds of Second_Life_X branches or on manual dispatch | |
| if: > | |
| (github.event_name == 'workflow_run' && | |
| github.event.workflow_run.conclusion == 'success' && | |
| startsWith(github.event.workflow_run.head_branch, 'Second_Life')) || | |
| github.event_name == 'workflow_dispatch' | |
| steps: | |
| # Windows-specific steps | |
| - name: Set Build ID | |
| if: matrix.os == 'windows' | |
| shell: pwsh | |
| run: | | |
| if ("${{ github.event_name }}" -eq "workflow_dispatch") { | |
| echo "BUILD_ID=${{ github.event.inputs.build_id }}" | Out-File -FilePath $env:GITHUB_ENV -Append | |
| echo "ARTIFACTS_URL=https://api.github.com/repos/secondlife/viewer/actions/runs/${{ github.event.inputs.build_id }}/artifacts" | Out-File -FilePath $env:GITHUB_ENV -Append | |
| } else { | |
| echo "BUILD_ID=${{ github.event.workflow_run.id }}" | Out-File -FilePath $env:GITHUB_ENV -Append | |
| echo "ARTIFACTS_URL=https://api.github.com/repos/secondlife/viewer/actions/runs/${{ github.event.workflow_run.id }}/artifacts" | Out-File -FilePath $env:GITHUB_ENV -Append | |
| } | |
| - name: Temporarily Allow PowerShell Scripts (Windows) | |
| if: matrix.os == 'windows' | |
| shell: pwsh | |
| run: | | |
| Set-ExecutionPolicy RemoteSigned -Scope Process -Force | |
| - name: Verify viewer-automation-main Exists (Windows) | |
| if: matrix.os == 'windows' | |
| shell: pwsh | |
| run: | | |
| if (-Not (Test-Path -Path '${{ matrix.install-path }}')) { | |
| Write-Host 'β Error: viewer-automation folder not found on runner!' | |
| exit 1 | |
| } | |
| Write-Host 'β viewer-automation folder is provided.' | |
| - name: Verify viewer-automation-main is Up-To-Date (Windows) | |
| if: matrix.os == 'windows' | |
| shell: pwsh | |
| continue-on-error: true | |
| run: | | |
| cd ${{ matrix.install-path }} | |
| Write-Host "Checking for repository updates..." | |
| # Check if .git directory exists | |
| if (Test-Path -Path ".git") { | |
| try { | |
| # Save local changes instead of discarding them | |
| git stash push -m "Automated stash before update $(Get-Date)" | |
| Write-Host "Local changes saved (if any)" | |
| # Update the repository | |
| git pull | |
| Write-Host "β Repository updated successfully" | |
| # Try to restore local changes if any were stashed | |
| $stashList = git stash list | |
| if ($stashList -match "Automated stash before update") { | |
| try { | |
| git stash pop | |
| Write-Host "β Local changes restored successfully" | |
| } catch { | |
| Write-Host "β οΈ Conflict when restoring local changes" | |
| # Save the conflicted state in a new branch for later review | |
| $branchName = "conflict-recovery-$(Get-Date -Format 'yyyyMMdd-HHmmss')" | |
| git checkout -b $branchName | |
| Write-Host "β Created branch '$branchName' with conflicted state" | |
| # For test execution, revert to a clean state | |
| git reset --hard HEAD | |
| Write-Host "β Reset to clean state for test execution" | |
| } | |
| } | |
| } catch { | |
| Write-Host "β οΈ Could not update repository: $_" | |
| Write-Host "Continuing with existing files..." | |
| } | |
| } else { | |
| Write-Host "β οΈ Not a Git repository, using existing files" | |
| } | |
| - name: Verify Python Installation (Windows) | |
| if: matrix.os == 'windows' | |
| shell: pwsh | |
| run: | | |
| try { | |
| $pythonVersion = (python --version) | |
| Write-Host "β Python found: $pythonVersion" | |
| } catch { | |
| Write-Host "β Error: Python not found in PATH. Please install Python on this runner." | |
| exit 1 | |
| } | |
| - name: Setup Python Virtual Environment (Windows) | |
| if: matrix.os == 'windows' | |
| shell: pwsh | |
| run: | | |
| Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force | |
| cd ${{ matrix.install-path }} | |
| if (-Not (Test-Path -Path ".venv")) { | |
| Write-Host "Creating virtual environment..." | |
| python -m venv .venv | |
| } else { | |
| Write-Host "Using existing virtual environment" | |
| } | |
| # Direct environment activation to avoid script execution issues | |
| $env:VIRTUAL_ENV = "$PWD\.venv" | |
| $env:PATH = "$env:VIRTUAL_ENV\Scripts;$env:PATH" | |
| # Install dependencies | |
| if (Test-Path -Path "requirements.txt") { | |
| Write-Host "Installing dependencies from requirements.txt..." | |
| pip install -r requirements.txt | |
| # Install Playwright browsers - add this line | |
| Write-Host "Installing Playwright browsers..." | |
| python -m playwright install | |
| } else { | |
| pip install outleap requests behave playwright | |
| # Install Playwright browsers - add this line | |
| Write-Host "Installing Playwright browsers..." | |
| python -m playwright install | |
| } | |
| - name: Fetch & Download Installer Artifact (Windows) | |
| if: matrix.os == 'windows' | |
| shell: pwsh | |
| run: | | |
| $BUILD_ID = "${{ env.BUILD_ID }}" | |
| $ARTIFACTS_URL = "${{ env.ARTIFACTS_URL }}" | |
| # Fetch the correct artifact URL | |
| $response = Invoke-RestMethod -Headers @{Authorization="token ${{ secrets.GITHUB_TOKEN }}" } -Uri $ARTIFACTS_URL | |
| $ARTIFACT_NAME = ($response.artifacts | Where-Object { $_.name -eq "${{ matrix.artifact }}" }).archive_download_url | |
| if (-Not $ARTIFACT_NAME) { | |
| Write-Host "β Error: ${{ matrix.artifact }} artifact not found!" | |
| exit 1 | |
| } | |
| Write-Host "β Artifact found: $ARTIFACT_NAME" | |
| # Secure download path | |
| $DownloadPath = "$env:TEMP\secondlife-build-$BUILD_ID" | |
| New-Item -ItemType Directory -Path $DownloadPath -Force | Out-Null | |
| $InstallerPath = "$DownloadPath\installer.zip" | |
| # Download the ZIP | |
| Invoke-WebRequest -Uri $ARTIFACT_NAME -Headers @{Authorization="token ${{ secrets.GITHUB_TOKEN }}"} -OutFile $InstallerPath | |
| # Ensure download succeeded | |
| if (-Not (Test-Path $InstallerPath)) { | |
| Write-Host "β Error: Failed to download ${{ matrix.artifact }}.zip" | |
| exit 1 | |
| } | |
| # Set the path for other steps | |
| echo "DOWNLOAD_PATH=$DownloadPath" | Out-File -FilePath $env:GITHUB_ENV -Append | |
| - name: Extract Installer & Locate Executable (Windows) | |
| if: matrix.os == 'windows' | |
| shell: pwsh | |
| run: | | |
| $BUILD_ID = "${{ env.BUILD_ID }}" | |
| $ExtractPath = "${{ env.DOWNLOAD_PATH }}" | |
| $InstallerZip = "$ExtractPath\installer.zip" | |
| # Print paths for debugging | |
| Write-Host "Extract Path: $ExtractPath" | |
| Write-Host "Installer ZIP Path: $InstallerZip" | |
| # Verify ZIP exists before extracting | |
| if (-Not (Test-Path $InstallerZip)) { | |
| Write-Host "β Error: ZIP file not found at $InstallerZip!" | |
| exit 1 | |
| } | |
| Write-Host "β ZIP file exists and is valid. Extracting..." | |
| Expand-Archive -Path $InstallerZip -DestinationPath $ExtractPath -Force | |
| # Find installer executable | |
| $INSTALLER_PATH = (Get-ChildItem -Path $ExtractPath -Filter '*.exe' -Recurse | Select-Object -First 1).FullName | |
| if (-Not $INSTALLER_PATH -or $INSTALLER_PATH -eq "") { | |
| Write-Host "β Error: No installer executable found in the extracted files!" | |
| Write-Host "π Extracted Files:" | |
| Get-ChildItem -Path $ExtractPath -Recurse | Format-Table -AutoSize | |
| exit 1 | |
| } | |
| Write-Host "β Installer found: $INSTALLER_PATH" | |
| echo "INSTALLER_PATH=$INSTALLER_PATH" | Out-File -FilePath $env:GITHUB_ENV -Append | |
| - name: Install Second Life (Windows) | |
| if: matrix.os == 'windows' | |
| shell: pwsh | |
| run: | | |
| # Windows - Use Task Scheduler to bypass UAC | |
| $action = New-ScheduledTaskAction -Execute "${{ env.INSTALLER_PATH }}" -Argument "/S" | |
| $principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest | |
| $task = New-ScheduledTask -Action $action -Principal $principal | |
| Register-ScheduledTask -TaskName "SilentSLInstaller" -InputObject $task -Force | |
| Start-ScheduledTask -TaskName "SilentSLInstaller" | |
| - name: Wait for Installation to Complete (Windows) | |
| if: matrix.os == 'windows' | |
| shell: pwsh | |
| run: | | |
| Write-Host "Waiting for the Second Life installer to finish..." | |
| do { | |
| Start-Sleep -Seconds 5 | |
| $installerProcess = Get-Process | Where-Object { $_.Path -eq "${{ env.INSTALLER_PATH }}" } | |
| } while ($installerProcess) | |
| Write-Host "β Installation completed!" | |
| - name: Cleanup After Installation (Windows) | |
| if: matrix.os == 'windows' | |
| shell: pwsh | |
| run: | | |
| # Cleanup Task Scheduler Entry | |
| Unregister-ScheduledTask -TaskName "SilentSLInstaller" -Confirm:$false | |
| Write-Host "β Task Scheduler entry removed." | |
| # Delete Installer ZIP | |
| $DeletePath = "${{ env.DOWNLOAD_PATH }}\installer.zip" | |
| Write-Host "Checking if installer ZIP exists: $DeletePath" | |
| # Ensure the ZIP file exists before trying to delete it | |
| if (Test-Path $DeletePath) { | |
| Remove-Item -Path $DeletePath -Force | |
| Write-Host "β Successfully deleted: $DeletePath" | |
| } else { | |
| Write-Host "β οΈ Warning: ZIP file does not exist, skipping deletion." | |
| } | |
| - name: Run QA Test Script (Windows) | |
| if: matrix.os == 'windows' | |
| shell: pwsh | |
| run: | | |
| Write-Host "Running QA Test script on Windows runner: ${{ matrix.runner }}..." | |
| cd ${{ matrix.install-path }} | |
| # Activate virtual environment | |
| Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force | |
| $env:VIRTUAL_ENV = "$PWD\.venv" | |
| $env:PATH = "$env:VIRTUAL_ENV\Scripts;$env:PATH" | |
| # Set runner name as environment variable | |
| $env:RUNNER_NAME = "${{ matrix.runner }}" | |
| # Run the test script | |
| python runTests.py | |
| # Mac-specific steps | |
| - name: Set Build ID (Mac) | |
| if: matrix.os == 'mac' | |
| shell: bash | |
| run: | | |
| if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then | |
| echo "BUILD_ID=${{ github.event.inputs.build_id }}" >> $GITHUB_ENV | |
| echo "ARTIFACTS_URL=https://api.github.com/repos/secondlife/viewer/actions/runs/${{ github.event.inputs.build_id }}/artifacts" >> $GITHUB_ENV | |
| else | |
| echo "BUILD_ID=${{ github.event.workflow_run.id }}" >> $GITHUB_ENV | |
| echo "ARTIFACTS_URL=https://api.github.com/repos/secondlife/viewer/actions/runs/${{ github.event.workflow_run.id }}/artifacts" >> $GITHUB_ENV | |
| fi | |
| - name: Verify viewer-automation-main Exists (Mac) | |
| if: matrix.os == 'mac' | |
| shell: bash | |
| run: | | |
| if [ ! -d "${{ matrix.install-path }}" ]; then | |
| echo "β Error: viewer-automation folder not found on runner!" | |
| exit 1 | |
| fi | |
| echo "β viewer-automation is provided." | |
| - name: Verify viewer-automation-main is Up-To-Date (Mac) | |
| if: matrix.os == 'mac' | |
| shell: bash | |
| continue-on-error: true | |
| run: | | |
| cd ${{ matrix.install-path }} | |
| echo "Checking for repository updates..." | |
| # Check if .git directory exists | |
| if [ -d ".git" ]; then | |
| # Save local changes instead of discarding them | |
| git stash push -m "Automated stash before update $(date)" | |
| echo "Local changes saved (if any)" | |
| # Update the repository | |
| git pull || echo "β οΈ Could not update repository" | |
| echo "β Repository updated (or attempted update)" | |
| # Try to restore local changes if any were stashed | |
| if git stash list | grep -q "Automated stash before update"; then | |
| # Try to pop the stash, but be prepared for conflicts | |
| if ! git stash pop; then | |
| echo "β οΈ Conflict when restoring local changes" | |
| # Save the conflicted state in a new branch for later review | |
| branch_name="conflict-recovery-$(date +%Y%m%d-%H%M%S)" | |
| git checkout -b "$branch_name" | |
| echo "β Created branch '$branch_name' with conflicted state" | |
| # For test execution, revert to a clean state | |
| git reset --hard HEAD | |
| echo "β Reset to clean state for test execution" | |
| else | |
| echo "β Local changes restored successfully" | |
| fi | |
| fi | |
| else | |
| echo "β οΈ Not a Git repository, using existing files" | |
| fi | |
| - name: Verify Python Installation (Mac) | |
| if: matrix.os == 'mac' | |
| shell: bash | |
| run: | | |
| if command -v python3 &> /dev/null; then | |
| PYTHON_VERSION=$(python3 --version) | |
| echo "β Python found: $PYTHON_VERSION" | |
| else | |
| echo "β Error: Python3 not found in PATH. Please install Python on this runner." | |
| exit 1 | |
| fi | |
| - name: Setup Python Virtual Environment (Mac) | |
| if: matrix.os == 'mac' | |
| shell: bash | |
| run: | | |
| cd ${{ matrix.install-path }} | |
| # Create virtual environment if it doesn't exist | |
| if [ ! -d ".venv" ]; then | |
| echo "Creating virtual environment..." | |
| python3 -m venv .venv | |
| else | |
| echo "Using existing virtual environment" | |
| fi | |
| # Activate virtual environment | |
| source .venv/bin/activate | |
| # Install dependencies | |
| if [ -f "requirements.txt" ]; then | |
| pip install -r requirements.txt | |
| echo "β Installed dependencies from requirements.txt" | |
| # Install Playwright browsers - add this line | |
| echo "Installing Playwright browsers..." | |
| python -m playwright install | |
| else | |
| pip install outleap requests behave playwright | |
| echo "β οΈ requirements.txt not found, installed basic dependencies" | |
| # Install Playwright browsers - add this line | |
| echo "Installing Playwright browsers..." | |
| python -m playwright install | |
| fi | |
| - name: Fetch & Download Installer Artifact (Mac) | |
| if: matrix.os == 'mac' | |
| shell: bash | |
| run: | | |
| # Mac-specific Bash commands | |
| response=$(curl -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" -s ${{ env.ARTIFACTS_URL }}) | |
| ARTIFACT_NAME=$(echo $response | jq -r '.artifacts[] | select(.name=="${{ matrix.artifact }}") | .archive_download_url') | |
| if [ -z "$ARTIFACT_NAME" ]; then | |
| echo "β Error: ${{ matrix.artifact }} artifact not found!" | |
| exit 1 | |
| fi | |
| echo "β Artifact found: $ARTIFACT_NAME" | |
| # Secure download path | |
| DOWNLOAD_PATH="/tmp/secondlife-build-${{ env.BUILD_ID }}" | |
| mkdir -p $DOWNLOAD_PATH | |
| INSTALLER_PATH="$DOWNLOAD_PATH/installer.zip" | |
| # Download the ZIP | |
| curl -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" -L $ARTIFACT_NAME -o $INSTALLER_PATH | |
| # Ensure download succeeded | |
| if [ ! -f "$INSTALLER_PATH" ]; then | |
| echo "β Error: Failed to download ${{ matrix.artifact }}.zip" | |
| exit 1 | |
| fi | |
| # Set the path for other steps | |
| echo "DOWNLOAD_PATH=$DOWNLOAD_PATH" >> $GITHUB_ENV | |
| - name: Extract Installer & Locate Executable (Mac) | |
| if: matrix.os == 'mac' | |
| shell: bash | |
| run: | | |
| EXTRACT_PATH="${{ env.DOWNLOAD_PATH }}" | |
| INSTALLER_ZIP="$EXTRACT_PATH/installer.zip" | |
| # Debug output | |
| echo "Extract Path: $EXTRACT_PATH" | |
| echo "Installer ZIP Path: $INSTALLER_ZIP" | |
| # Verify ZIP exists | |
| if [ ! -f "$INSTALLER_ZIP" ]; then | |
| echo "β Error: ZIP file not found at $INSTALLER_ZIP!" | |
| exit 1 | |
| fi | |
| echo "β ZIP file exists and is valid. Extracting..." | |
| # Extract the ZIP | |
| unzip -o "$INSTALLER_ZIP" -d "$EXTRACT_PATH" | |
| # Find DMG file | |
| INSTALLER_PATH=$(find "$EXTRACT_PATH" -name "*.dmg" -type f | head -1) | |
| if [ -z "$INSTALLER_PATH" ]; then | |
| echo "β Error: No installer DMG found in the extracted files!" | |
| echo "π Extracted Files:" | |
| ls -la "$EXTRACT_PATH" | |
| exit 1 | |
| fi | |
| echo "β Installer found: $INSTALLER_PATH" | |
| echo "INSTALLER_PATH=$INSTALLER_PATH" >> $GITHUB_ENV | |
| - name: Install Second Life (Mac) | |
| if: matrix.os == 'mac' | |
| shell: bash | |
| run: | | |
| # Mac installation | |
| echo "Mounting DMG installer..." | |
| MOUNT_POINT="/tmp/secondlife-dmg" | |
| mkdir -p "$MOUNT_POINT" | |
| # Mount the DMG | |
| hdiutil attach "$INSTALLER_PATH" -mountpoint "$MOUNT_POINT" -nobrowse | |
| echo "β DMG mounted at $MOUNT_POINT" | |
| echo "Installing application to default location from DMG..." | |
| # Find the .app bundle in the DMG | |
| APP_PATH=$(find "$MOUNT_POINT" -name "*.app" -type d | head -1) | |
| if [ -z "$APP_PATH" ]; then | |
| echo "β Error: No .app bundle found in the mounted DMG!" | |
| exit 1 | |
| fi | |
| APP_NAME=$(basename "$APP_PATH") | |
| DEST_PATH="/Applications/$APP_NAME" | |
| # Handle existing installation | |
| if [ -d "$DEST_PATH" ]; then | |
| echo "Found existing installation at: $DEST_PATH" | |
| echo "Moving existing installation to trash..." | |
| # Move to trash instead of force removing | |
| TRASH_PATH="$HOME/.Trash/$(date +%Y%m%d_%H%M%S)_$APP_NAME" | |
| mv "$DEST_PATH" "$TRASH_PATH" || { | |
| echo "β οΈ Could not move to trash, trying direct removal..." | |
| rm -rf "$DEST_PATH" || { | |
| echo "β Could not remove existing installation" | |
| echo "Please manually remove: $DEST_PATH" | |
| exit 1 | |
| } | |
| } | |
| echo "β Existing installation handled successfully" | |
| fi | |
| # Copy the .app to /Applications | |
| echo "Copying app from: $APP_PATH" | |
| echo "To destination: /Applications/" | |
| cp -R "$APP_PATH" /Applications/ | |
| # Verify the app was copied successfully | |
| if [ ! -d "$DEST_PATH" ]; then | |
| echo "β Error: Failed to install application to /Applications!" | |
| exit 1 | |
| fi | |
| echo "β Application installed successfully to /Applications" | |
| # Save mount point for cleanup | |
| echo "MOUNT_POINT=$MOUNT_POINT" >> $GITHUB_ENV | |
| - name: Wait for Installation to Complete (Mac) | |
| if: matrix.os == 'mac' | |
| shell: bash | |
| run: | | |
| echo "Waiting for installation to complete..." | |
| # Sleep to allow installation to finish (adjust as needed) | |
| sleep 30 | |
| echo "β Installation completed" | |
| - name: Cleanup After Installation (Mac) | |
| if: matrix.os == 'mac' | |
| shell: bash | |
| run: | | |
| # Mac cleanup | |
| # Unmount the DMG | |
| echo "Unmounting DMG..." | |
| hdiutil detach "${{ env.MOUNT_POINT }}" -force | |
| # Clean up temporary files | |
| echo "Cleaning up temporary files..." | |
| rm -rf "${{ env.DOWNLOAD_PATH }}" | |
| rm -rf "${{ env.MOUNT_POINT }}" | |
| echo "β Cleanup completed" | |
| - name: Run QA Test Script (Mac) | |
| if: matrix.os == 'mac' | |
| shell: bash | |
| run: | | |
| echo "Running QA Test script on Mac runner: ${{ matrix.runner }}..." | |
| cd ${{ matrix.install-path }} | |
| # Activate virtual environment | |
| source .venv/bin/activate | |
| # Set runner name as environment variable | |
| export RUNNER_NAME="${{ matrix.runner }}" | |
| # Run the test script | |
| python runTests.py | |
| # - name: Upload Test Results | |
| # if: always() | |
| # uses: actions/upload-artifact@v4 | |
| # with: | |
| # name: test-results-${{ matrix.runner }} | |
| # path: ${{ matrix.install-path }}/regressionTest/test_results.html |