name: Integration Tests (Excel)
# This workflow runs Excel COM integration tests on a self-hosted Azure VM runner
# Requires: Azure Windows VM with Microsoft Excel and GitHub Actions runner installed
# Setup Guide: docs/AZURE_SELFHOSTED_RUNNER_SETUP.md
#
# Trigger Options:
# - Manual: Workflow dispatch from Actions tab
# - PR Optional: Add 'run-integration-tests' label to PR
permissions:
contents: read
checks: write # Required for test reporter
pull-requests: write # Required for PR comments
on:
# Allow manual trigger from Actions tab
workflow_dispatch:
# Optional: Run on PR when specifically requested via label
pull_request:
types: [labeled]
branches: [ main ]
jobs:
integration-tests:
runs-on: [self-hosted, windows, excel]
timeout-minutes: 90
# Run on manual dispatch or PR with 'run-integration-tests' label
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && contains(github.event.label.name, 'run-integration-tests'))
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Configure Git safe directory
run: git config --global --add safe.directory ${{ github.workspace }}
shell: pwsh
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Display Excel Version
run: |
try {
$excel = New-Object -ComObject Excel.Application
$version = $excel.Version
Write-Output "โ
Excel Version: $version"
$excel.Quit()
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($excel) | Out-Null
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
} catch {
Write-Error "โ Excel not available: $_"
exit 1
}
shell: pwsh
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore --configuration Release
- name: Verify Core Commands Coverage
run: |
Write-Output "๐ Verifying Core Commands coverage..."
& scripts/audit-core-coverage.ps1 -FailOnGaps
if ($LASTEXITCODE -ne 0) {
Write-Error "โ Coverage gaps detected! All Core methods must be exposed via MCP Server."
exit 1
}
Write-Output "โ
Coverage audit passed - 100% coverage maintained"
shell: pwsh
- name: Run Integration Tests (ComInterop - Foundation)
run: dotnet test tests/ExcelMcp.ComInterop.Tests/ExcelMcp.ComInterop.Tests.csproj --no-build --configuration Release --filter "Category=Integration&RunType!=OnDemand" --logger "trx;LogFileName=cominterop-integration-test-results.trx" --verbosity normal -- RunConfiguration.MaxCpuCount=1
- name: Run Integration Tests (Core - Excluding VBA)
run: dotnet test tests/ExcelMcp.Core.Tests/ExcelMcp.Core.Tests.csproj --no-build --configuration Release --filter "Category=Integration&RunType!=OnDemand&Feature!=VBA&Feature!=VBATrust" --logger "trx;LogFileName=core-integration-test-results.trx" --verbosity normal -- RunConfiguration.MaxCpuCount=1
- name: Run Integration Tests (MCP Server - Excluding VBA)
run: dotnet test tests/ExcelMcp.McpServer.Tests/ExcelMcp.McpServer.Tests.csproj --no-build --configuration Release --filter "Category=Integration&RunType!=OnDemand&Feature!=VBA&Feature!=VBATrust" --logger "trx;LogFileName=mcp-integration-test-results.trx" --verbosity normal -- RunConfiguration.MaxCpuCount=1
- name: Run Integration Tests (CLI - Excluding VBA)
run: dotnet test tests/ExcelMcp.CLI.Tests/ExcelMcp.CLI.Tests.csproj --no-build --configuration Release --filter "Category=Integration&RunType!=OnDemand&Feature!=VBA&Feature!=VBATrust" --logger "trx;LogFileName=cli-integration-test-results.trx" --verbosity normal -- RunConfiguration.MaxCpuCount=1
- name: Upload Test Results
if: always()
uses: actions/upload-artifact@v4
with:
name: integration-test-results-${{ github.run_number }}
path: '**/TestResults/*.trx'
retention-days: 30
- name: Publish Test Results
if: always()
uses: dorny/test-reporter@v1
with:
name: Integration Test Results
path: '**/TestResults/*.trx'
reporter: dotnet-trx
fail-on-error: true
max-annotations: 50
- name: Cleanup Excel Processes
if: always()
run: |
Write-Output "๐งน Cleaning up Excel processes..."
$excelProcesses = Get-Process excel -ErrorAction SilentlyContinue
if ($excelProcesses) {
Write-Output "Found $($excelProcesses.Count) Excel process(es) - terminating..."
$excelProcesses | Stop-Process -Force
Start-Sleep -Seconds 5
Write-Output "โ
Cleanup complete"
} else {
Write-Output "โ
No Excel processes found"
}
# Force garbage collection
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
[System.GC]::Collect()
shell: pwsh
- name: Check for Orphaned Excel Processes
if: always()
run: |
$remainingProcesses = Get-Process excel -ErrorAction SilentlyContinue
if ($remainingProcesses) {
Write-Warning "โ ๏ธ Warning: $($remainingProcesses.Count) Excel process(es) still running after cleanup"
$remainingProcesses | Format-Table Id, ProcessName, StartTime, CPU, WorkingSet -AutoSize
} else {
Write-Output "โ
No orphaned Excel processes detected"
}
shell: pwsh