# .gitea/workflows/test-matrix.yml # Unified test matrix pipeline with TRX reporting for all test categories # Sprint: SPRINT_20251226_007_CICD - Dynamic test discovery # # WORKFLOW INTEGRATION STRATEGY (Sprint 20251226_003_CICD): # ========================================================= # This workflow is the PRIMARY test execution workflow for PR gating. # It dynamically discovers and runs ALL test projects by Category trait. # # PR-Gating Categories (required for merge): # Unit, Architecture, Contract, Integration, Security, Golden # # Scheduled/On-Demand Categories: # Performance, Benchmark, AirGap, Chaos, Determinism, Resilience, Observability # # For build/deploy operations, see: build-test-deploy.yml (runs in parallel) name: Test Matrix on: push: branches: [main] paths-ignore: - 'docs/**' - '*.md' pull_request: paths-ignore: - 'docs/**' - '*.md' schedule: - cron: '0 5 * * *' # Daily at 5 AM UTC workflow_dispatch: inputs: include_performance: description: 'Include performance tests' type: boolean default: false include_benchmark: description: 'Include benchmark tests' type: boolean default: false include_airgap: description: 'Include airgap tests' type: boolean default: false include_chaos: description: 'Include chaos tests' type: boolean default: false include_determinism: description: 'Include determinism tests' type: boolean default: false include_resilience: description: 'Include resilience tests' type: boolean default: false include_observability: description: 'Include observability tests' type: boolean default: false env: DOTNET_VERSION: '10.0.100' DOTNET_NOLOGO: 1 DOTNET_CLI_TELEMETRY_OPTOUT: 1 DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: 1 TZ: UTC jobs: # =========================================================================== # DISCOVER TEST PROJECTS # =========================================================================== discover: name: Discover Tests runs-on: ubuntu-22.04 outputs: test-projects: ${{ steps.find.outputs.projects }} test-count: ${{ steps.find.outputs.count }} steps: - name: Checkout uses: actions/checkout@v4 - name: Find all test projects id: find run: | # Find all test project files, including non-standard naming conventions: # - *.Tests.csproj (standard) # - *UnitTests.csproj, *SmokeTests.csproj, *FixtureTests.csproj, *IntegrationTests.csproj # Exclude: TestKit, Testing libraries, node_modules, bin, obj PROJECTS=$(find src \( \ -name "*.Tests.csproj" \ -o -name "*UnitTests.csproj" \ -o -name "*SmokeTests.csproj" \ -o -name "*FixtureTests.csproj" \ -o -name "*IntegrationTests.csproj" \ \) -type f \ ! -path "*/node_modules/*" \ ! -path "*/.git/*" \ ! -path "*/bin/*" \ ! -path "*/obj/*" \ ! -name "StellaOps.TestKit.csproj" \ ! -name "*Testing.csproj" \ | sort) # Count projects COUNT=$(echo "$PROJECTS" | grep -c '.csproj' || echo "0") echo "Found $COUNT test projects" # Output as JSON array for matrix echo "projects=$(echo "$PROJECTS" | jq -R -s -c 'split("\n") | map(select(length > 0))')" >> $GITHUB_OUTPUT echo "count=$COUNT" >> $GITHUB_OUTPUT - name: Display discovered projects run: | echo "## Discovered Test Projects" >> $GITHUB_STEP_SUMMARY echo "Total: ${{ steps.find.outputs.count }}" >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY find src \( -name "*.Tests.csproj" -o -name "*UnitTests.csproj" -o -name "*SmokeTests.csproj" -o -name "*FixtureTests.csproj" -o -name "*IntegrationTests.csproj" \) -type f ! -path "*/node_modules/*" ! -name "StellaOps.TestKit.csproj" ! -name "*Testing.csproj" | sort >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY # =========================================================================== # PR-GATING TESTS (run on every push/PR) # =========================================================================== unit: name: Unit Tests runs-on: ubuntu-22.04 timeout-minutes: 20 needs: discover steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} include-prerelease: true - name: Run Unit Tests (all test projects) run: | mkdir -p ./TestResults/Unit FAILED=0 PASSED=0 SKIPPED=0 # Find and run all test projects with Unit category # Use expanded pattern to include non-standard naming conventions for proj in $(find src \( -name "*.Tests.csproj" -o -name "*UnitTests.csproj" -o -name "*SmokeTests.csproj" -o -name "*FixtureTests.csproj" -o -name "*IntegrationTests.csproj" \) -type f ! -path "*/node_modules/*" ! -name "StellaOps.TestKit.csproj" ! -name "*Testing.csproj" | sort); do echo "::group::Testing $proj" # Create unique TRX filename using path hash to avoid duplicates TRX_NAME=$(echo "$proj" | sed 's|/|_|g' | sed 's|\.csproj||')-unit.trx # Restore and build in one step, then test if dotnet test "$proj" \ --filter "Category=Unit" \ --configuration Release \ --logger "trx;LogFileName=$TRX_NAME" \ --results-directory ./TestResults/Unit \ --collect:"XPlat Code Coverage" \ --verbosity minimal 2>&1; then PASSED=$((PASSED + 1)) echo "✓ $proj passed" else # Check if it was just "no tests matched" which is not a failure if [ $? -eq 0 ] || grep -q "No test matches" /tmp/test-output.txt 2>/dev/null; then SKIPPED=$((SKIPPED + 1)) echo "○ $proj skipped (no Unit tests)" else FAILED=$((FAILED + 1)) echo "✗ $proj failed" fi fi echo "::endgroup::" done echo "## Unit Test Summary" >> $GITHUB_STEP_SUMMARY echo "- Passed: $PASSED" >> $GITHUB_STEP_SUMMARY echo "- Failed: $FAILED" >> $GITHUB_STEP_SUMMARY echo "- Skipped: $SKIPPED" >> $GITHUB_STEP_SUMMARY # Fail if any tests failed if [ $FAILED -gt 0 ]; then exit 1 fi - name: Upload Test Results uses: actions/upload-artifact@v4 if: always() with: name: test-results-unit path: ./TestResults/Unit retention-days: 14 architecture: name: Architecture Tests runs-on: ubuntu-22.04 timeout-minutes: 15 needs: discover steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} include-prerelease: true - name: Run Architecture Tests (all test projects) run: | mkdir -p ./TestResults/Architecture FAILED=0 PASSED=0 SKIPPED=0 for proj in $(find src \( -name "*.Tests.csproj" -o -name "*UnitTests.csproj" -o -name "*SmokeTests.csproj" -o -name "*FixtureTests.csproj" -o -name "*IntegrationTests.csproj" \) -type f ! -path "*/node_modules/*" ! -name "StellaOps.TestKit.csproj" ! -name "*Testing.csproj" | sort); do echo "::group::Testing $proj" TRX_NAME=$(echo "$proj" | sed 's|/|_|g' | sed 's|\.csproj||')-architecture.trx if dotnet test "$proj" \ --filter "Category=Architecture" \ --configuration Release \ --logger "trx;LogFileName=$TRX_NAME" \ --results-directory ./TestResults/Architecture \ --verbosity minimal 2>&1; then PASSED=$((PASSED + 1)) else SKIPPED=$((SKIPPED + 1)) fi echo "::endgroup::" done echo "## Architecture Test Summary" >> $GITHUB_STEP_SUMMARY echo "- Passed: $PASSED" >> $GITHUB_STEP_SUMMARY echo "- Skipped: $SKIPPED" >> $GITHUB_STEP_SUMMARY - name: Upload Test Results uses: actions/upload-artifact@v4 if: always() with: name: test-results-architecture path: ./TestResults/Architecture retention-days: 14 contract: name: Contract Tests runs-on: ubuntu-22.04 timeout-minutes: 15 needs: discover steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} include-prerelease: true - name: Run Contract Tests (all test projects) run: | mkdir -p ./TestResults/Contract FAILED=0 PASSED=0 SKIPPED=0 for proj in $(find src \( -name "*.Tests.csproj" -o -name "*UnitTests.csproj" -o -name "*SmokeTests.csproj" -o -name "*FixtureTests.csproj" -o -name "*IntegrationTests.csproj" \) -type f ! -path "*/node_modules/*" ! -name "StellaOps.TestKit.csproj" ! -name "*Testing.csproj" | sort); do echo "::group::Testing $proj" TRX_NAME=$(echo "$proj" | sed 's|/|_|g' | sed 's|\.csproj||')-contract.trx if dotnet test "$proj" \ --filter "Category=Contract" \ --configuration Release \ --logger "trx;LogFileName=$TRX_NAME" \ --results-directory ./TestResults/Contract \ --verbosity minimal 2>&1; then PASSED=$((PASSED + 1)) else SKIPPED=$((SKIPPED + 1)) fi echo "::endgroup::" done echo "## Contract Test Summary" >> $GITHUB_STEP_SUMMARY echo "- Passed: $PASSED" >> $GITHUB_STEP_SUMMARY echo "- Skipped: $SKIPPED" >> $GITHUB_STEP_SUMMARY - name: Upload Test Results uses: actions/upload-artifact@v4 if: always() with: name: test-results-contract path: ./TestResults/Contract retention-days: 14 integration: name: Integration Tests runs-on: ubuntu-22.04 timeout-minutes: 45 needs: discover services: postgres: image: postgres:16 env: POSTGRES_USER: stellaops POSTGRES_PASSWORD: stellaops POSTGRES_DB: stellaops_test ports: - 5432:5432 options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} include-prerelease: true - name: Run Integration Tests (all test projects) env: STELLAOPS_TEST_POSTGRES_CONNECTION: "Host=localhost;Port=5432;Database=stellaops_test;Username=stellaops;Password=stellaops" run: | mkdir -p ./TestResults/Integration FAILED=0 PASSED=0 SKIPPED=0 for proj in $(find src \( -name "*.Tests.csproj" -o -name "*UnitTests.csproj" -o -name "*SmokeTests.csproj" -o -name "*FixtureTests.csproj" -o -name "*IntegrationTests.csproj" \) -type f ! -path "*/node_modules/*" ! -name "StellaOps.TestKit.csproj" ! -name "*Testing.csproj" | sort); do echo "::group::Testing $proj" TRX_NAME=$(echo "$proj" | sed 's|/|_|g' | sed 's|\.csproj||')-integration.trx if dotnet test "$proj" \ --filter "Category=Integration" \ --configuration Release \ --logger "trx;LogFileName=$TRX_NAME" \ --results-directory ./TestResults/Integration \ --verbosity minimal 2>&1; then PASSED=$((PASSED + 1)) else SKIPPED=$((SKIPPED + 1)) fi echo "::endgroup::" done echo "## Integration Test Summary" >> $GITHUB_STEP_SUMMARY echo "- Passed: $PASSED" >> $GITHUB_STEP_SUMMARY echo "- Skipped: $SKIPPED" >> $GITHUB_STEP_SUMMARY - name: Upload Test Results uses: actions/upload-artifact@v4 if: always() with: name: test-results-integration path: ./TestResults/Integration retention-days: 14 security: name: Security Tests runs-on: ubuntu-22.04 timeout-minutes: 25 needs: discover steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} include-prerelease: true - name: Run Security Tests (all test projects) run: | mkdir -p ./TestResults/Security FAILED=0 PASSED=0 SKIPPED=0 for proj in $(find src \( -name "*.Tests.csproj" -o -name "*UnitTests.csproj" -o -name "*SmokeTests.csproj" -o -name "*FixtureTests.csproj" -o -name "*IntegrationTests.csproj" \) -type f ! -path "*/node_modules/*" ! -name "StellaOps.TestKit.csproj" ! -name "*Testing.csproj" | sort); do echo "::group::Testing $proj" TRX_NAME=$(echo "$proj" | sed 's|/|_|g' | sed 's|\.csproj||')-security.trx if dotnet test "$proj" \ --filter "Category=Security" \ --configuration Release \ --logger "trx;LogFileName=$TRX_NAME" \ --results-directory ./TestResults/Security \ --verbosity minimal 2>&1; then PASSED=$((PASSED + 1)) else SKIPPED=$((SKIPPED + 1)) fi echo "::endgroup::" done echo "## Security Test Summary" >> $GITHUB_STEP_SUMMARY echo "- Passed: $PASSED" >> $GITHUB_STEP_SUMMARY echo "- Skipped: $SKIPPED" >> $GITHUB_STEP_SUMMARY - name: Upload Test Results uses: actions/upload-artifact@v4 if: always() with: name: test-results-security path: ./TestResults/Security retention-days: 14 golden: name: Golden Tests runs-on: ubuntu-22.04 timeout-minutes: 25 needs: discover steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} include-prerelease: true - name: Run Golden Tests (all test projects) run: | mkdir -p ./TestResults/Golden FAILED=0 PASSED=0 SKIPPED=0 for proj in $(find src \( -name "*.Tests.csproj" -o -name "*UnitTests.csproj" -o -name "*SmokeTests.csproj" -o -name "*FixtureTests.csproj" -o -name "*IntegrationTests.csproj" \) -type f ! -path "*/node_modules/*" ! -name "StellaOps.TestKit.csproj" ! -name "*Testing.csproj" | sort); do echo "::group::Testing $proj" TRX_NAME=$(echo "$proj" | sed 's|/|_|g' | sed 's|\.csproj||')-golden.trx if dotnet test "$proj" \ --filter "Category=Golden" \ --configuration Release \ --logger "trx;LogFileName=$TRX_NAME" \ --results-directory ./TestResults/Golden \ --verbosity minimal 2>&1; then PASSED=$((PASSED + 1)) else SKIPPED=$((SKIPPED + 1)) fi echo "::endgroup::" done echo "## Golden Test Summary" >> $GITHUB_STEP_SUMMARY echo "- Passed: $PASSED" >> $GITHUB_STEP_SUMMARY echo "- Skipped: $SKIPPED" >> $GITHUB_STEP_SUMMARY - name: Upload Test Results uses: actions/upload-artifact@v4 if: always() with: name: test-results-golden path: ./TestResults/Golden retention-days: 14 # =========================================================================== # SCHEDULED/ON-DEMAND TESTS # =========================================================================== performance: name: Performance Tests runs-on: ubuntu-22.04 timeout-minutes: 45 needs: discover if: github.event_name == 'schedule' || github.event.inputs.include_performance == 'true' steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} include-prerelease: true - name: Run Performance Tests (all test projects) run: | mkdir -p ./TestResults/Performance FAILED=0 PASSED=0 SKIPPED=0 for proj in $(find src \( -name "*.Tests.csproj" -o -name "*UnitTests.csproj" -o -name "*SmokeTests.csproj" -o -name "*FixtureTests.csproj" -o -name "*IntegrationTests.csproj" \) -type f ! -path "*/node_modules/*" ! -name "StellaOps.TestKit.csproj" ! -name "*Testing.csproj" | sort); do echo "::group::Testing $proj" TRX_NAME=$(echo "$proj" | sed 's|/|_|g' | sed 's|\.csproj||')-performance.trx if dotnet test "$proj" \ --filter "Category=Performance" \ --configuration Release \ --logger "trx;LogFileName=$TRX_NAME" \ --results-directory ./TestResults/Performance \ --verbosity minimal 2>&1; then PASSED=$((PASSED + 1)) else SKIPPED=$((SKIPPED + 1)) fi echo "::endgroup::" done echo "## Performance Test Summary" >> $GITHUB_STEP_SUMMARY echo "- Passed: $PASSED" >> $GITHUB_STEP_SUMMARY echo "- Skipped: $SKIPPED" >> $GITHUB_STEP_SUMMARY - name: Upload Test Results uses: actions/upload-artifact@v4 if: always() with: name: test-results-performance path: ./TestResults/Performance retention-days: 14 benchmark: name: Benchmark Tests runs-on: ubuntu-22.04 timeout-minutes: 60 needs: discover if: github.event_name == 'schedule' || github.event.inputs.include_benchmark == 'true' steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} include-prerelease: true - name: Run Benchmark Tests (all test projects) run: | mkdir -p ./TestResults/Benchmark FAILED=0 PASSED=0 SKIPPED=0 for proj in $(find src \( -name "*.Tests.csproj" -o -name "*UnitTests.csproj" -o -name "*SmokeTests.csproj" -o -name "*FixtureTests.csproj" -o -name "*IntegrationTests.csproj" \) -type f ! -path "*/node_modules/*" ! -name "StellaOps.TestKit.csproj" ! -name "*Testing.csproj" | sort); do echo "::group::Testing $proj" TRX_NAME=$(echo "$proj" | sed 's|/|_|g' | sed 's|\.csproj||')-benchmark.trx if dotnet test "$proj" \ --filter "Category=Benchmark" \ --configuration Release \ --logger "trx;LogFileName=$TRX_NAME" \ --results-directory ./TestResults/Benchmark \ --verbosity minimal 2>&1; then PASSED=$((PASSED + 1)) else SKIPPED=$((SKIPPED + 1)) fi echo "::endgroup::" done echo "## Benchmark Test Summary" >> $GITHUB_STEP_SUMMARY echo "- Passed: $PASSED" >> $GITHUB_STEP_SUMMARY echo "- Skipped: $SKIPPED" >> $GITHUB_STEP_SUMMARY - name: Upload Test Results uses: actions/upload-artifact@v4 if: always() with: name: test-results-benchmark path: ./TestResults/Benchmark retention-days: 14 airgap: name: AirGap Tests runs-on: ubuntu-22.04 timeout-minutes: 45 needs: discover if: github.event.inputs.include_airgap == 'true' steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} include-prerelease: true - name: Run AirGap Tests (all test projects) run: | mkdir -p ./TestResults/AirGap FAILED=0 PASSED=0 SKIPPED=0 for proj in $(find src \( -name "*.Tests.csproj" -o -name "*UnitTests.csproj" -o -name "*SmokeTests.csproj" -o -name "*FixtureTests.csproj" -o -name "*IntegrationTests.csproj" \) -type f ! -path "*/node_modules/*" ! -name "StellaOps.TestKit.csproj" ! -name "*Testing.csproj" | sort); do echo "::group::Testing $proj" TRX_NAME=$(echo "$proj" | sed 's|/|_|g' | sed 's|\.csproj||')-airgap.trx if dotnet test "$proj" \ --filter "Category=AirGap" \ --configuration Release \ --logger "trx;LogFileName=$TRX_NAME" \ --results-directory ./TestResults/AirGap \ --verbosity minimal 2>&1; then PASSED=$((PASSED + 1)) else SKIPPED=$((SKIPPED + 1)) fi echo "::endgroup::" done echo "## AirGap Test Summary" >> $GITHUB_STEP_SUMMARY echo "- Passed: $PASSED" >> $GITHUB_STEP_SUMMARY echo "- Skipped: $SKIPPED" >> $GITHUB_STEP_SUMMARY - name: Upload Test Results uses: actions/upload-artifact@v4 if: always() with: name: test-results-airgap path: ./TestResults/AirGap retention-days: 14 chaos: name: Chaos Tests runs-on: ubuntu-22.04 timeout-minutes: 45 needs: discover if: github.event.inputs.include_chaos == 'true' steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} include-prerelease: true - name: Run Chaos Tests (all test projects) run: | mkdir -p ./TestResults/Chaos FAILED=0 PASSED=0 SKIPPED=0 for proj in $(find src \( -name "*.Tests.csproj" -o -name "*UnitTests.csproj" -o -name "*SmokeTests.csproj" -o -name "*FixtureTests.csproj" -o -name "*IntegrationTests.csproj" \) -type f ! -path "*/node_modules/*" ! -name "StellaOps.TestKit.csproj" ! -name "*Testing.csproj" | sort); do echo "::group::Testing $proj" TRX_NAME=$(echo "$proj" | sed 's|/|_|g' | sed 's|\.csproj||')-chaos.trx if dotnet test "$proj" \ --filter "Category=Chaos" \ --configuration Release \ --logger "trx;LogFileName=$TRX_NAME" \ --results-directory ./TestResults/Chaos \ --verbosity minimal 2>&1; then PASSED=$((PASSED + 1)) else SKIPPED=$((SKIPPED + 1)) fi echo "::endgroup::" done echo "## Chaos Test Summary" >> $GITHUB_STEP_SUMMARY echo "- Passed: $PASSED" >> $GITHUB_STEP_SUMMARY echo "- Skipped: $SKIPPED" >> $GITHUB_STEP_SUMMARY - name: Upload Test Results uses: actions/upload-artifact@v4 if: always() with: name: test-results-chaos path: ./TestResults/Chaos retention-days: 14 determinism: name: Determinism Tests runs-on: ubuntu-22.04 timeout-minutes: 45 needs: discover if: github.event.inputs.include_determinism == 'true' steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} include-prerelease: true - name: Run Determinism Tests (all test projects) run: | mkdir -p ./TestResults/Determinism FAILED=0 PASSED=0 SKIPPED=0 for proj in $(find src \( -name "*.Tests.csproj" -o -name "*UnitTests.csproj" -o -name "*SmokeTests.csproj" -o -name "*FixtureTests.csproj" -o -name "*IntegrationTests.csproj" \) -type f ! -path "*/node_modules/*" ! -name "StellaOps.TestKit.csproj" ! -name "*Testing.csproj" | sort); do echo "::group::Testing $proj" TRX_NAME=$(echo "$proj" | sed 's|/|_|g' | sed 's|\.csproj||')-determinism.trx if dotnet test "$proj" \ --filter "Category=Determinism" \ --configuration Release \ --logger "trx;LogFileName=$TRX_NAME" \ --results-directory ./TestResults/Determinism \ --verbosity minimal 2>&1; then PASSED=$((PASSED + 1)) else SKIPPED=$((SKIPPED + 1)) fi echo "::endgroup::" done echo "## Determinism Test Summary" >> $GITHUB_STEP_SUMMARY echo "- Passed: $PASSED" >> $GITHUB_STEP_SUMMARY echo "- Skipped: $SKIPPED" >> $GITHUB_STEP_SUMMARY - name: Upload Test Results uses: actions/upload-artifact@v4 if: always() with: name: test-results-determinism path: ./TestResults/Determinism retention-days: 14 resilience: name: Resilience Tests runs-on: ubuntu-22.04 timeout-minutes: 45 needs: discover if: github.event.inputs.include_resilience == 'true' steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} include-prerelease: true - name: Run Resilience Tests (all test projects) run: | mkdir -p ./TestResults/Resilience FAILED=0 PASSED=0 SKIPPED=0 for proj in $(find src \( -name "*.Tests.csproj" -o -name "*UnitTests.csproj" -o -name "*SmokeTests.csproj" -o -name "*FixtureTests.csproj" -o -name "*IntegrationTests.csproj" \) -type f ! -path "*/node_modules/*" ! -name "StellaOps.TestKit.csproj" ! -name "*Testing.csproj" | sort); do echo "::group::Testing $proj" TRX_NAME=$(echo "$proj" | sed 's|/|_|g' | sed 's|\.csproj||')-resilience.trx if dotnet test "$proj" \ --filter "Category=Resilience" \ --configuration Release \ --logger "trx;LogFileName=$TRX_NAME" \ --results-directory ./TestResults/Resilience \ --verbosity minimal 2>&1; then PASSED=$((PASSED + 1)) else SKIPPED=$((SKIPPED + 1)) fi echo "::endgroup::" done echo "## Resilience Test Summary" >> $GITHUB_STEP_SUMMARY echo "- Passed: $PASSED" >> $GITHUB_STEP_SUMMARY echo "- Skipped: $SKIPPED" >> $GITHUB_STEP_SUMMARY - name: Upload Test Results uses: actions/upload-artifact@v4 if: always() with: name: test-results-resilience path: ./TestResults/Resilience retention-days: 14 observability: name: Observability Tests runs-on: ubuntu-22.04 timeout-minutes: 30 needs: discover if: github.event.inputs.include_observability == 'true' steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} include-prerelease: true - name: Run Observability Tests (all test projects) run: | mkdir -p ./TestResults/Observability FAILED=0 PASSED=0 SKIPPED=0 for proj in $(find src \( -name "*.Tests.csproj" -o -name "*UnitTests.csproj" -o -name "*SmokeTests.csproj" -o -name "*FixtureTests.csproj" -o -name "*IntegrationTests.csproj" \) -type f ! -path "*/node_modules/*" ! -name "StellaOps.TestKit.csproj" ! -name "*Testing.csproj" | sort); do echo "::group::Testing $proj" TRX_NAME=$(echo "$proj" | sed 's|/|_|g' | sed 's|\.csproj||')-observability.trx if dotnet test "$proj" \ --filter "Category=Observability" \ --configuration Release \ --logger "trx;LogFileName=$TRX_NAME" \ --results-directory ./TestResults/Observability \ --verbosity minimal 2>&1; then PASSED=$((PASSED + 1)) else SKIPPED=$((SKIPPED + 1)) fi echo "::endgroup::" done echo "## Observability Test Summary" >> $GITHUB_STEP_SUMMARY echo "- Passed: $PASSED" >> $GITHUB_STEP_SUMMARY echo "- Skipped: $SKIPPED" >> $GITHUB_STEP_SUMMARY - name: Upload Test Results uses: actions/upload-artifact@v4 if: always() with: name: test-results-observability path: ./TestResults/Observability retention-days: 14 # =========================================================================== # SUMMARY JOB # =========================================================================== summary: name: Test Summary runs-on: ubuntu-22.04 needs: [discover, unit, architecture, contract, integration, security, golden] if: always() steps: - name: Download all test results uses: actions/download-artifact@v4 with: pattern: test-results-* path: ./TestResults - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} include-prerelease: true - name: Install trx2junit run: dotnet tool install -g trx2junit - name: Convert TRX to JUnit run: | find ./TestResults -name "*.trx" -exec trx2junit {} \; || true - name: Generate Summary run: | echo "## Test Results Summary" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### PR-Gating Tests" >> $GITHUB_STEP_SUMMARY echo "| Category | Status |" >> $GITHUB_STEP_SUMMARY echo "|----------|--------|" >> $GITHUB_STEP_SUMMARY echo "| Discover | ${{ needs.discover.result }} |" >> $GITHUB_STEP_SUMMARY echo "| Unit | ${{ needs.unit.result }} |" >> $GITHUB_STEP_SUMMARY echo "| Architecture | ${{ needs.architecture.result }} |" >> $GITHUB_STEP_SUMMARY echo "| Contract | ${{ needs.contract.result }} |" >> $GITHUB_STEP_SUMMARY echo "| Integration | ${{ needs.integration.result }} |" >> $GITHUB_STEP_SUMMARY echo "| Security | ${{ needs.security.result }} |" >> $GITHUB_STEP_SUMMARY echo "| Golden | ${{ needs.golden.result }} |" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### Test Projects Discovered: ${{ needs.discover.outputs.test-count }}" >> $GITHUB_STEP_SUMMARY - name: Count TRX files run: | TRX_COUNT=$(find ./TestResults -name "*.trx" | wc -l) echo "### Total TRX Files Generated: $TRX_COUNT" >> $GITHUB_STEP_SUMMARY - name: Upload Combined Results uses: actions/upload-artifact@v4 with: name: test-results-combined path: ./TestResults retention-days: 14 - name: Check for failures if: contains(needs.*.result, 'failure') run: exit 1