Addressing PR comments #1687
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: FlinkDotNet Unit Tests | |
| on: | |
| push: | |
| workflow_dispatch: | |
| env: | |
| configuration: Release | |
| concurrency: | |
| group: unit-tests-${{ github.head_ref || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| run-unit-tests: | |
| name: Run .NET Unit Tests | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| shell: pwsh | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis | |
| - name: Set up .NET 9.0 | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '9.0.x' | |
| - name: Set up JDK 17 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '17' | |
| distribution: 'zulu' # Required for SonarQube Cloud | |
| - name: Install Maven | |
| uses: stCarolas/setup-maven@v4 | |
| with: | |
| maven-version: '3.9.6' | |
| - name: Cache SonarQube Cloud packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.sonar/cache | |
| key: ${{ runner.os }}-sonar | |
| restore-keys: ${{ runner.os }}-sonar | |
| - name: Cache SonarQube Cloud scanner | |
| id: cache-sonar-scanner | |
| uses: actions/cache@v4 | |
| with: | |
| path: ${{ runner.temp }}/scanner | |
| key: ${{ runner.os }}-sonar-scanner | |
| restore-keys: ${{ runner.os }}-sonar-scanner | |
| - name: Install SonarQube Cloud scanner | |
| if: steps.cache-sonar-scanner.outputs.cache-hit != 'true' | |
| shell: bash | |
| run: | | |
| mkdir -p ${{ runner.temp }}/scanner | |
| dotnet tool update dotnet-sonarscanner --tool-path ${{ runner.temp }}/scanner | |
| - name: Begin SonarQube Cloud analysis | |
| if: github.event_name == 'push' || github.event_name == 'pull_request' | |
| env: | |
| SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | |
| shell: bash | |
| run: | | |
| cd FlinkDotNet | |
| MAX_RETRIES=3 | |
| RETRY_COUNT=0 | |
| RETRY_DELAY=5 | |
| while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do | |
| echo "Attempt $((RETRY_COUNT + 1)) of $MAX_RETRIES: Starting SonarQube Cloud analysis..." | |
| if ${{ runner.temp }}/scanner/dotnet-sonarscanner begin \ | |
| /k:"devstress_flinkdotnet" \ | |
| /o:"devstress" \ | |
| /d:sonar.token="${{ secrets.SONAR_TOKEN }}" \ | |
| /d:sonar.host.url="https://sonarcloud.io" \ | |
| /d:sonar.cs.opencover.reportsPaths="TestResults/**/coverage.opencover.xml" \ | |
| /d:sonar.cs.vscoveragexml.reportsPaths="TestResults/**/coverage.cobertura.xml" \ | |
| /d:sonar.exclusions="**/bin/**,**/obj/**,**/TestResults/**,**/CoverageReport/**,**/Demo/**,**/Backpressure/TestingSupportClasses.cs" \ | |
| /d:sonar.test.exclusions="**/bin/**,**/obj/**" \ | |
| /d:sonar.coverage.exclusions="**/*.Tests/**,**/TestResults/**" \ | |
| /d:sonar.dotnet.excludeTestProjects=true; then | |
| echo "SonarQube Cloud analysis started successfully" | |
| exit 0 | |
| fi | |
| RETRY_COUNT=$((RETRY_COUNT + 1)) | |
| if [ $RETRY_COUNT -lt $MAX_RETRIES ]; then | |
| echo "Failed to start SonarQube analysis. Retrying in ${RETRY_DELAY} seconds..." | |
| sleep $RETRY_DELAY | |
| RETRY_DELAY=$((RETRY_DELAY * 2)) | |
| else | |
| echo "WARNING: Failed to start SonarQube analysis after $MAX_RETRIES attempts. Continuing without SonarQube analysis." | |
| exit 0 | |
| fi | |
| done | |
| - name: Build FlinkDotNet solution | |
| shell: bash | |
| run: | | |
| cd FlinkDotNet | |
| echo "Building FlinkDotNet solution..." | |
| dotnet restore FlinkDotNet.sln | |
| dotnet build FlinkDotNet.sln --configuration ${{ env.configuration }} --no-restore | |
| - name: Run tests for FlinkDotNet solution with coverage | |
| shell: bash | |
| run: | | |
| cd FlinkDotNet | |
| echo "Running tests for FlinkDotNet.sln with code coverage..." | |
| dotnet test FlinkDotNet.sln --configuration ${{ env.configuration }} --no-build --logger "trx" --results-directory "TestResults" --collect:"XPlat Code Coverage" --settings coverlet.runsettings | |
| - name: Install ReportGenerator tool | |
| shell: bash | |
| run: | | |
| dotnet tool install -g dotnet-reportgenerator-globaltool || dotnet tool update -g dotnet-reportgenerator-globaltool | |
| - name: Generate Code Coverage Report | |
| shell: bash | |
| run: | | |
| reportgenerator \ | |
| -reports:"FlinkDotNet/TestResults/**/coverage.cobertura.xml" \ | |
| -targetdir:"FlinkDotNet/CoverageReport" \ | |
| -reporttypes:"Html;Cobertura;MarkdownSummary" \ | |
| -verbosity:"Info" | |
| - name: Display Coverage Summary | |
| run: | | |
| Write-Host "Code Coverage Summary:" | |
| if (Test-Path "FlinkDotNet/CoverageReport/Summary.md") { | |
| Get-Content "FlinkDotNet/CoverageReport/Summary.md" | |
| } | |
| - name: Check Code Coverage Threshold | |
| shell: bash | |
| run: | | |
| COVERAGE=$(grep -oP 'line-rate="\K[^"]+' FlinkDotNet/CoverageReport/Cobertura.xml | head -1) | |
| COVERAGE_PERCENT=$(echo "$COVERAGE * 100" | bc) | |
| echo "Code Coverage: ${COVERAGE_PERCENT}%" | |
| if (( $(echo "$COVERAGE_PERCENT < 85" | bc -l) )); then | |
| echo "ERROR: Code coverage ${COVERAGE_PERCENT}% is below the required 85% threshold" | |
| exit 1 | |
| fi | |
| echo "SUCCESS: Code coverage ${COVERAGE_PERCENT}% meets the 85% threshold" | |
| - name: Upload Coverage Report | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: code-coverage-report | |
| path: FlinkDotNet/CoverageReport/ | |
| retention-days: 7 | |
| - name: End SonarQube Cloud analysis | |
| if: github.event_name == 'push' || github.event_name == 'pull_request' | |
| env: | |
| SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | |
| shell: bash | |
| run: | | |
| cd FlinkDotNet | |
| MAX_RETRIES=3 | |
| RETRY_COUNT=0 | |
| RETRY_DELAY=5 | |
| while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do | |
| echo "Attempt $((RETRY_COUNT + 1)) of $MAX_RETRIES: Ending SonarQube Cloud analysis..." | |
| if ${{ runner.temp }}/scanner/dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}"; then | |
| echo "SonarQube Cloud analysis completed successfully" | |
| exit 0 | |
| fi | |
| RETRY_COUNT=$((RETRY_COUNT + 1)) | |
| if [ $RETRY_COUNT -lt $MAX_RETRIES ]; then | |
| echo "Failed to complete SonarQube analysis. Retrying in ${RETRY_DELAY} seconds..." | |
| sleep $RETRY_DELAY | |
| RETRY_DELAY=$((RETRY_DELAY * 2)) | |
| else | |
| echo "WARNING: Failed to complete SonarQube analysis after $MAX_RETRIES attempts. Continuing without completing SonarQube analysis." | |
| exit 0 | |
| fi | |
| done | |
| - name: Verify Test Results | |
| run: | | |
| Write-Host "Unit tests completed successfully." | |
| Write-Host "Test Results Summary:" | |
| Get-ChildItem -Path "./FlinkDotNet/TestResults" -Recurse -Filter "*.trx" | ForEach-Object { | |
| Write-Host " Test Result: $($_.FullName)" | |
| } | |
| - name: Upload unit test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: unit-test-results | |
| path: | | |
| FlinkDotNet/TestResults/**/*.trx | |
| retention-days: 7 | |
| - name: Publish test results report | |
| if: always() | |
| uses: dorny/test-reporter@v1 | |
| with: | |
| name: Test Results | |
| path: 'FlinkDotNet/TestResults/**/*.trx' | |
| reporter: 'dotnet-trx' | |
| fail-on-error: false | |