# .gitea/workflows/test-lanes.yml # Lane-based test execution using standardized trait filtering # Implements Task 10 from SPRINT 5100.0007.0001 name: Test Lanes on: pull_request: branches: [ main, develop ] paths: - 'src/**' - 'tests/**' - 'scripts/test-lane.sh' - '.gitea/workflows/test-lanes.yml' push: branches: [ main ] workflow_dispatch: inputs: run_performance: description: 'Run Performance lane tests' required: false default: false type: boolean run_live: description: 'Run Live lane tests (external dependencies)' required: false default: false type: boolean env: DOTNET_VERSION: '10.0.100' BUILD_CONFIGURATION: Release TEST_RESULTS_DIR: ${{ github.workspace }}/test-results jobs: # =========================================================================== # Unit Lane: Fast, isolated, deterministic tests (PR-gating) # =========================================================================== unit-tests: name: Unit Tests runs-on: ubuntu-22.04 timeout-minutes: 15 steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup .NET ${{ env.DOTNET_VERSION }} uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} include-prerelease: true - name: Restore solution run: dotnet restore src/StellaOps.sln - name: Build solution run: dotnet build src/StellaOps.sln --configuration $BUILD_CONFIGURATION --no-restore - name: Run Unit lane tests run: | mkdir -p "$TEST_RESULTS_DIR" chmod +x scripts/test-lane.sh ./scripts/test-lane.sh Unit \ --logger "trx;LogFileName=unit-tests.trx" \ --results-directory "$TEST_RESULTS_DIR" \ --verbosity normal - name: Upload Unit test results uses: actions/upload-artifact@v4 if: always() with: name: unit-test-results path: ${{ env.TEST_RESULTS_DIR }} if-no-files-found: ignore retention-days: 7 # =========================================================================== # Contract Lane: API contract stability tests (PR-gating) # =========================================================================== contract-tests: name: Contract Tests runs-on: ubuntu-22.04 timeout-minutes: 10 steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup .NET ${{ env.DOTNET_VERSION }} uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} include-prerelease: true - name: Restore solution run: dotnet restore src/StellaOps.sln - name: Build solution run: dotnet build src/StellaOps.sln --configuration $BUILD_CONFIGURATION --no-restore - name: Run Contract lane tests run: | mkdir -p "$TEST_RESULTS_DIR" chmod +x scripts/test-lane.sh ./scripts/test-lane.sh Contract \ --logger "trx;LogFileName=contract-tests.trx" \ --results-directory "$TEST_RESULTS_DIR" \ --verbosity normal - name: Upload Contract test results uses: actions/upload-artifact@v4 if: always() with: name: contract-test-results path: ${{ env.TEST_RESULTS_DIR }} if-no-files-found: ignore retention-days: 7 # =========================================================================== # Integration Lane: Service + storage tests with Testcontainers (PR-gating) # =========================================================================== integration-tests: name: Integration Tests runs-on: ubuntu-22.04 timeout-minutes: 30 steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup .NET ${{ env.DOTNET_VERSION }} uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} include-prerelease: true - name: Restore solution run: dotnet restore src/StellaOps.sln - name: Build solution run: dotnet build src/StellaOps.sln --configuration $BUILD_CONFIGURATION --no-restore - name: Run Integration lane tests env: POSTGRES_TEST_IMAGE: postgres:16-alpine run: | mkdir -p "$TEST_RESULTS_DIR" chmod +x scripts/test-lane.sh ./scripts/test-lane.sh Integration \ --logger "trx;LogFileName=integration-tests.trx" \ --results-directory "$TEST_RESULTS_DIR" \ --verbosity normal - name: Upload Integration test results uses: actions/upload-artifact@v4 if: always() with: name: integration-test-results path: ${{ env.TEST_RESULTS_DIR }} if-no-files-found: ignore retention-days: 7 # =========================================================================== # Security Lane: AuthZ, input validation, negative tests (PR-gating) # =========================================================================== security-tests: name: Security Tests runs-on: ubuntu-22.04 timeout-minutes: 20 steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup .NET ${{ env.DOTNET_VERSION }} uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} include-prerelease: true - name: Restore solution run: dotnet restore src/StellaOps.sln - name: Build solution run: dotnet build src/StellaOps.sln --configuration $BUILD_CONFIGURATION --no-restore - name: Run Security lane tests run: | mkdir -p "$TEST_RESULTS_DIR" chmod +x scripts/test-lane.sh ./scripts/test-lane.sh Security \ --logger "trx;LogFileName=security-tests.trx" \ --results-directory "$TEST_RESULTS_DIR" \ --verbosity normal - name: Upload Security test results uses: actions/upload-artifact@v4 if: always() with: name: security-test-results path: ${{ env.TEST_RESULTS_DIR }} if-no-files-found: ignore retention-days: 7 # =========================================================================== # Performance Lane: Benchmarks and regression thresholds (optional/scheduled) # =========================================================================== performance-tests: name: Performance Tests runs-on: ubuntu-22.04 if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.run_performance == 'true') timeout-minutes: 30 steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup .NET ${{ env.DOTNET_VERSION }} uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} include-prerelease: true - name: Restore solution run: dotnet restore src/StellaOps.sln - name: Build solution run: dotnet build src/StellaOps.sln --configuration $BUILD_CONFIGURATION --no-restore - name: Run Performance lane tests run: | mkdir -p "$TEST_RESULTS_DIR" chmod +x scripts/test-lane.sh ./scripts/test-lane.sh Performance \ --logger "trx;LogFileName=performance-tests.trx" \ --results-directory "$TEST_RESULTS_DIR" \ --verbosity normal - name: Upload Performance test results uses: actions/upload-artifact@v4 if: always() with: name: performance-test-results path: ${{ env.TEST_RESULTS_DIR }} if-no-files-found: ignore retention-days: 14 # =========================================================================== # Live Lane: External API smoke tests (opt-in only, never PR-gating) # =========================================================================== live-tests: name: Live Tests (External Dependencies) runs-on: ubuntu-22.04 if: github.event_name == 'workflow_dispatch' && github.event.inputs.run_live == 'true' timeout-minutes: 20 steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup .NET ${{ env.DOTNET_VERSION }} uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} include-prerelease: true - name: Restore solution run: dotnet restore src/StellaOps.sln - name: Build solution run: dotnet build src/StellaOps.sln --configuration $BUILD_CONFIGURATION --no-restore - name: Run Live lane tests run: | mkdir -p "$TEST_RESULTS_DIR" chmod +x scripts/test-lane.sh ./scripts/test-lane.sh Live \ --logger "trx;LogFileName=live-tests.trx" \ --results-directory "$TEST_RESULTS_DIR" \ --verbosity normal continue-on-error: true - name: Upload Live test results uses: actions/upload-artifact@v4 if: always() with: name: live-test-results path: ${{ env.TEST_RESULTS_DIR }} if-no-files-found: ignore retention-days: 7 # =========================================================================== # Test Results Summary # =========================================================================== test-summary: name: Test Results Summary runs-on: ubuntu-22.04 needs: [unit-tests, contract-tests, integration-tests, security-tests] if: always() steps: - name: Download all test results uses: actions/download-artifact@v4 with: path: all-test-results - name: Generate summary run: | echo "## Test Lane Results" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY for lane in unit contract integration security; do result_dir="all-test-results/${lane}-test-results" if [ -d "$result_dir" ]; then echo "### ${lane^} Lane: ✅ Passed" >> $GITHUB_STEP_SUMMARY else echo "### ${lane^} Lane: ❌ Failed or Skipped" >> $GITHUB_STEP_SUMMARY fi done echo "" >> $GITHUB_STEP_SUMMARY echo "See individual job logs for detailed test output." >> $GITHUB_STEP_SUMMARY